pytorch loss function (人脸损失函数/ 度量损失函数/回归问题的损失函数)总结

参考文献

https://blog.csdn.net/zhangxb35/article/details/72464152

人脸识别中Softmax-based Loss的演化史(技术改进主要又能被归为两大类别,做归一化以及加 margin)
人脸识别最新进展——几篇相关论文总结

人脸识别损失函数(Center-Loss、A-Softmax、AM-Softmax、ArcFace)
人脸识别损失函数综述(附开源实现)
人脸识别:损失函数总结
人脸识别损失函数(Center-Loss、A-Softmax、AM-Softmax、ArcFace)(对几个loss的优缺点进行了点评)

有大牛在cifar10和 cifar100上测试过 centerloss ,发现效果并不是很好,准确率明显低于单独的 softmax loss ;在mnist 上测试加上centerloss 的 softmax 好于单独的 softmax loss ;所以理解之所以centerloss是针对人脸识别的loss 是有原因的,因为人脸的中心性更强一些,即一个人的所有脸取平均值之后的人脸我们还是可以辨识是不是这个人,所以centerloss才能发挥作用。

人脸识别损失函数简介与Pytorch实现:ArcFace、SphereFace、CosFace

一言以蔽之ArcFace、SphereFace、CosFace三个损失函数相对于前辈们而言,改进的一个核心思路就是:
只有平常(train)更刻苦的训练,才有可能在比赛中(test)中得到更好的结果。
它们都对卷积神经网络提出了更高的目标,在训练阶段更为艰难,也因此让其成为了一个更好的分类器。

人脸损失函数

CenterLoss (2016)

CenterLoss | 减小类间距离
损失函数改进之Center Loss

github代码讲述了怎样实现centerloss,以及怎样使用和更新centerloss,以及特征可视化

  • centerloss的主要思路为:让每一类特征尽可能的在输出特征空间内聚集在一起。更直白的描述就是每一类的特征在特征空间中尽可能的聚集在某一个中心点附近。

  • 中心点是如何维护的?
    接下来就详细讲一下这个动态过程,首先提出一个问题:中心点明明是不确定的,那如何让特征去聚集在这个不确定的特征中心点呢?
    ----- 随机初始化各类的中心点,然后动态更新。
    在这里插入图片描述

用知乎上比较概括性的话来讲就是:
center loss的原理主要是在softmax loss的基础上,通过对训练集的每个类别在特征空间分别维护一个类中心,在训练过程,增加样本经过网络映射后在特征空间与类中心的距离约束,从而兼顾了类内聚合与类间分离。

最终通过将centerloss和softmaxloss进行加权求和,实现整体的分类任务的学习。
在这里插入图片描述
注意:因为center loss要维护一个动态变化的center,所以它本身是具有可学习参数的。因此要为center loss搭配一个优化器。代码参考:https://github.com/KaiyangZhou/pytorch-center-loss

在这里插入图片描述

github的pytorch源码中,centerLoss类有一个初始化参数feat_dim

def init(self, num_classes=10, feat_dim=2, use_gpu=True)
其中,feat_dim指的是输入loss函数进行损失计算的特征向量的维度,一般是将最后全连接层的输出送入centerLoss,所以一般feat_dim和num_classes相等

余弦距离 cosine loss

注意:余弦距离是比较两个向量的相似度,要与“Large Margin Cosine Loss”区别开来(后者是将交叉熵变换到极坐标空间,然后强行加入一个决策边界)。

深度学习分类、识别等任务常用的余弦距离和对应的PyTorch代码

分类结果是可以通过判断两个样本在输出空间对应的向量之间的夹角来得知是否是同一类样本。这个夹角就是所谓的余弦距离,夹角越小,两个样本越相似。

在这里插入图片描述

from torch.nn import functional as F
def calculate_cos_distance(a,b):
    a = F.normalize(a, dim=-1)
    b = F.normalize(b, dim=-1)
    cose = torch.mm(a,b)
    return 1 - cose

CosineMarginLoss(Large-Margin-Cosine-Loss)(2018 CosFace)

pytorch源码
TensorFlow源码

