从零开始学CV之二损失函数篇(3)

在这里插入图片描述
注:本篇博客大部分内容并非原创,而是本人将之前收藏的资料整理,并加以自己的愚解整合成到一起,方便回顾复习,所有参考资料均已注明出处,并已点赞加收藏~

前言: 上篇我们讲完了图像分类、目标检测常用的损失函数,这篇我们继续往下讲,主要讲的是人脸识别的损失函数。

人脸识别算是CV落地最成熟的一个方向了,损失函数对于人脸模型来说实在是太重要了,常见的人脸识别框架facenet、insightface都会在论文里面花大篇幅去介绍它们的损失函数。

那么这一章,我们按照softmax→Triplet Loss→Center Loss→Sphereface→Cosface→Arcface的顺序介绍人脸识别常用的损失函数。

1. 人脸识别

1.1 Softmax Loss

softmax在激活函数篇章中已经有过详细的介绍,不太了解的同学可以翻一翻之前的内容

https://zhuanlan.zhihu.com/p/380237014

softmax既可以充当激活函数,又可以当损失函数来用(但是和之前讲的激活函数softmax又有一丢丢不一样),在经典的人脸识别框架facenet中,损失函数之一便是softmax(另外几个是tripet loss和center loss,下面再讲),具体的应用大家可以去看下官方开源的代码:

https://github.com/davidsandberg/facenet/blob/master/src/train_softmax.py

1.2 Tripet Loss(三元组损失)

三元组由三部分组成,分别是anchor, positive, negative:

  • anchor是基准
  • positive是针对anchor的正样本,表示与anchor来自同一个人
  • negative是针对anchor的负样本
    在这里插入图片描述
    triplet loss的目标是使得:
  • 具有相同label的样本,它们的embedding在embedding空间尽可能接近
  • 具有不同label的样本,它们的embedding距离尽可能拉远

如下图所示,图中的anchor与positive属于同一id,即 y a n c h o r = y p o s i t i v e y_{anchor}=y_{positive} yanchor=ypositive;而anchor与negative属于不同的id,即 y a n c h o r ≠ y p o s i t i v e y_{anchor}\ne y_{positive} yanchor=ypositive。通过不断学习后,使得anchor与positive的欧式距离变小,anchor与negative的欧式距离变大。其中,这里的anchor、Positive、negative都是图片的d维嵌入向量(我们称之为embedding)。
在这里插入图片描述
使用数学公式进行表达,triplet loss想达到的效果是:
在这里插入图片描述
其中, d ( ) d() d() 表示两个向量之间的欧氏距离, α α α 表示两个向量之间的 margin ,防止 d ( x i a , x i p ) = d ( x i a , x i n ) = 0 d\left(x_{i}^{a}, x_{i}^{p}\right)=d\left(x_{i}^{a}, x_{i}^{n}\right)=0 d(xia,xip)=d(xia,xin)=0。因此,可以最小化triplet loss损失函数来达到此目的:
在这里插入图片描述
综上:

  • triplet loss 最终的优化目标是拉近 a , p a, p a,p 的距离, 拉远 a , n a, n a,n 的距离
  • easy triplets : L = 0 L = 0 L=0 d ( a , p ) + m a r g i n < d ( a , n ) d ( a , p ) + m a r g i n<d(a,n) d(a,p)+margin<d(a,n) ,这种情况不需要优化,大部分情况下 a , p a, p a,p 的距离很近, a , n a, n a,n 的距离远
  • hard triplets : d ( a , n ) < d ( a , p ) d ( a , n ) <d ( a , p ) d(a,n)<d(a,p) , 即 a , p a, p a,p 的距离远
  • semi-hard triplets : d ( a , p ) < d ( a , n ) < d ( a , p ) + m a r g i n d ( a , p ) d ( a , p ) <d ( a , n )<d ( a , p ) + m a r g i n d(a, p) d(a,p)<d(a,n)<d(a,p)+margind(a,p)
  • FaceNet 中是随机选取semi-hard triplets 进行训练的, (也可以选择 hard triplets 或者两者一起进行训练)

训练方式:

  • offline mining

在训练每个epoch的开始阶段,计算训练集种所有的embedding,并挑选出所有的hard triplets和semi-hard triplets,并在该epoch内训练这些triplets.

这种方式不是很高效,因为每个epoch我们都需要遍历整个数据集来生产triplets。

  • online mining

这种想法就是对于每个batch的输入,动态地计算有用的triplets。给定batch size为 B B B B B B必须为3的倍数)的样本,我们计算其对应的 B e m b e d d i n g s B_{embeddings} Bembeddings ,此时我们最多可以找到 B 3 t r i p l e t s B^3 triplets B3triplets。当然这其中很多triplet都不是合法的(因为triplet中需要有2个是相同label,1个是不同label)

1.3 Center Loss

Center Loss函数提出于ECCV2016的一篇论文,论文链接:

http://ydwen.github.io/papers/WenECCV16.pdf

为了提高特征的区分能力,作者提出了center loss损失函数,不仅能缩小类内差异,而且能扩大类间差异。

作者首先在MNIST数据集上进行试验,将隐藏层的最后输出维度改为2,使用softmax+交叉熵作为损失函数,将其结果可视化出来,如下图所示。可以看出,交叉熵可以使每一类分开,数据分布呈射线形,但却不够区分性,即类内差异大。

在这里插入图片描述
左边为50K的训练集,右边为10K的测试集,也间接说明数据量足够大可以使算法的鲁棒性越强

因此,作者想要在保持数据的可分性前提下,进一步缩小类内之间的差异。为了达到这个目的,提出了Center Loss损失函数:
在这里插入图片描述
Center Loss的实现是通过先产生所有类别的向量,然后将这些随机的向量与该类别真正的向量求欧式距离,求得的欧氏距离便作为center loss,通过反向传播自动调整这些初始为随机的向量。

其中, c y i c_{y_i} cyi 表示第 y i y_i yi 类的中心。因此,通常将Center Loss和交叉熵进行结合,构成组合损失函数:
在这里插入图片描述
其中, λ λ λ 表示center loss的惩罚力度。同样在MNIST中,其结果如下图所示。可以看到随着 λ λ λ 的增加,约束性更强,每一类会更聚集在类内中心处。
在这里插入图片描述
在使用Center Loss损失函数时,需要引入两个超参: α α α λ λ λ 。其中, λ λ λ表示center loss的惩罚力度;而 α α α 控制类内中心点 c y i c_{y_i} cyi的学习率。类内中心点 c y i c_{y_i} cyi 应该随着特征的不同,会产生变化。一般会在每个mini-batch中更新类内中心点 c y i c_{y_i} cyi

参考

[1] https://www.cnblogs.com/dengshunge/p/12252820.html
[2] https://zhuanlan.zhihu.com/p/295512971
[3] https://blog.csdn.net/u013082989/article/details/83537370

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值