这是一篇2022年的ECCV的人脸识别的文章,实习的时候做新模型探索的时候用到了。关于人脸识别这项技术已经是非常成熟的了,但里面可研究的东西还是有的,比如如何更好的区分难分的人脸,这就是分类问题里的难例挖掘。
一.文章亮点:
1.针对人脸识别中的难例挖掘问题,重点研究样本的类中心与最近负类中心的关系
2.对于数据集中的标签噪声,提出了一个闭集噪声的自纠正模块
二.文章和代码分析:
训练和测试的流程,这个没什么好说的,和Arcface的代码非常像,唯一不一样的地方就是多了自纠正模块,这里重点讲一下代码部分的损失函数和自纠正模块。以及如何理解这种方法。
1.损失函数:
整个人脸识别的损失函数都是由softmax loss演化而来:
上面就是softmax loss的函数, ( [ b, feature_dim] )表示输入,W ([num_class,feature_dim])表示标准类别下的特征矩阵(说白了就是每个类别的特征向量矩阵)。而这里是标准矩阵W的转置和输入
相乘,就是求两个向量的相似度。输出为[b,num_class],再加上一个偏置。
1.2归一化的softmax loss:
L1如何变化到L2的呢?首先L1中的输入x和权重W都进行了归一化,那么根据向量相乘的公式
由于都进行了归一化,所以完全可以转化为cos角度,最后在加上一个缩放系数s就得到指数的变化。对于log的分母位置,是把和某一类的角度单拿出来了,也就是把分子部分拿出来了,只是形式不一样,其实都是相等的。
1.3Cosface Loss:
给当前类添加了一个边界m,不过这个边界是添加在cos值上的。
1.4Arcface Loss:
这个间隔m添加在了角度上面,然后通过s的缩放系数,映射到球面上。
1.5BoundaryFace Loss:
添加了一个决策边界,来决定是否要校正标签。
2.代码:
cosine就是权重和输入想乘得到,求sin是为了求phi,phi通过cos的公式可以得到,这样就给角度添加了一个边界,th = -cos(m)。
代码中分为easy_margin 和hard_margin 是为了让phi 在单调递减,具体的证明过程
可以参考这一篇:
arcface代码中对easy_margin的理解_arcface easy_margin-CSDN博客
one_hot:里面存放了batch个样本的真实标签,只不过形式是one_hot的形式,属于自己的那一类为1,其余的都为0.
epoch_start设置了标签的自纠正模块在第几个epoach使用,一般前几个epoch的训练效果并不好,所以不用自纠正模块,在后面阶段才开启自纠正模块。
2.1训练初始阶段:
由于初始阶段没有自纠正模块的参与,因此纠正后的label还是原label,输出output是按照公式来的,对于当前类,会加上一个m的边界,对于其他的类直接取cos值。和公式不同的的是输出output只有分母的部分。
2.2自纠正模块的参与:
right2: 当前这个样本和它标签的相似度
left2:当前这个样本和其他样本标签(除了本标签之外)的相似度。然后取left2(这个样本和其他标签的相似度)集合中,最大值,就表示这个样本和其他标签最相似的标签 (left_max2)。
sub2:表示该样本和其他标签的距离和该样本和本类别中心距离的差值。
temp2:取出那些分类错误的(与其他标签类别的相似度中大于标签本类相似度的),就表示该样本的标签错误了。
然后把这些分类错误的图片地址保存,并进行纠正,保存在txt文件中。
并且将one_hot中该类别的标签进行纠正,表示其标签
后面就和初始的output的计算就是一样的了。
这里有一个final表示,最后loss的补偿,由于里面存在着分类错误的标签,所以补偿的部分就是分类错误的这一部分的差值,由于一个batch中可能有多个样本分类错误,所以这里取了平均值并且乘上了一个。
整个代码核心的模型部分就解释完毕,其余都是简单的部分。
欢迎讨论和指正!!!!