PyTorch 模型训练实用教程(四):损失函数

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-26 10:29   319   0

目录

PyTorch 的七个损失函数

1. L1loss

2. MSELoss

3. CrossEntropyLoss

4. NLLLoss

5. PoissonNLLLoss

6. KLDivLoss

7. BCELoss

8. BCEWithLogitsLoss

9. MarginRankingLoss

10. HingeEmbeddingLoss

11. MultiLabelMarginLoss

12. SmoothL1Loss

13. SoftMarginLoss

14. MultiLabelSoftMarginLoss

15. CosineEmbeddingLoss

16. MultiMarginLoss

17. TripletMarginLoss


PyTorch 的七个损失函数

我们所说的优化,即优化网络权值使得损失函数值变小。但是,损失函数值变小是否能代表模型的分类 / 回归精度变高呢?那么多种损失函数,应该如何选择呢?请来了解PyTorch 中给出的十七种损失函数吧。

1. L1loss

class torch.nn.L1Loss ( size_average=None , reduce=None )
官方文档中仍有 reduction='elementwise_mean' 参数,但代码实现中已经删除该参数
功能:
计算 output target 之差的绝对值,可选返回同维度的 tensor 或者是一个标量。
计算公式:

参数:
reduce(bool)- 返回值是否为标量,默认为 True
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和

2. MSELoss

class torch.nn.MSELoss ( size_average=None , reduce=None , reduction='elementwise_mean' )
官方文档中仍有 reduction='elementwise_mean' 参数,但代码实现中已经删除该参数
功能:
计算 output target 之差的平方,可选返回同维度的 tensor 或者是一个标量。
计算公式:
reduce(bool)- 返回值是否为标量,默认为 True
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和

3. CrossEntropyLoss

class torch.nn.CrossEntropyLoss ( weight=None , size_average=None , ignore_index=-100 , reduce=None , reduction='elementwise_mean' )
功能:
将输入经过 softmax 激活函数之后,再计算其与 target 的交叉熵损失。即该方法将nn.LogSoftmax() nn.NLLLoss() 进行了结合。严格意义上的交叉熵损失函数应该是nn.NLLLoss()
补充:小谈交叉熵损失函数
交叉熵损失 (cross-entropy Loss) 又称为对数似然损失 (Log-likelihood Loss) 、对数损失;二分类时还可称之为逻辑斯谛回归损失 (Logistic Loss) 。交叉熵损失函数表达式为 L =- sigama(y_i * log(x_i)) pytroch 这里不是严格意义上的交叉熵损失函数,而是先将 input 经过 softmax 激活函数,将向量 归一化 成概率形式,然后再与 target 计算严格意义上交叉熵损失。
在多分类任务中,经常采用 softmax 激活函数 + 交叉熵损失函数,因为交叉熵描述了两个概率分布的差异,然而神经网络输出的是向量,并不是概率分布的形式。所以需要 softmax激活函数将一个向量进行 归一化 成概率分布的形式,再采用交叉熵损失函数计算 loss
再回顾 PyTorch CrossEntropyLoss() ,官方文档中将 nn.LogSoftmax()和 nn.NLLLoss() 进行了结合, nn.LogSoftmax() 相当于激活函数 , nn.NLLLoss() 是损失函数,将其结合,完整的是否可以叫做 softmax+ 交叉熵损失函数呢?
计算公式:

参数:
weight(Tensor)- 为每个类别的 loss 设置权值,常用于类别不均衡问题 weight 必须是 float类型的 tensor ,其长度要于类别 C 一致,即每一个类别都要设置有 weight 。带 weight 的计 算公式:

size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
ignore_index(int)- 忽略某一类别,不计算其 loss ,其 loss 会为 0 ,并且,在采用size_average 时,不会计算那一类的 loss ,除的时候的分母也不会统计那一类的样本。
补充:
output 不仅可以是向量,还可以是图片,即对图像进行像素点的分类,这个例子可以从 NLLLoss() 中看到,这在图像分割当中很有用。

4. NLLLoss

