论文提出一种新的loss函数,名叫Triplet Loss。
假设有一张目标脸Anchor,我们的目的是要使得其与相同身份的另一张图片Positive之间的距离要小于其与不同身份的一张脸Negtive的距离。如上图所示,刚开始,Anchor和Positive之间的距离要大于Anchor和Negative的距离,经过学习之后使得Anchor和Positive之间的距离小于Anchor和Negative的距离。由此定义损失函数公式如下:
image.png
triplet loss 代码[1]:
def triplet_loss(anchor, positive, negative, alpha):
"""Calculate the triplet loss according to the FaceNet paper
Args:
anchor: the embeddings for the anchor images.
positive: the embeddings for the positive images.
negative: the embeddings for the negative images.
Returns:
the triplet loss according to the FaceNet paper as a float tensor.
"""
with tf.variable_scope('triplet_loss'):
pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), 1)
neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), 1)
basic_loss = tf.add(tf.subtract(pos_dist,neg_dist), alpha)
loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0)
return
训练方法
因此我们在训练的时候需要3张图片为一组。
有一个问题就是如果我们随机挑选图片,会存在选择的图片组本身Anchor和Positive之间的距离d(A,P)就小于d(A,N)的情况,这样的话模型就学不到任何东西,因此我们需要选择难以训练的图片组,也就是d(A,P)>d(A,N),文中称之为hard positive/negative examplars, 即Triplet。
有两种方法来获取Triplet:
Online:在每一个batch中,先把图片过一遍神经网络算出特征(infrense),然后根据算出来的特征来构造Triplet,用构造出的Triplet来训练网络。
Offline:每n个step后在全部数据集上构造Triplet。
论文中使用的是Online方法。
训练过程
500个epoch。每一个epoch有1000个batch。一个batch从数据集中随机提取45个人,每个人40张图片,共1800张图片。从这1800张图片中提取满足条件的Triplet参与训练。
Triplet 选择方法:一个mini-batch中的同label的每一对图片都构成一对Anchor-Positive;然后再在不同label中随机选择一个满足d(A,N)-α < d(A,P) < d(A,N)的Negative。
疑问:
1。为什么hardest negative会导致collapsed model?
Reference:
[1] https://github.com/davidsandberg/facenet
[2] FaceNet---深度学习与人脸识别的二次结合
网友评论