CosineMarginLoss做了两件事:
1、转换了学习空间,由最开始的优化内积变成了现在的优化角度,但是学习到的feature仍然只是separable,还没到达我们的目标:discriminative features。

  • 转换过程如下:
    (1)原始的交叉熵损失:

在这里插入图片描述
上式中,p(i)是指ground truth的标签,q(i)是指预测概率。

分类神经网络中,很多情况下(因为one-hot编码中label只有一项为1,其它都为0)就等效为下式(哭:下式中pi指的是预测概率):
在这里插入图片描述
pi 被正确分类的后验概率,C是类别总数, fi是最后的全连接层(偏置为0)的输出。

上式中,因为采用的是softmax,所以有log(pi)的等式:
在这里插入图片描述
(2)令Wj是分类全连接层参数,x是全连接层前的特征,那么就有:
在这里插入图片描述
这个公式表明向量的范数和角度都会影响后验概率。作者是根据NormFace这篇文章的思想,将||Wj||||x||规范化为一个尺度s。因此,后验概率仅仅依赖于夹角的余弦值。
在这里插入图片描述

到目前为止,模型只是转换了学习空间而已,由最开始的优化内积变成了现在的优化角度,但是学习到的feature仍然只是separable,还没到达我们的目标:discriminative features。(然而这个损失函数仅仅将不同类的特征分离,增强了分类的正确性,学习到的特征判别性还不够强。因此有必要为分类界面引入余弦Margin)

2、引入一个cosine margin来进行度量的约束,让当前样本所属的类别在减去一个m之后仍然属于这个类别
在这里插入图片描述
因此进一步改进后的损失函数通过额外添加的Margin促使学习的特征更具有判别性。最后定义Large Margin Cosine Loss(LMCL):
在这里插入图片描述

ArcFace

ArcFace算法笔记

Circle Loss(2020)

CVPR 2020 Oral | 旷视研究院提出Circle Loss,统一优化视角

MV-Softmax loss(2020)

2020- Mis-classifified Vector Guided Softmax Loss for Face Recognition
我们提出了一种新的MV-Softmax loss算法,它明确指出了难例样本,并着重于它们来指导鉴别特征学习。

CurricularFace(2020)

人脸识别中常用损失函数主要包括两类,基于间隔和难样本挖掘,这两种方法损失函数的训练策略都存在缺陷。
基于间隔的方法是对所有样本都采用一个固定的间隔值,没有充分利用每个样本自身的难易信息,这可能导致在使用大边际时出现收敛问题;
基于难样本挖掘的方法则在整个网络训练周期都强调难样本,可能出现网络无法收敛问题。

为了解决上述问题,优图实验室引入了Curriculum Learning的概念来优化损失函数。

人脸损失函数github源码详解

ArcFace(InsightFace)pytorch代码实现(对官方代码有详细注解)

Angular Penalty Softmax Losses Pytorch

Angular Penalty Softmax Losses Pytorch(实现啦ArcFace、SphereFace、CosFace、Additive Margin等loss,但是这份源码仅有训练部分,没有测试部分的代码)

损失函数的定义

文件:loss_functions.py
三种损失函数进行了统一的定义
在这里插入图片描述

损失函数中引入了一个Linear层,也就引入了参数。这些参数在训练过程中是需要更新的。其中,Linear层的输入是骨干网的输出矢量(如resnet最后的Linear层输出的一维向量,也就是类别数(在画可视化图时,可以将resnet的最后输出改为2,便于画二维可视化图,见center loss的原文))
在这里插入图片描述
在这里插入图片描述

模型的定义

文件:model.py
在这里插入图片描述

训练

在这里插入图片描述

Face_Pytorch

Face_Pytorch( including arcface, cosface and sphereface and so on. 有训练代码、测试代码,注意训练和测试采用的网络结构不一样,后者只使用了骨干网,没有采用Loss函数中的Linear层。)

在这里插入图片描述
在这里插入图片描述

Arcface的loss函数实现

在这里插入图片描述

训练

存在于train.py

  • 训练前的准备

在这里插入图片描述

  • 每一次iter
    在这里插入图片描述
