深度学习方法(十九):一文理解Contrastive Loss,Triplet Loss,Focal Loss

Posted 大饼博士X

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习方法(十九):一文理解Contrastive Loss,Triplet Loss,Focal Loss相关的知识,希望对你有一定的参考价值。

文章目录


本文记录一下三种常用的loss function:Contrastive Loss,Triplet Loss,Focal Loss。其中前面两个可以认为是ranking loss类型,Focal Loss是针对正负样本极其不均衡情况下的一种cross entropy loss的升级版。本文主要参考资料是[2][3][5]。

我们平时ML任务的时候,用的最多的是cross entropy loss或者MSE loss。需要有一个明确的目标,比如一个具体的数值或者是一个具体的分类类别。但是ranking loss实际上是一种metric learning,他们学习的相对距离,相关关系,而对具体数值不是很关心。ranking loss 有非常多的叫法,但是他们的公式实际上非常一致的。大概有两类,一类是输入pair 对,另外一种是输入三元组结构。

1. Contrastive Loss (对比loss)

在孪生神经网络(siamese network)中,其采用的损失函数是contrastive loss,这种损失函数可以有效的处理孪生神经网络中的paired data的关系(形式上并不一定是两个Net,也可以是一个Net两个Out,可以认为上面示意图的Network1和2是同一个,或者不是同一个)。contrastive loss的表达式如下:
L = 1 2 N ∑ n = 1 N y d 2 + ( 1 − y ) m a x ( m a r g i n − d , 0 ) 2 L=\\frac12N\\sum_n=1^Nyd^2+(1-y)max(margin-d,0)^2 L=2N1n=1Nyd2+(1y)max(margind,0)2

其中 d = ∣ ∣ a n − b n ∣ ∣ 2 d=||a_n - b_n||_2 d=anbn2,代表两个样本特征的欧氏距离,y为两个样本是否匹配的标签,y=1代表两个样本相似或者匹配,y=0则代表不匹配,margin为设定的阈值。这种损失函数最初来源于Yann LeCun的Dimensionality Reduction by Learning an Invariant Mapping,主要是用在降维中,即本来相似的样本,在经过降维(特征提取)后,在特征空间中,两个样本仍旧相似;而原本不相似的样本,在经过降维后,在特征空间中,两个样本仍旧不相似。

观察上述的contrastive loss的表达式可以发现,这种损失函数可以很好的表达成对样本的匹配程度,也能够很好用于训练提取特征的模型。当y=1(即样本相似)时,损失函数只剩下 ∑ y d 2 \\sum yd^2 yd2,即原本相似的样本,如果在特征空间的欧式距离较大,则说明当前的模型不好,因此加大损失。而当y=0时(即样本不相似)时,损失函数为 ∑ ( 1 − y ) m a x ( m a r g i n − d , 0 ) 2 \\sum (1-y)max(margin-d,0)^2 (1y)max(margind,0)2,即当样本不相似时,其特征空间的欧式距离反而小的话,损失值会变大,这也正好符号我们的要求。其中margin是一个超参,相当于是给loss定了一个上届(margin平方),如果d大于等于margin,那么说明已经优化的很好了,loss=0了。

这张图表示的就是损失函数值与样本特征的欧式距离之间的关系,其中红色虚线表示的是相似样本的损失值,蓝色实线表示的不相似样本的损失值。

2. Triplet Loss(三元loss)

Triplet loss最初是在 FaceNet: A Unified Embedding for Face Recognition and Clustering 论文中提出的,可以学到较好的人脸的embedding。

Softmax是确定的分类,需要有真实的标注label。而有的时候我们不一定知道label,但是知道正样本对和负样本对——比如两张照片是同一个人,或者不是同一个人。


输入是一个三元组 <a, p, n>

  • a: anchor,表示一个基准样本
  • p: positive, 与 a 是同一类别的样本,比如就是同一个人的照片
  • n: negative, 与 a 是不同类别的样本,比如就是不同人的照片

Triplet Loss形式
L = m a x ( d ( a , p ) − d ( a , n ) + margin , 0 ) L=max(d(a,p)−d(a,n)+\\textmargin,0) L=max(d(a,p)d(a,n)+margin,0)

其中 d d d表示距离函数,一般指在Embedding下的欧式距离计算。很显然,Triplet-Loss是希望让a和p的距离尽可能小,而a和n的距离尽可能大,但是具体而言 d ( a , p ) d(a,p) d(a,p) d ( a , n ) d(a,n) d(a,n)的数值是多少,并没有规定,只要考察他们之间的相对距离。网上有一张图片说明了几种相对关系。

如果我们给定了一个a和p,以及参数 margin > 0 \\textmargin>0 margin>0,那么我们就可以考察negative点的位置,会出现三种case(如果是Easy negative的三元组我们叫做Easy triplet,其他类似):

  • Easy negatives(绿色区域): L = 0 L=0 L=0 d ( a , p ) + margin ≤ d ( a , n ) d(a,p)+\\textmargin \\leq d(a,n) d(a,p)+margind(a,n),这种情况不需要优化(无法优化,Loss为0),天然a, p的距离很近, a, n的距离远。
  • hard negatives(红色区域): d ( a , n ) ≤ d ( a , p ) d(a,n) \\leq d(a,p) d(a,n)d(a,p),也就是说negative点反而比较近,说明距离估计的不准,这个时候loss比较大。
  • Semi-hard negatives(橙色区域): d ( a , p ) < d ( a , n ) < d ( a , p ) + margin d(a,p)\\lt d(a,n)\\lt d(a,p)+\\textmargin d(a,p)<d(a,n)<d(a,p)+margin, 即a, n的距离靠的很近,但是因为我们有一个margin,使得loss依然是正的。这种情况下,其实是说在这个三元组里面比较p和n离a的距离差不多,比较容易混淆。

