gpt4 book ai didi

tensorflow - Tensorflow 的TripletSemiHardLoss 和TripletHardLoss 是如何实现的,如何与Siamese Network 一起使用?

转载 作者:行者123 更新时间:2023-12-04 15:57:48 24 4
gpt4 key购买 nike

据我所知 Triplet Loss是一个损失函数,它减少了 anchor 和正之间的距离,但减少了 anchor 和负之间的距离。此外,还添加了一个边距。
例如,让我们假设:一个 Siamese Network ,这给出了嵌入:

anchor_output = [1,2,3,4,5...] # embedding given by the CNN model
positive_output = [1,2,3,4,4...]
negative_output= [53,43,33,23,13...]
而且我认为我可以获得三重损失,例如:(我认为我必须使用 Lambda 层左右将其作为损失)
# calculate triplet loss
d_pos = tf.reduce_sum(tf.square(anchor_output - positive_output), 1)
d_neg = tf.reduce_sum(tf.square(anchor_output - negative_output), 1)

loss = tf.maximum(0., margin + d_pos - d_neg)
loss = tf.reduce_mean(loss)

那么到底是什么:
tfa.losses.TripletHardLoss
tfa.losses.TripletSemiHardLoss
据我所知,Semi 和 hard 是 Siamese Techniques 的数据生成技术类型。这插入模型学习更多。
我的想法 : 正如我在 This Post 中了解到的,我认为你可以这样做:
  • 生成一批说 3 张图像并制作一对 3 具有 27图片
  • 丢弃每个 无效 对(所有 i,j,k 都应该是唯一的)。剩余批次 B
  • 批量获取每对嵌入 B

  • 所以我想 HardTripletLoss每批仅考虑具有 的那 3 张图像最大 anchor 定正距离和 最低 anchor 定 - 负距离。
    而对于 Semi Hard ,我认为它丢弃了距离为 0 的每个图像对计算的所有损失。
    如果没有,请有人纠正我并告诉我如何使用这些。 (我知道我们可以在 model.complie() 中使用它,但我的问题是不同的。

    最佳答案

    什么是TripletHardLoss ?
    此亏跟普通TripletLoss形式,但在计算损失时使用最大正距离和最小负距离加上批次内的边际常数,如我们在公式中所见:
    enter image description here
    调查source codetfa.losses.TripletHardLoss我们可以看到上面的公式已经完全实现了:

    # Build pairwise binary adjacency matrix.
    adjacency = tf.math.equal(labels, tf.transpose(labels))
    # Invert so we can select negatives only.
    adjacency_not = tf.math.logical_not(adjacency)

    adjacency_not = tf.cast(adjacency_not, dtype=tf.dtypes.float32)
    # hard negatives: smallest D_an.
    hard_negatives = _masked_minimum(pdist_matrix, adjacency_not)

    batch_size = tf.size(labels)

    adjacency = tf.cast(adjacency, dtype=tf.dtypes.float32)

    mask_positives = tf.cast(adjacency, dtype=tf.dtypes.float32) - tf.linalg.diag(
    tf.ones([batch_size])
    )

    # hard positives: largest D_ap.
    hard_positives = _masked_maximum(pdist_matrix, mask_positives)

    if soft:
    triplet_loss = tf.math.log1p(tf.math.exp(hard_positives - hard_negatives))
    else:
    triplet_loss = tf.maximum(hard_positives - hard_negatives + margin, 0.0)

    # Get final mean triplet loss
    triplet_loss = tf.reduce_mean(triplet_loss)
    请注意 soft tfa.losses.TripletHardLoss 中的参数是 不是 使用以下公式计算普通 TripletLoss :
    enter image description here
    因为正如我们在上面的源代码中看到的,它仍然使用最大正距离和最小负距离,所以它决定是否使用软边距
    什么是 TripletSemiHardLoss ?
    这个亏损也跟普通 TripletLoss形式,正距离与普通 TripletLoss相同和负距离使用 半硬负 :

    Minimum negative distance among which are at least greater than thepositive distance plus the margin constant, if no such negativeexists, uses the largest negative distance instead.


    即我们首先要找到满足以下条件的负距离:
    enter image description here p为正和 n对于负数,如果 wan 找不到满足此条件的负距离,则我们使用最大负距离代替。
    正如我们在 source code 中可以看到上述条件过程清晰的 tfa.losses.TripletSemiHardLoss , 其中 negatives_outside是满足这个条件的距离和 negatives_inside是最大的负距离:
    # Build pairwise binary adjacency matrix.
    adjacency = tf.math.equal(labels, tf.transpose(labels))
    # Invert so we can select negatives only.
    adjacency_not = tf.math.logical_not(adjacency)

    batch_size = tf.size(labels)

    # Compute the mask.
    pdist_matrix_tile = tf.tile(pdist_matrix, [batch_size, 1])
    mask = tf.math.logical_and(
    tf.tile(adjacency_not, [batch_size, 1]),
    tf.math.greater(
    pdist_matrix_tile, tf.reshape(tf.transpose(pdist_matrix), [-1, 1])
    ),
    )
    mask_final = tf.reshape(
    tf.math.greater(
    tf.math.reduce_sum(
    tf.cast(mask, dtype=tf.dtypes.float32), 1, keepdims=True
    ),
    0.0,
    ),
    [batch_size, batch_size],
    )
    mask_final = tf.transpose(mask_final)

    adjacency_not = tf.cast(adjacency_not, dtype=tf.dtypes.float32)
    mask = tf.cast(mask, dtype=tf.dtypes.float32)

    # negatives_outside: smallest D_an where D_an > D_ap.
    negatives_outside = tf.reshape(
    _masked_minimum(pdist_matrix_tile, mask), [batch_size, batch_size]
    )
    negatives_outside = tf.transpose(negatives_outside)

    # negatives_inside: largest D_an.
    negatives_inside = tf.tile(
    _masked_maximum(pdist_matrix, adjacency_not), [1, batch_size]
    )
    semi_hard_negatives = tf.where(mask_final, negatives_outside, negatives_inside)

    loss_mat = tf.math.add(margin, pdist_matrix - semi_hard_negatives)

    mask_positives = tf.cast(adjacency, dtype=tf.dtypes.float32) - tf.linalg.diag(
    tf.ones([batch_size])
    )

    # In lifted-struct, the authors multiply 0.5 for upper triangular
    # in semihard, they take all positive pairs except the diagonal.
    num_positives = tf.math.reduce_sum(mask_positives)

    triplet_loss = tf.math.truediv(
    tf.math.reduce_sum(
    tf.math.maximum(tf.math.multiply(loss_mat, mask_positives), 0.0)
    ),
    num_positives,
    )
    那些损失怎么用?
    双方亏损预期 y_true提供为一维整数 Tensor具有形状 [batch_size] 的多类整数标签。和嵌入 y_pred必须是二维浮点数 Tensor l2个归一化嵌入向量。
    准备输入和标签的示例代码:
    import tensorflow as tf
    import tensorflow_addons as tfa
    import tensorflow_datasets as tfds

    def _normalize_img(img, label):
    img = tf.cast(img, tf.float32) / 255.
    return (img, label)

    train_dataset, test_dataset = tfds.load(name="mnist", split=['train', 'test'], as_supervised=True)

    # Build your input pipelines
    train_dataset = train_dataset.shuffle(1024).batch(16)
    train_dataset = train_dataset.map(_normalize_img)

    # Take one batch of data
    for data in train_dataset.take(1):
    print("Batch of images shape:\n{}\nBatch of labels:\n{}\n".format(data[0].shape, data[1]))
    输出:
    Batch of images shape:
    (16, 28, 28, 1)
    Batch of labels:
    [8 4 0 3 2 4 5 1 0 5 7 0 2 6 4 9]
    关注此 official tutorial about how to using TripletSemiHardLoss ( TripletHardLoss as well) in general如果您在使用时遇到问题。

    关于tensorflow - Tensorflow 的TripletSemiHardLoss 和TripletHardLoss 是如何实现的,如何与Siamese Network 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65579247/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com