您当前的位置: 首页 >  ar
  • 3浏览

    0关注

    417博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

人脸识别0-05:insightFace-损失函数arcface-史上最全

江南才尽,年少无知! 发布时间:2019-08-23 09:56:56 ,浏览量:3

以下链接是个人关于insightFace所有见解,如有错误欢迎大家指出,我会第一时间纠正,如有兴趣可以加微信:17575010159 相互讨论技术。 人脸识别0-00:insightFace目录:https://blog.csdn.net/weixin_43013761/article/details/99646731: 这是本人项目的源码:https://github.com/944284742/1.FaceRecognition 其中script目录下的文件为本人编写,主要用于适应自己的项目,可以查看该目录下的redeme文件。

softmax到arcface

在讲解arcface loss之前,我们必须去看一下softmax家族发展的历史,这里就直接贴出链接了,大家去看即可:

softmax变种或增强1:Large-Margin Softmax Loss for Convolutional Neural Networks

softmax增强: A-SoftMax. SphereFace: Deep Hypersphere Embedding for Face Recognition

论文阅读之Arcface:https://blog.csdn.net/Wuzebiao2016/article/details/81839452

ArcFace算法笔记:https://blog.csdn.net/u014380165/article/details/80645489

人脸识别-arcface损失函数:看了前面的,再看这篇,通俗易解。

自我理解

大家看了上面的之后,应该思路也比较清晰了。在这里我也讲解一下自己的理解。如果我们要了解arcface,那么肯定需要了解一下该算法的发展,演变过程, 首先我们来看看

sofrmax loss

在这里插入图片描述

这是传统的的Softmax公式, W x T x i W_x^Tx_i WxT​xi​+ b j b_j bj​代表的是全链接的输出,通过计算会得到每个类别的概率。而这种方式主要考虑是否能够正确的分类,缺乏类内和类间距的约束。在[A Discriminative Feature Learning Approach for Deep Face Recognition]这篇文章中,作者使用了一个比LeNet更深的网络结构,用Mnist做了一个小实验来证明Softmax学习到的特征与理想状态下的差距: 在这里插入图片描述 实验结果表明,传统的Softmax仍存在着很大的类内距离,也就是说,通过对损失函数增加类内距离的约束,能达到比更新现有网络结构更加事半功倍的效果。于是,[A Discriminative Feature Learning Approach for Deep Face Recognition]的作者提出了Center Loss,并从不同角度对结果的提升做了论证。 下面是直接的理解: 在这里插入图片描述 N是样本的数量,i代表第i个样本,j代表第j个类别,fyi代表着第i个样本所属的类别的分数

fyi是全连接层的输出,代表着每一个类别的分数,

每一个分数即为权重W和特征向量X的内积 在这里插入图片描述 每个样本的softmax值即为: 在这里插入图片描述

L-softmax loss

假设一个2分类问题,x属于类别1,那么原来的softmax肯定是希望: W 1 T x > W 2 T x W^T_1x > W^T_2x W1T​x>W2T​x

也就是属于类别1的概率大于类别2的概率,这个式子和下式是等效的: ∣ ∣ W 1 ∣ ∣ ∣ ∣ x ∣ ∣ c o s ( θ 1 ) > ∣ ∣ W 2 ∣ ∣ ∣ ∣ x ∣ ∣ c o s ( θ 2 ) ||W1|| ||x||cos(θ _1) > ||W2|| ||x||cos(θ _2) ∣∣W1∣∣∣∣x∣∣cos(θ1​)>∣∣W2∣∣∣∣x∣∣cos(θ2​)

large margin softmax就是将上面不等式替换为: ∣ ∣ W 1 ∣ ∣ ∣ ∣ x ∣ ∣ c o s ( m θ 1 ) > ∣ ∣ W 2 ∣ ∣ ∣ ∣ x ∣ ∣ c o s ( θ 2 ) ( 0 < θ 1 < p i = 3.14 m ) ||W1|| ||x||cos(mθ _1) > ||W2|| ||x||cos(θ _2)(0= 0: is_softmax = False nembedding = mx.symbol.L2Normalization(embedding, mode='instance', name='fc1n') anchor = mx.symbol.slice_axis(nembedding, axis=0, begin=0, end=args.per_batch_size // 3) positive = mx.symbol.slice_axis(nembedding, axis=0, begin=args.per_batch_size // 3, end=2 * args.per_batch_size // 3) negative = mx.symbol.slice_axis(nembedding, axis=0, begin=2 * args.per_batch_size // 3, end=args.per_batch_size) if config.loss_name == 'triplet': ap = anchor - positive an = anchor - negative ap = ap * ap an = an * an ap = mx.symbol.sum(ap, axis=1, keepdims=1) # (T,1) an = mx.symbol.sum(an, axis=1, keepdims=1) # (T,1) triplet_loss = mx.symbol.Activation(data=(ap - an + config.triplet_alpha), act_type='relu') triplet_loss = mx.symbol.mean(triplet_loss) else: ap = anchor * positive an = anchor * negative ap = mx.symbol.sum(ap, axis=1, keepdims=1) # (T,1) an = mx.symbol.sum(an, axis=1, keepdims=1) # (T,1) ap = mx.sym.arccos(ap) an = mx.sym.arccos(an) triplet_loss = mx.symbol.Activation(data=(ap - an + config.triplet_alpha), act_type='relu') triplet_loss = mx.symbol.mean(triplet_loss) triplet_loss = mx.symbol.MakeLoss(triplet_loss) out_list = [mx.symbol.BlockGrad(embedding)] # 如果使用了softmax if is_softmax: softmax = mx.symbol.SoftmaxOutput(data=fc7, label=gt_label, name='softmax', normalization='valid') out_list.append(softmax) if config.ce_loss: # ce_loss = mx.symbol.softmax_cross_entropy(data=fc7, label = gt_label, name='ce_loss')/args.per_batch_size body = mx.symbol.SoftmaxActivation(data=fc7) body = mx.symbol.log(body) _label = mx.sym.one_hot(gt_label, depth=config.num_classes, on_value=-1.0, off_value=0.0) body = body * _label ce_loss = mx.symbol.sum(body) / args.per_batch_size out_list.append(mx.symbol.BlockGrad(ce_loss)) # 如果是triplet else: out_list.append(mx.sym.BlockGrad(gt_label)) out_list.append(triplet_loss) # 聚集所有的符号 out = mx.symbol.Group(out_list) return out

好了,这次就分析到此为止了

关注
打赏
1592542134
查看更多评论
立即登录/注册

微信扫码登录

0.0408s