class torch.nn.NLLLoss ( weight=None , size_average=None , ignore_index=-100 , reduce=None , reduction='elementwise_mean' )
功能:
计算公式: loss(input, class) = -input[class] 。举个例,三分类任务, input=[-1.233, 2.657, 0.534] , 真实标签为 2 class=2 ),则 loss -0.534 。就是对应类别上的输出,取一个负号!感觉被 NLLLoss 的名字欺骗了。
实际应用:
常用于多分类任务,但是 input 在输入 NLLLoss() 之前,需要对 input 进行 log_softmax 函数激活,即将 input 转换成概率分布的形式,并且取对数。其实这些步骤在 CrossEntropyLoss中就有,如果不想让网络的最后一层是 log_softmax 层的话,就可以采用 CrossEntropyLoss
完全代替此函数
参数:
weight(Tensor)- 为每个类别的 loss 设置权值,常用于类别不均衡问题。 weight 必须是 float类型的 tensor ,其长度要于类别 C 一致,即每一个类别都要设置有 weight
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为除以权重之和的平均值;为 False 时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
ignore_index(int)- 忽略某一类别,不计算其 loss ,其 loss 会为 0 ,并且,在采用size_average 时,不会计算那一类的 loss ,除的时候的分母也不会统计那一类的样本。

5. PoissonNLLLoss

class torch.nn.PoissonNLLLoss ( log_input=True , full=False , size_average=None , eps=1e-08 , reduce=None , reduction='elementwise_mean' )
功能:
用于 target 服从泊松分布的分类任务。
计算公式:

参数:
log_input(bool)- True 时,计算公式为: loss(input,target)=exp(input) - target * input;
False 时, loss(input,target)=input - target * log(input+eps)
full(bool)- 是否计算全部的 loss 。例如,当采用斯特林公式近似阶乘项时,此为target*log(target) - target+0.5 log(2πtarget)
eps(float)- log_input = False 时,用来防止计算 log(0) ,而增加的一个修正项。即loss(input,target)=input - target * log(input+eps)
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

6. KLDivLoss