测试
  • 疑问?— 为啥测试时仅用骨干网的输出矢量,但这个矢量的维度却不等于类别数?
  • xys猜测:因为人脸识别跟普通的分类问题不同,并没有确定的类别数量。(普通的分类问题时,骨干网的输出矢量的维度应该就要等于类别数量)

在这里插入图片描述

在这里插入图片描述

人脸损失函数用于普通分类

Arcface loss实现MNIST数据集(pytorch)

分类器ArcFace、ArcLoss在MNIST数据集上的实现和效果

pytorch-center-loss(mnist数据集)

models.py的定义

模型采用Lenet,为了适应centerloss的需要,在模型的最后做了微调。

原始的Lenet就是在卷积层后加入一个全连接层作为logits输出,但该模型中把该全连接层作为了一个特征向量(特征向量的维度=2是为了可视化,也可是其它维度)
在这里插入图片描述
该模型在输出时有两个值,一个是特征向量x,x在训练时后接centerloss计算模块,x在推理时不使用;另一个是分类输出y,y在训练时后接交叉熵损失,y在推理时用作分类
在这里插入图片描述

main.py

训练开始之前定义两个优化器。
在这里插入图片描述

main.py中进行了模型的训练
在这里插入图片描述
main.py模型测试:
在这里插入图片描述

度量学习损失函数

  • 常用度量学习损失函数(介绍了对比损失、三元组损失(Triplet loss)、四元组损失(Quadruplet loss)、难样本采样三元组损失(Triplet loss with batch hard mining, TriHard loss)、边界挖掘损失(Margin sample mining loss, MSML))

  • Margin Sample Mining Loss(MSML是同时兼顾相对距离和绝对距离并引入了难样本采样思想的度量学习方法)

MSML损失的核心思想是:对于每一个训练batch,随机挑选 P 个ID的行人,每个行人随机挑选 K 张不同的图片,即一个batch含有 P×K 张图片,然后计算一个NxN的距离矩阵。之后对于一个batch,我们只挑选一个最难的正样本对和一个最难的负样本对。
这种采样方法并不会浪费训练数据,因为两个样本对的选择,是由整个批次中所有的数据决定的,随着训练次数增加,损失的下降,不仅仅两个选择的样本对,大部分的正负样本对之间的距离都会变大。
TriHard损失是针对batch中的每一张图片都挑选了一个三元组,而MSML损失只挑选出最难的一个正样本对和最难的一个负样本对计算损失。所以MSML是比TriHard更难的一种难样本采样

深度度量学习中的损失函数(Contrastive loss、Triplet loss、N-pair-ms loss、Lifted Struct loss、Proxy NCA loss、Ranked list loss、Multi-Similarity loss)

ranking loss家族正如以上介绍的,在不同的应用中都有广泛应用,然而其表达式都是大同小异的,虽然他们在不同的工作中名儿并不一致,这可真让人头疼。在这里,我尝试对为什么采用不同的别名,进行解释:
1、ranking loss:这个名字来自于信息检索领域,在这个应用中,我们期望训练一个模型对项目(items)进行特定的排序。比如文件检索中,对某个检索项目的排序等。
2、Margin loss:这个名字来自于一个事实——我们介绍的这些loss都使用了边界去比较衡量样本之间的嵌入表征距离,见Fig 2.3
3、Contrastive loss:我们介绍的loss都是在计算类别不同的两个(或者多个)数据点的特征嵌入表征。这个名字经常在成对样本的ranking loss中使用。但是我从没有在以三元组为基础的工作中使用这个术语去进行表达。
4、Triplet loss:这个是在三元组采样被使用的时候,经常被使用的名字。
5、Hinge loss:也被称之为max-margin objective。通常在分类任务中训练SVM的时候使用。他有着和SVM目标相似的表达式和目的:都是一直优化直到到达预定的边界为止。

一些用于回归问题的损失函数

最牛损失函数解读: A General and Adaptive Robust Loss Function
对于一个特定的问题,我们可能需要测试各种损失。在训练一个网络的同时,快速测试各种损失函数不是很神奇吗?本文的主要思想是引入一个广义的损失函数,其中损失函数的鲁棒性可以改变,并可以在训练网络的同时训练这个超参数,以提高性能。这比通过执行网格搜索交叉验证来寻找最佳损失所花费的时间要少得多。

  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值