知识点来源于知乎链接
- triplet loss的原理
- 损失函数的公式
L=max(d(a,p)-d(a,n)+margin,0)
- a: anchor,p: positive, 与a是同一类别的样本;n: negative, 与a是不同类别的样本,margin是一个大于0的常数。最终优化目标是拉近a与p的距离,拉远a和n的距离。
- 其中样本分为三类:
- easy triplets: L=0,即d(a,p) + margin<d(a,n),这种情况不需要优化,天然a和p的距离很近,a和n的距离很远,如下图
- hard triplets:L>margin,即d(a,n)>d(a,p),a和n的距离近,a和p的距离远,这种情况损失最大,需要优化,如下图
- semi-hard triplets: L<margin, 即d(a,p)<d(a,n)<d(a,p)+margin, 即a和p的距离比a和n的距离近,但是近的不够多,不满足margin,这种情况存在损失,但损失比hard triplets要小,也需要优化,如下图
- easy triplets: L=0,即d(a,p) + margin<d(a,n),这种情况不需要优化,天然a和p的距离很近,a和n的距离很远,如下图
- 损失函数的公式
- 设置margin的原因
- 避免模型走捷径,将negative和positive的embedding训练成很相近,如果没有margin,triplets loss 公式就变成了L=max(d(a,p)-d(a,n),0), 只要d(a,p)= d(a,n)就可以满足上式,也就是a与正例p跟a与负例n的距离一样即可,这样模型很难正确区分正例和负例。
- 设定一个margin常量,可以迫使模型努力学习,能让a和负例n的distance值更大,同时让a与p的distance值更小。
- 由于margin的存在,是的triplets loss多了一个参数,margin的大小需要调参。如果margin太大,则模型的损失会更大,而且学习到最后,loss也很难趋近于0,甚至导致网络不收敛,但是可以较大把握区分较为相似的样本,;如果margin太小,loss很容易趋近于0,模型很好训练,但较难区分a与p。
- triolets loss该如何构造训练集
- 对于triplet loss的损失公式,要有3个输入,即锚点a,正例p和负例n。对于样本来讲,有3种,即easy triplets、hard triplets和semi-hard triplets
- 理论上讲,使用hard triplets训练模型最好,因为这样模型能够有很好的学习能力,但由于margin的存在,这类样本可能模型没法很好的拟合,训练比较困难;其次是使用semi-hard triplets,这类样本是实际使用中最优选择,因为这类样本损失不为0,而且损失不大,模型既可以学习到样本之间的差异,又较容易收敛;至于easy triplet,损失为0,不用拿来训练。
- 针对不同的业务,其实构造的原则也不一样,比如人脸识别场景,样本的选择应该满足d(a,p)和d(a,n)尽可能接近,其实就是选择semi-hard triplets样本,这样一来,损失函数的公式不容易满足,也就意味着损失值不够低,模型必须认真训练和更新自己的参数,从而努力让d(a,n)的值尽可能变大,同时让d(a,p)的值尽可能变小。