1

我正在尝试通过随机负三元组选择来实现三元组损失。现在我有一个形状为 (batch_size, batch_size, batch_size) 的张量,其中元素 (i,j,k) 等于 dist(i,j) - dist(i,k) + margin(i 是锚,j 是正对,ka 负)。

我将所有无效元素清零并tf.maximum(tensor,0.)
为每对 i,j 取 Now 我想随机选择一个非零元素(如果存在),并计算所有这些选定元素的平均值。我需要禁用急切的执行,所以我不需要遍历任何东西。

现在我的代码如下所示:

def random_negative_triplet_loss(labels, embeddings):

    margin = 1.
    # Get the pairwise distance matrix
    pairwise_dist = _pairwise_distances(embeddings)

    # shape (batch_size, batch_size, 1)
    anchor_positive_dist = tf.expand_dims(pairwise_dist, 2)
    assert anchor_positive_dist.shape[2] == 1, "{}".format(anchor_positive_dist.shape)
    # shape (batch_size, 1, batch_size)
    anchor_negative_dist = tf.expand_dims(pairwise_dist, 1)
    assert anchor_negative_dist.shape[1] == 1, "{}".format(anchor_negative_dist.shape)

    # Compute a 3D tensor of size (batch_size, batch_size, batch_size)
    # triplet_loss[i, j, k] will contain the triplet loss of anchor=i, positive=j, negative=k
    # Uses broadcasting where the 1st argument has shape (batch_size, batch_size, 1)
    # and the 2nd (batch_size, 1, batch_size)
    triplet_loss = anchor_positive_dist - anchor_negative_dist + margin
    # Put to zero the invalid triplets
    # (where label(a) != label(p) or label(n) == label(a) or a == p)
    mask = _get_triplet_mask(labels)

    mask = tf.to_float(mask)
    triplet_loss = tf.multiply(mask, triplet_loss)
    # Remove negative losses (i.e. the easy triplets)
    triplet_loss = tf.maximum(triplet_loss, 0.0)
    num_classes = 5
    the_loss = 0
    the_count = 0
    num_valid = tf.reduce_sum(mask, axis=2)
    valid_count = tf.reduce_sum(tf.to_int32(tf.greater(num_valid, 1e-16)))
    sampler = tf.distributions.Uniform(0., tf.to_float(50) - 1e-3)

我假设可以通过使用 tf.distributions.Uniform 来实现随机性,但是由于每对 i,j 具有不同数量的有效索引 k 我不知道如何应用它。

4

0 回答 0