三元组损失是什么?让同类靠近、异类远离的度量学习方法
三元组损失(Triplet Loss)是深度学习中的一种损失函数,用来训练模型学习一种“距离”:让同类的样本在特征空间中彼此靠近,不同类的样本彼此远离。它最广为人知的应用,是谷歌在 2015 年提出的 FaceNet 人脸识别系统。
什么是“三元组”
“三元组”是指每次训练时用到的三个数据点:锚点(Anchor),一个参照样本,比如某个人的一张照片;正样本(Positive),和锚点属于同一类别的另一个样本,比如同一个人的另一张照片;负样本(Negative),和锚点属于不同类别的样本,比如另一个人的照片。
三元组损失的目标是:最小化锚点与正样本之间的距离,同时最大化锚点与负样本之间的距离。更准确地说,它要求锚点到正样本的距离,至少要比锚点到负样本的距离小一个预先设定的“间隔”(margin)。如果已经满足了这个要求,这个三元组的损失就是零,不需要再调整;如果不满足,就产生损失,推动模型调整特征,把正样本拉近、把负样本推远。设置间隔是为了避免模型偷懒:比如把所有样本都映射到同一个点,距离全都是零。
为什么这样训练
在人脸识别这类任务中,类别的数量非常多,而且不断有新的类别出现:世界上有几十亿人,系统需要识别的人随时在增加。如果把它当成一个普通的分类问题,每增加一个人就要重新训练模型,这不现实。三元组损失训练的是一种“度量”:模型学会把任何一张人脸照片转换成一个特征向量,同一个人的照片向量靠近,不同人的照片向量远离。训练好之后,判断两张照片是不是同一个人,只需要计算它们的向量距离;识别一个新人,只需要存下他一张照片的向量,不需要重新训练。这种方法被称为度量学习。
难样本挖掘
三元组损失的效果很大程度上取决于选择哪些三元组来训练。如果随机选择,大部分三元组都太“容易”:负样本和锚点本来就差别很大,早已满足要求,损失为零,对训练没有帮助。因此通常需要“难样本挖掘”:专门挑选那些容易混淆的三元组,比如长得很像的两个人,或者同一个人差别很大的两张照片(不同角度、光线、年龄)。但挑选得太难也可能导致训练不稳定,FaceNet 采用了“半难”样本的策略来取得平衡。
应用
除了人脸识别,三元组损失还被用于行人重识别(在不同摄像头中找到同一个人)、图像检索、商品同款搜索、声纹识别、推荐系统和句子嵌入等任务。后来出现的对比学习方法,比如使用 InfoNCE 损失的方法,在一批样本中同时比较一个正样本和多个负样本,可以看作三元组损失思想的推广。