Bootstrap

Triplet Loss 实现

按照我原来的想法,Triplet Loss 三元组应该是这样选择的:

(1) 前馈操作: cnn 先执行forward 操作,获取到embedding 的具体值后,再去用非 tf 函数去处理embedding并生成三元组

(2) 训练操作: 用(1) 生成的三元组进行训练

 

今天看了下别人的实现代码,直接用Tensorflow 在一次cnn操作中,直接选取并获取最终的loss值。(而我想象的那样,不是一次前馈+一次训练) 

很多很巧妙的思路(如果让我写,我想不出来的那种):

(1) 获取所有三元组的loss,已知d[i,j] 是第i个和第j embedding 的距离,dx[i,j,1] = d[i,1,k] = d[i,j] 

     通过以下一句就可以实现获取所有三元组的loss值

#triplet_loss[i,j,k] = dx[i,j,1] - dy[i,1,k] +margin = d[i,j] - d[i,k] +margin
triplet_loss = anchor_positive_dist - anchor_negative_dist + margin

(2) 通过reduce_max / reduce_min 等操作,省略选取三元组中的各种if 操作

 

代码来源:https://github.com/omoindrot/tensorflow-triplet-loss/blob/master/model/triplet_loss.py

以下代码加了我的注释:

"""Define functions to create the triplet loss with online triplet mining."""

import tensorflow as tf

# (*) 返回embeddings 两两之间的距离
def _pairwise_distances(embeddings, squared=False):
    """Compute the 2D matrix of distances between all the embeddings.

    Args:
        embeddings: tensor of shape (batch_size, embed_dim)
        squared: Boolean. If true, output is the pairwise squared euclidean distance matrix.
                 If false, output is the pairwise euclidean distance matrix.

    Returns:
        pairwise_distances: tensor of shape (batch_size, batch_size)
    """
    # Get the dot product between all embeddings
    # shape (batch_size, batch_size)
    dot_product = tf.matmul(embeddings, tf.transpose(embeddings))

    # Get squared L2 norm for each embedding. We can just take the diagonal of `dot_product`.
    # This also provides more numerical stability (the diagonal of the result will be exactly 0).
    # shape (batch_size,)
    square_norm = tf.diag_part(dot_product)

    # Compute the pairwise distance matrix as we have:
    # ||a - b||^2 = ||a||^2  - 2 <a, b> + ||b||^2
    # shape (batch_size, batch_size)
    distances = tf.expand_dims

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;