最近学习 pytorch,将其损失函数大致使用场景做了一下汇总,多参考网上大家的文章,或直接引用,文后附有原文链接,如有不对,欢迎指正
一、L1Loss
L1 Loss,它有几个别称:
- L1 范数损失
- 最小绝对值偏差(LAD)
- 最小绝对值误差(LAE)
最常看到的 MAE 也是指L1 Loss损失函数
它是把目标值 g 与模型输出(估计值) y 做绝对值得到的误差 。
什么时候用?
- 回归任务
- 简单的模型
- 由于神经网络通常是解决复杂问题,所以很少使用。
二、MSELoss
也就是L2 Loss了,它有几个别称:
- L2 范数损失
- 最小均方值偏差(LSD)
- 最小均方值误差(LSE)
最常看到的 MSE 也是指L2 Loss损失函数,PyTorch中也将其命名为torch.nn.MSELoss
它是把目标值 g 与模型输出(估计值) y 做差然后平方得到的误差
什么时候使用?
- 回归任务
- 数值特征不大
- 问题维度不高
三、SmoothL1Loss
简单来说就是平滑版的L1 Loss。
原理
当预测值和ground truth差别较小的时候(绝对值差小于1),其实使用的是L2 Loss;而当差别大的时候,是L1 Loss的平移。
SmoothL1Loss其实是L2Loss和L1Loss的结合 ,它同时拥有L2 Loss和L1 Loss的部分优点。
- 当预测值和ground truth差别较小的时候(绝对值差小于1),梯度不至于太大。(损失函数相较L1 Loss比较圆滑)
- 当差别大的时候,梯度值足够小(较稳定,不容易梯度爆炸)。
什么时候使用?
- 回归
- 当特征中有较大的数值
- 适合大多数问题
四、交叉熵损失 CrossEntropyLoss
原理
交叉熵损失函数图形(分类情况):
单个样本的交叉熵损失函数:
当 y = 1 时:
这时候,L 与预测输出的关系如下图所示:
看了 L 的图形,简单明了!横坐标是预测输出,纵坐标是交叉熵损失函数 L。显然,预测输出越接近真实样本标签 1,损失函数 L 越小;预测输出越接近 0,L 越大。因此,函数的变化趋势完全符合实际需要的情况。
当 y = 0 时:
这时候,L 与预测输出的关系如下图所示:
同样,预测输出越接近真实样本标签 0,损失函数 L 越小;预测函数越接近 1,L 越大。函数的变化趋势也完全符合实际需要的情况。
从上面两种图,可以帮助我们对交叉熵损失函数有更直观的理解。无论真实样本标签 y 是 0 还是 1,L 都表征了预测输出与 y 的差距。
另外,重点提一点的是,从图形中我们可以发现:预测输出与 y 差得越多,L 的值越大,也就是说对当前模型的 “ 惩罚 ” 越大,而且是非线性增大,是一种类似指数增长的级别。这是由 log 函数本身的特性所决定的。这样的好处是模型会倾向于让预测输出更接近真实样本标签 y。
什么时候用?
torch.nn.CrossEntropyLoss(weight=None,ignore_index=-100, reduction='mean')
参数:
weight (Tensor, optional) – 自定义的每个类别的权重. 必须是一个长度为 C 的 Tensor
ignore_index (int, optional) – 设置一个目标值, 该目标值会被忽略, 从而不会影响到 输入的梯度。
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。
当训练有 C 个类别的分类问题时很有效. 可选参数 weight 必须是一个1维 Tensor, 权重将被分配给各个类别. 对于不平衡的训练集非常有效。
在多分类任务中,经常采用 softmax 激活函数+交叉熵损失函数,因为交叉熵描述了两个概率分布的差异,然而神经网络输出的是向量,并不是概率分布的形式。所以需要 softmax激活函数将一个向量进行“归一化”成概率分布的形式,再采用交叉熵损失函数计算 loss。
五、NLLLoss
什么时候用?
用于多分类的负对数似然损失函数
在神经网络中,可以通过在最后一层添加 LogSoftmax
层来得到对数概率(log-probability). 此时,损失函数计算为 LogSoftmax
+ NLLLoss
的输出. 如果不喜欢新增额外的网络层,可以直接采用 CrossEntropyLoss
, CrossEntropyLoss
的作用就相当于nn.LogSoftmax
+ nn.NLLLoss
六、BCELoss
什么时候用?
二分类任务时的交叉熵计算函数
此函数可以认为是nn.CrossEntropyLoss
函数的特例。其分类限定为二分类,y必须是{0,1}。还需要注意的是,input应该为概率分布的形式,这样才符合交叉熵的应用。所以在BCELoss之前,input一般为sigmoid激活层的输出,官方例子也是这样给的。该损失函数在自编码器中常用
七、BCEWithLogitsLoss
什么时候用?
二分类任务时的交叉熵计算函数
BCEWithLogitsLoss损失函数把 Sigmoid 层集成到了 BCELoss 类中。该版比用一个简单的 Sigmoid 层和 BCELoss 在数值上更稳定,因为把这两个操作合并为一个层之后, 可以利用 log-sum-exp 的 技巧来实现数值稳定。
八、SoftMarginLoss
什么时候用?
计算的是,输入 tensor x 和 target tensor y (包含 1 或 -1) 间的二类分类逻辑损失函数(two-class classification logistic loss )。
九、MultiLabelSoftMarginLoss
什么时候用?
SoftMarginLoss
的多分类版本
计算的是,输入 tensor x 和 target tensor y (size 为 (N,C) 间,基于最大熵(max-entropy)优化 multi-label one-versus-all(一对多)的损失函数,y 只能取 (1,0) 两种,代表正类和负类。
十、KL 散度损失 KLDivLoss
KL 散度,又叫做相对熵,用于描述两个概率分布之间的差,越相似则越接近零。
计算 input 和 target 之间的 KL 散度,KL 散度可用于衡量不同的连续分布之间的距离,在连续的输出分布的空间上(离散采样)上进行直接回归时很有效的。
信息熵 = 交叉熵 - 相对熵 从信息论角度观察三者,其关系为信息熵 = 交叉熵 - 相对熵。在机器学习中,当训练数据固定,最小化相对熵 D(p||q) 等价于最小化交叉熵 H(p,q)
什么时候用?
不同的连续分布之间的距离
十一、MultiMarginLoss
含义
MultiMarginLoss 计算的是,给定输入 2D mini-batch Tensor x 和输出 target 类别索引的 1D Tensor y (0≤y≤x.size(1)−1) 时,multi-class 分类的 hinge loss(margin-based loss) 的优化。
nn.MultiMarginLoss (p=1, margin=1.0, weight=None, size_average=None, reduce=None, reduction='mean')
其中次数p一般缺省为1。
weight为根据样本类别分布而设置的权重,可选择性设置。margin为hinge的阈值,就像图像表示的函数,1也是margin值。该样本错误预测的得分和正确预测的得分,两者的差值可用来表示两种预测结果的相似关系,margin是一个由自己指定的安全系数。
我们希望正确预测的得分高于错误预测的得分,且高出一个边界值 margin,换句话说,越高越好,越低越好,(–)越大越好,(–)越小越好,但二者得分之差最多为margin就足够了,差距更大并不会有任何奖励。这样设计的目的在于,对单个样本正确分类只要有margin的把握就足够了,更大的把握则不必要,过分注重单个样本的分类效果反而有可能使整体的分类效果变坏。分类器应该更加专注于整体的分类误差。
什么时候用?
计算多分类的折页损失
十二、MultiLabelMarginLoss
什么时候用?
多类别(multi-class)多分类(multi-classification)的 Hinge 损失,是上面 MultiMarginLoss 在多类别上的拓展。同时限定 p = 1,margin = 1。
十三、MarginRankingLoss
什么时候用?
nn.MarginRankingLoss(margin=0.0, size_average=None, reduce=None, reduction='mean')
计算两个向量之间的相似度,当两个向量之间的距离大于margin,则loss为正,小于margin,loss为0
十四、HingeEmbeddingLoss
什么时候用?
计算的是,给定输入 tensor x 和 labels tensor y (包含1和-1) 时的损失函数;
往往用于度量两个输入是否相似,如采用 L1 成对距离(pairdistance);
多用于学习非线性嵌入(nonlinear embeddings) 或者半监督学习。
十五、CosineEmbeddingLoss
什么时候用?
和上面的HingeEmbeddingLoss
功能类似,计算的是,给定输入 tensor x 和 labels tensor y (包含1和-1) 时的损失函数;
用于采用 cosine 距离来度量两个输入是否相似;
往往被用于学习非线性嵌入和半监督学习中。
十六、CTCLoss
什么时候用?
nn.CTCLoss(blank=0, reduction='mean', zero_infinity=False)
功能: Connectionist Temporal Classification。主要是解决时序类数据的分类问题,特别是label 和output 不对齐的问题(Alignment problem)
十七、PoissonNLLLoss
什么时候用?
用于target服从泊松分布的分类任务
十八、TripletMarginLoss
什么时候用?
计算三元组损失,人脸验证中常用。
如下图Anchor、Negative、Positive,目标是让Positive元和Anchor元之间的距离尽可能的小,Positive元和Negative元之间的距离尽可能的大。