aistudio:https://aistudio.baidu.com/aistudio/projectdetail/4505831?forkThirdPart=1
论文地址:https://arxiv.org/pdf/1801.07698.pdf
复现github地址:https://github.com/GuoQuanhao/arcface-Paddle
原始github地址:https://github.com/deepinsight/insightface/tree/master/recognition
参考:https://zhuanlan.zhihu.com/p/101059838
就是通过余弦角来比对,输入特征和不同类中心的距离,引入空余角度,使得不同的类能在空间上能拉开。
人脸检测的目标强调类内聚,类间开,主流的人脸识别网络包含三个部分:数据、网络、loss。其中数据越多越好,网络能力越高越好,而LOSS是近几年最关注的一个目标。
人脸识别分为四个过程:人脸检测、人脸对齐、特征提取、特征匹配。其中,特征提取作为人脸识别最关键的步骤,提取到的特征更偏向于该人脸独有的特征,对于特征匹配起到举足轻重的作用,而我们的网络和模型承担着提取特征的重任,优秀的网络和训练策略使得模型更加健壮。
自RseNet提出以后,越来越多的网络基于ResNet进行优化,取得较好的结果,但是网络优化进一步升级愈加困难,目前研究人员把研究重心放到了损失函数优化方面。
参考:https://zhuanlan.zhihu.com/p/374733665
1、目前的softmax-loss的存在的问题:
计算过程如图:首先经过网络,获得特征矩阵,和一个线性的矩阵相乘,得到一个score,经过softmax函数,以及一个交叉熵。但softmax存在问题:不存在Margin概念。W(代表每一类的Center)可能非常大(随着identity的增大线性增长)。
2、目前的Triplet-loss的存在的问题:
Triplet-loss符合类内要要聚合,类间要开的想法。“Margin”也是一个有效方法。但是图片与图片比较的时候,由于图片数量较多,组合的pair数越多,一旦组合的数目非常多,不太可能进行穷举,只能选择其中一部分来比较。使用了semi-hard技巧。目前对Triplet-loss做出的探索,发现使用的pair数量越多,效果越稳定越好。
TripLet loss将postive的距离缩小,negative的距离放大,如果可以将图片与图片之间的比对,换成图片和类别之间的比对,计算量可以大大缩小。
因为Triplet-loss的关注点在图片的比较上,是不是可以把思想转变为图像和类之间的比较过程?因为图像中类的数目远远小于图像的数目 。(因为class num 远小于image num)如果将一张图像分别和自己的类与其他图像的类作比较,相对于该图片与其他所有图片作比较,比价次数明显变小。但问题是我们怎么获得图像类别的表达? 因为如果我们把所有的样本都forward出来,求最小值或者求中间值,但是这样的训练往往是不高效的。
3、改进的ArcFace结构,W是d*n的矩阵,然后对于W的每一列(代表每一类的center)
我们希望:
既要有大量图像之间的比
有margin概念
希望系统之间有大规模的训练。
所以ArcFace基于该思想做了改进:
整体流程图下图所示:resNet model输出特征,进入archead将特征和权重间加上margin输出预测标签,softmax loss求预测标签和实际标签的误差。
ArcFace也像Triple loss一样,对feature进行Normalization,xi是1d的输入特征向量,对该向量执行L2正则化操作就得到xi/||xi||。W是dn的矩阵,然后对于W的每一列(代表每一类的center)进行Normalization,两个都标准化以后,当它们的模为1的时候,W和X做矩阵相乘得到全连接层的输出,就是cosθ的值(严格讲是||xi/(||xi||)||*||Wj/(||Wj||)||*cosθj,因为前面两项都是1,所以就是cosθj)。对于target logit,也就是真实的similarity score,进行arccos得到它的角度(也就是说任何一个图片xi,和它的center W之间有一个夹角)。
1.思路简单,只需要几行代码可以构造loss,在softmax损失上操作较为简单。
2.arcface解释起来非常清晰。
如图,论文挑了8个identity,投影到二维的空间,左边是没加margin的softmax。右边是加了margin以后,做到了类内聚,类间开。用人脸的示意图来看,类W1和类W2之间,各自类别的图片围绕着各自类别的center分布,类和类之前存在Margin,一旦在Normalize的空间,就和Arc弧相对应。
unzip -d ./ data/data80496/faces_emore.zip
注意:mxnet_reader用于Linux系统部署训练,mxnet_reader_win10用于win10系统部署训练,两者均为重构mxnet数据读取后的代码
python train.py --network iresnet18
detach的方法,将variable参数从网络中隔离开,不参与参数更新。
如下:
# y=A(x), z=B(y) 求B中参数的梯度,不求A中参数的梯度
y = A(x)
z = B(y.detach())
z.backward()