总结下insightface的相关内容,其实,个人理解,这种用于分类的算法,相比较检测的算法来说的话,要来的简单一点。
为了搞清楚整个算法的流程,这里先对arcface_loss做一些在项目过程中的记录。先贴上损失函数公式
损失函数如上图所示。其实对于arcface的损失函数,网上的理解比比皆是,无非是为了增加分类的准确性,扩大化类间差距,增强类内紧度,引入了参数m。
但是这里看下公式,既然是损失函数,那么我们的网络的输出呢?我们数据的label呢?那么到底是怎么实现的呢?这里再贴上一个简化的网络结构
ok!看下网络结构,首先输入图片维度为(batch,112,112,3),然后中网络的话使用了Res_net100然后每个block做了改变变为IR,作者解释,更有利于人脸特征的提取!在这里我们暂且不研究网络具体结构,然后再看,以Resnet_100为例,网络输出为(batch,512),也就是生成了一个512维的向量来表示图片特征。其实从embedding到下一个(b,class)层,是我们用来构建arcface的,什么意思呢?也就是我们损失函数中的W矩阵是这一层的矩阵,然后利用BP来更新所有的前面的权重!我们先把这些明确,还有就是无论arcface_loss怎么变,最后我们就是要求一个Wx将(batch,512)映射到(batch,classes)上,然后根据这个再使用softmaxloss,来与label求一个误差!
这里结合arcface_loss实现的代码进行一步一步的解释:
这里再明确一点,我们使用arcloss函数,先确定的是softmax损失函数中相当于Wx的部分
def arcface_loss(embedding,labels,w_init,classes,W,s=64,m=0.5):
'''
embedding : (batch,512)
labels : (batch,classes) [1,432,64,78......
classes : 类别数
'''
cos_m = math.cos(m)
sim_m = math.sin(m)
mm = sin_m * m
threshold = math.cos(math.pi - m)
with tf.variable_scope('arcface_loss'):
#首先求||x||
embedding_norm = tf.norm(embedding,