我正在尝试通过随机负三元组选择来实现三元组损失。现在我有一个形状为 (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 我不知道如何应用它。