FaceNet论文中是随机选取semi-hard triplets进行训练的, (也可以选择 hard triplets或者两者一起进行训练)

在线训练时产生样本
虽然可以离线把triplet数据都产生(配对)好,但实际使用采用此方法,即在线对一个Batch去产生。产生时又分为两种策略Batch All和Batch Hard (是在一篇行人重识别的论文中提到的[7],假设一个batch中有 B = P K B=PK B=PK张图片, 其中 P P P个身份的人,每个身份的人 K K K张图片(比如 K = 4 K=4 K=4)。

  • Batch All:计算batch_size中所有valid的hard triplet 和 semi-hard triplet(valid是指a,p,n三个都不能相同,需要是不同图片), 然后取平均得到Loss。理论上最多可以产生 P K ( K − 1 ) ( P K − K ) PK(K−1)(PK−K) PK(K1)(PKK)个 triplets:PK个 anchor,K-1 个 positive,PK-K 个 negative。但是因为很多是easy triplets的情况,所以平均会导致Loss很小,easy triplets对我们是不需要的。所以是对所有valid的hard triplet和semi-hard triplet对求平均。

  • Batch Hard:对于每一个anchor,选择距离最大的 d ( a , p ) d(a, p) d(a,p)和距离最大的 d ( a , n ) d(a, n) d(a,n),所以只有 P K PK PK个三元组triplets来求loss。

3. Focal Loss[5]

Focal Loss的提出是用来解决一阶段目标检测算法面对的极端不平衡前景和背景目标(框)数量,作者表示可能有1:1000。原论文主要是关心处理简单的二分类问题,即前景背景检测,但是loss本身也非常容易扩展到多分类问题。

基本的交叉熵loss(针对一个样本,其中 p t p_t pt表示模型的输出概率,且只要针对ground truth那个类别的输出概率):

CE ( p t ) = − log ⁡ ( p t ) \\textCE(p_t) = -\\log(p_t) CE(pt)=log(pt)

α-balanced focal lossloss

F L ( p t ) = − α t ( 1 − p t ) γ log ⁡ ( p t ) FL(p_t) = -\\alpha_t (1-p_t)^\\gamma\\log (p_t) FL(pt)=αt(1pt)γlog(pt)

其中,我们发现在原来的cross entropy loss基础上,加上了一个调节因子 ( 1 − p t ) γ (1-p_t)^\\gamma (1pt)γ γ ≥ 0 \\gamma \\geq 0 γ0,这个调节因子的作用是:

  • When an example is misclassified and pt
    is small, the modulating factor is near 1 and the loss is unaffected. As p t → 1 p_t \\rightarrow 1 pt1, the factor goes to 0 and the loss for well-classified examples is down-weighted
  • The focusing parameter γ \\gamma γ smoothly adjusts the rate at which easy examples are downweighted.

实验中发现,一般 γ = 2 \\gamma = 2 γ=2是最有效的。这个调节因子可以让容易分的样本的loss降低重要性。比如,当 γ = 2 \\gamma = 2 γ=2,以及 p t = 0.9 p_t = 0.9 pt=0.9,那么这个样本就是比较容易分对,它的loss较Cross Entropy Loss就降低了100倍;而 p t = 0.968 p_t = 0.968 pt=0.968,loss就小了1000倍;而对 p t = 0.5 p_t = 0.5 pt=0.5的难分样本,loss只是降低了4倍,相当于重要性变大了。另外,还多了一个weighting factor α ∈ [ 0 , 1 ] \\alpha \\in [0,1] α[0,1],作者表示:In practice α \\alpha α may be set by inverse class frequency or treated as a hyperparameter to set by cross validation。实际在实验中,作者是看成一个超参的,需要调节,比如用0.25, 0.5, 0.75都有试过。如果二分类,就设 α t \\alpha_t αt for class 1 and 1 − α t 1−\\alpha_t 1αt for class −1。

3.1 引申讨论:其他形式的Focal Loss

作者提出,实际上并不只是上面的Focal Loss可以有效,应该存在一批定义方法,他们的效果是类似的。在[5]附录中作者又给出了一种Focal Loss*的定义方法:

我们定义: x t = y x x_t = yx xt=yx

其中, y ∈ − 1 , + 1 y \\in \\-1,+1 \\ y1一文理解神经网络的本质

一文理解神经网络的本质

一文理解深度学习中的BN,LN,IN,GN,SN的归一化操作

深度学习核心技术精讲100篇(五十九)-多业务融合推荐策略实战应用

深度学习一文读懂机器学习常用损失函数(Loss Function)

一文轻松掌握深度学习框架中的einsum