class torch.nn.KLDivLoss ( size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
计算 input target 之间的 KL 散度 ( Kullback–Leibler divergence)
计算公式:
补充: KL 散度
KL 散度 ( Kullback–Leibler divergence) 又称为相对熵 ( Relative Entropy ) ,用于描述两个概率分布之间的差异。计算公式 ( 离散时 )
其中 p 表示真实分布, q 表示 p 的拟合分布, D(P||Q) 表示当用概率分布 q 来拟合真实分布 p 时,产生的信息损耗。这里的信息损耗,可以理解为损失,损失越低,拟合分布 q越接近真实分布 p 。同时也可以从另外一个角度上观察这个公式,即计算的是 p q 之间的对数差在 p 上的期望值。
特别注意, D(p||q) ≠ D(q||p) , 其不具有对称性,因此不能称为 K-L 距离。
信息熵 = 交叉熵 - 相对熵
从信息论角度观察三者,其关系为信息熵 = 交叉 - 相对熵。在机器学习中,当训练数据固定,最小化相对熵 D(p||q) 等价于最小化交叉熵 H(p,q)
参数:
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值,平均值为
element-wise 的,而不是针对样本的平均;为 False 时,返回是各样本各维度的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
使用注意事项:
要想获得真正的 KL 散度,需要如下操作:
1. reduce = True size_average=False
2. 计算得到的 loss 要对 batch 进行求平均

7. BCELoss

class torch.nn.BCELoss ( weight=None , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
二分类任务时的交叉熵计算函数。此函数可以认为是 nn.CrossEntropyLoss 函数的特例。其分类限定为二分类, y 必须是 {0,1} 。还需要注意的是, input 应该为概率分布的形式,这样才符合交叉熵的应用。所以在 BCELoss 之前, input 一般为 sigmoid 激活层的输出,官方例子也是这样给的。该损失函数在自编码器中常用。
计算公式:
参数:
weight(Tensor)- 为每个类别的 loss 设置权值,常用于类别不均衡问题。
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

8. BCEWithLogitsLoss

class torch.nn.BCEWithLogitsLoss ( weight=None , size_average=None , reduce=None , reduction='elementwise_mean' , pos_weight=None )
功能:
Sigmoid BCELoss 结合,类似于 CrossEntropyLoss( nn.LogSoftmax() nn.NLLLoss()进行结合)。即 input 会经过 Sigmoid 激活函数,将 input 变成概率分布的形式。
计算公式:

参数:
weight(Tensor)- : batch 中单个样本设置权值, If given, has to be a Tensor of size “nbatch”.
pos_weight-: 正样本的权重 , p>1 ,提高召回率,当 P<1 ,提高精确度。可达到权衡召回率 (Recall) 和精确度 (Precision) 的作用。 Must be a vector with length equal to the number of classes.
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

9. MarginRankingLoss

class torch.nn.MarginRankingLoss ( margin=0 , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
计算两个向量之间的相似度,当两个向量之间的距离大于 margin ,则 loss 为正,小于margin loss 0
计算公式:

参数:
margin(float)- x1 x2 之间的差异。
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

10. HingeEmbeddingLoss

class torch.nn.HingeEmbeddingLoss ( margin=1.0 , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
未知。为折页损失的拓展,主要用于衡量两个输入是否相似。 used for learning nonlinear embeddings or semi-supervised
计算公式:

参数:
margin(float)- 默认值为 1 ,容忍的差距。
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False
时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

11. MultiLabelMarginLoss

class torch.nn.MultiLabelMarginLoss ( size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
用于一个样本属于多个类别时的分类任务。例如一个四分类任务,样本 x 属于第 0类,第 1 类,不属于第 2 类,第 3 类。
计算公式:
x[y[j]] 表示 样 本 x 所属类的输出值, x[i] 表示不等于该类的输出值。
参数:
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
Input: (C) or (N,C) where N is the batch size and C is the number of classes.
Target: (C) or (N,C), same shape as the input.

12. SmoothL1Loss

class torch.nn.SmoothL1Loss ( size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
计算平滑 L1 损失,属于 Huber Loss 中的一种 ( 因为参数 δ 固定为 1 )
补充:
Huber Loss 常用于回归问题,其最大的特点是对离群点( outliers )、噪声不敏感,具有较强的鲁棒性。
公式为:

理解为,当误差绝对值小于 δ ,采用 L2 损失;若大于 δ ,采用 L1 损失。
回到 SmoothL1Loss ,这是 δ =1 时的 Huber Loss
计算公式为:
对应红色线:
参数:
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

13. SoftMarginLoss

class torch.nn.SoftMarginLoss ( size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
Creates a criterion that optimizes a two-class classification logistic loss between input tensor x and target tensor y (containing 1 or -1). (暂时看不懂怎么用,有了解的朋友欢迎补充!)
计算公式:

参数:
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

14. MultiLabelSoftMarginLoss

class torch.nn.MultiLabelSoftMarginLoss ( weight=None , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
SoftMarginLoss 多标签版本, a multi-label one-versus-all loss based on max-entropy,
计算公式:
参数:
weight(Tensor)- 为每个类别的 loss 设置权值。 weight 必须是 float 类型的 tensor ,其长度要于类别 C 一致,即每一个类别都要设置有 weight

15. CosineEmbeddingLoss

class torch.nn.CosineEmbeddingLoss ( margin=0 , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
Cosine 函数来衡量两个输入是否相似。 used for learning nonlinear embeddings or semi-supervised
计算公式:
参数:
margin(float)- : 取值范围 [-1,1] , 推荐设置范围 [0, 0.5]
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

16. MultiMarginLoss

class torch.nn.MultiMarginLoss ( p=1 , margin=1 , weight=None , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
计算多分类的折页损失。
计算公式:

其中, 0≤y≤x.size(1) ; i == 0 to x.size(0) and i≠y; p==1 or p ==2; w[y] 为各类别的weight
参数:
p(int)- 默认值为 1 ,仅可选 1 或者 2
margin(float)- 默认值为 1
weight(Tensor)- 为每个类别的 loss 设置权值。 weight 必须是 float 类型的 tensor ,其长度要于类别 C 一致,即每一个类别都要设置有 weight
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

17. TripletMarginLoss

class torch.nn.TripletMarginLoss ( margin=1.0 , p=2 , eps=1e-06 , swap=False , size_average=None , reduce=None , reduction='elementwise_mean' )
功能:
计算三元组损失,人脸验证中常用。
如下图 Anchor Negative Positive ,目标是让 Positive 元和 Anchor 元之间的距离尽可能的小, Positive 元和 Negative 元之间的距离尽可能的大。

从公式上看, Anchor 元和 Positive 元之间的距离加上一个 threshold 之后,要小于Anchor 元与 Negative 元之间的距离。
计算公式:
参数:
margin(float)- 默认值为 1
p(int)- Th e norm degree ,默认值为 2
swap(float)– The distance swap is described in detail in the paper Learning shallow convolutional feature descriptors with triplet losses by V. Balntas, E. Riba et al. Default: False
size_average(bool)- reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP