深度学习方法(十九):一文理解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=\frac{1}{2N}\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)+\text{margin},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 \text{margin}>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)+\text{margin} \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)+\text{margin} 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 ) \text{CE}(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 \} y{1,+1}表示样本分对or分错。给出了一种新的loss形式:: Focal Loss*

p t ∗ = σ ( γ x t + β ) F L ∗ = − log ⁡ ( p t ∗ ) / γ p_t^* = \sigma(\gamma x_t + \beta)\\ FL^* = -\log (p_t^*)/\gamma pt=σ(γxt+β)FL=log(pt)/γ

下图是本文中几种loss曲线,以及他们的梯度:
在这里插入图片描述
在这里插入图片描述
具体的梯度公式推导是:

在这里插入图片描述
最后作者给出的结果是,几种Focal Loss的作用差不了太多,但是比原始的Cross Entropy显著要好一些。作者认为和Focal Loss有相同作用的其他loss应该是等效效果的。

参考资料

[1] Triplet Loss, Ranking Loss, Margin Loss
[2] Contrastive Loss (对比损失)
[3] Triplet-Loss原理及其实现、应用
[4] Loss Rank Mining: A General Hard Example Mining Method for Real-time Detectors
[5] Focal Loss for Dense Object Detection
[6] FaceNet: A Unified Embedding for Face Recognition and Clustering
[7] In Defense of the Triplet Loss for Person Re-Identification
[8] 文献阅读 - Dimensionality Reduction by Learning an Invariant Mapping
[9] 目标检测focal loss 和 loss rank mining笔记

  • 25
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 对比损失(Contrastive Loss)是一个用于度量相似度或距离的损失函数。在PyTorch中,我们可以使用这个损失函数来训练一些需要度量相似度或距离的模型,比如人脸识别、语音识别等。该损失函数的计算方式是将正样本(相似样本)的距离(或相似度)降低,将负样本(不相似样本)的距离(或相似度)增加。 ### 回答2: 对比损失是一种针对分类问题的常见损失函数,用于衡量两个样本之间的相似度或差异度。PyTorch提供了实现对比损失的API,即`nn.ContrastiveLoss()`。 对比损失的计算方法是将两个输入样本通过一个共享的神经网络模型,得到两个特征向量$f(x_1), f(x_2)$,然后计算它们之间的欧氏距离$d = ||f(x_1)-f(x_2)||_2$,并将其作为损失函数的一部分。如果两个相同类别的样本(即$y_1=y_2$)距离小于一个预设的阈值$m$,则认为它们是“相似”的,此时损失为$d^2$,反之如果是不同类别的样本(即$y_1\neq y_2$)距离大于$m$,则认为它们是“不相似”的,此时损失为$max(0, m-d)^2$。 在PyTorch中,可以使用以下代码来定义对比损失: ```python loss_fn = nn.ContrastiveLoss(margin=1.0) ``` 其中`margin`参数是阈值$m$。 然后将输入样本和相应标签传递给模型并计算损失,例如: ```python x1, x2 = get_input_samples() # 获取输入样本 y = get_input_labels() # 获取标签 out1, out2 = model(x1, x2) # 执行前向计算 loss = loss_fn(out1, out2, y) # 计算损失 ``` 需要注意的是,在使用对比损失函数时,样本对的构造方式至关重要。一般来说,可以使用负采样的方式来构造不同类型的样本对,使得训练集中正样本和负样本数量相等。否则,模型很容易就会收敛到一个平凡的解。 总之,对比损失是一种较为常用的损失函数,可以用于许多不同的任务,例如人脸识别、图像检索、文本分类等。在PyTorch中,可以很方便地使用`nn.ContrastiveLoss()`实现对比损失的计算。 ### 回答3: contrastive loss就是一种损失函数,其主要目的是将同类样本的特征向量拉近,把不同类的特征向量拉远。这有助于使训练模型更加准确地分类不同类的问题。 PyTorch是一种用于构建深度学习模型的开源框架,使用PyTorch可以更方便地实现深度学习算法。 在PyTorch中,实现contrastive loss方法可以通过构建一个自定义的损失函数来实现。首先,需要定义一个度量函数,用于度量输入样本之间的相似度。其中,常见的度量函数有欧式距离和余弦距离等。然后,在自定义的损失函数中,根据度量函数计算输入样本之间的相似度,并利用这些值来计算损失。 具体而言,对于具有标签的输入数据,损失函数的计算包括以下步骤: 1. 首先,将输入数据分为两类,一类是同类样本,一类是不同类样本。 2. 对于同类样本,使用定义的度量函数度量它们之间的相似度,并将相似度值作为损失函数的一部分。 3. 对于不同类样本,使用度量函数度量它们之间的距离,并将距离值作为损失函数的一部分。同时,需要设置一个阈值,将距离值小于阈值的样本划分为同类样本。 4. 最终,将同类样本和不同类样本的损失加权求和,并反向传播用于调整模型参数。 总之,contrastive loss pytorch可以通过自定义损失函数来实现。对于训练深度学习模型时需要进行分类或相似度匹配问题时,contrastive loss pytorch是一个非常有效的工具。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值