PyTorch框架学习十二——损失函数

之前的笔记写过,一个深度学习/机器学习模型的实现过程主要来说包括五部分:数据、模型、损失函数、最优化和迭代过程。前面的笔记已经介绍了数据部分和模型部分,这次笔记主要介绍损失函数。

因为在实际使用中根据不同的实际情况会选择不同的损失函数,所以对损失函数的公式推导就不涉及了,以后具体用到什么再写什么吧,这次笔记聚焦于PyTorch中损失函数的构建与工作原理,并简单介绍常用的18种损失函数,具体公式推导应参考相关论文,这里不详细推导。

一、损失函数的作用

损失函数简单来说就是用来衡量模型输出(预测值)与真实标签(真实值)的差异的。

有三个概念很容易混淆:

  1. 损失函数:在这里插入图片描述
  2. 代价函数:在这里插入图片描述
  3. 目标函数:在这里插入图片描述
    其中,损失函数是关于某一个具体样本的衡量,代价函数是所有样本的损失的平均,目标函数是在代价函数的基础上加上正则化。

二、18种常见损失函数简述

1.L1Loss(MAE)

功能:计算inputs与targets之差的绝对值。

torch.nn.L1Loss(size_average=None, reduce=None, reduction: str = 'mean')

参数只需要关注reduction,因为size_average和reduce两个结合做了reduction的事,以后PyTorch会舍弃这两个参数,下面每个损失函数都有这两个参数,就不提了。

reduction是一个字符串参数,能取三个值:‘none’、‘mean’、‘sum’,因为现在计算loss基本都是一个batch的数据样本不是一个单独的样本,所以这三个值分别代表对一个batch的样本分别求loss、求所有loss的均值、求loss的和。

看一个例子:

inputs = torch.ones((2, 2))
target = torch.ones((2, 2)) * 3

loss_none = nn.L1Loss(reduction='none')
loss1 = loss_none(inputs, target)
print("input:{}\n\ntarget:{}\n\nL1 loss_none:{}".format(inputs, target, loss1))

loss_mean = nn.L1Loss(reduction='mean')
loss2 = loss_mean(inputs, target)
print("\nL1 loss_mean:{}".format(loss2))

loss_sum = nn.L1Loss(reduction='sum')
loss3 = loss_sum(inputs, target)
print("\nL1 loss_mean:{}".format(loss3))

输出:

input:tensor([[1., 1.],
        [1., 1.]])

target:tensor([[3., 3.],
        [3., 3.]])

L1 loss_none:tensor([[2., 2.],
        [2., 2.]])

L1 loss_mean:2.0

L1 loss_mean:8.0

2.MSELoss

功能:计算inputs与targets之差的平方。

torch.nn.MSELoss(size_average=None, reduce=None, reduction: str = 'mean')

这个损失函数与L1Loss形式上很相似,直接举例:

inputs = torch.ones((2, 2))
target = torch.ones((2, 2)) * 3

loss_f_mse = nn.MSELoss(reduction='none')
loss_mse = loss_f_mse(inputs, target)

print("input:{}\n\ntarget:{}\n\nMSE loss:{}".format(inputs, target, loss_mse))

输出:

input:tensor([[1., 1.],
        [1., 1.]])

target:tensor([[3., 3.],
        [3., 3.]])

MSE loss:tensor([[4., 4.],
        [4., 4.]])

3.SmoothL1Loss

功能:平滑的L1Loss。

torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction: str = 'mean')

其公式为:
在这里插入图片描述
我们将真实值全部设置为0,就可以绘制出其损失函数的样子,并与L1Loss进行比较:

    inputs = torch.linspace(-3, 3, steps=500)
    target = torch.zeros_like(inputs)

    loss_f = nn.SmoothL1Loss(reduction='none')

    loss_smooth = loss_f(inputs, target)

    loss_l1 = np.abs(inputs.numpy())

    plt.plot(inputs.numpy(), loss_smooth.numpy(), label='Smooth L1 Loss')
    plt.plot(inputs.numpy(), loss_l1, label='L1 loss')
    plt.xlabel('x_i - y_i')
    plt.ylabel('loss value')
    plt.legend()
    plt.grid()
    plt.show()

绘制的结果为:
在这里插入图片描述

4.交叉熵CrossEntropyLoss

功能:nn.LogSoftmax()与nn.NLLLoss()结合,进行交叉熵计算。

torch.nn.CrossEntropyLoss(weight: Optional[torch.Tensor] = None, size_average=None, ignore_index: int = -100, reduce=None, reduction: str = 'mean')

交叉熵损失是分类问题中常用的损失函数,它的计算公式如下:
在这里插入图片描述
若再考虑权重weight,公式为:
在这里插入图片描述
权重的设置在数据不平衡时非常关键。

参数如下所示:

  1. weight:各类别的loss设置权值。
  2. ignore_index:忽略某个类别。
  3. reduction:同上。

举个栗子:

inputs = torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
target = torch.tensor([0, 1, 1], dtype=torch.long)

loss_f_none = nn.CrossEntropyLoss(weight=None, reduction='none')
loss_none = loss_f_none(inputs, target)

print("Cross Entropy Loss:\n ", loss_none)

输出:

Cross Entropy Loss:
  tensor([1.3133, 0.1269, 0.1269])

5.NLLLoss

功能:实现负对数似然函数中的负号功能。

torch.nn.NLLLoss(weight: Optional[torch.Tensor] = None, size_average=None, ignore_index: int = -100, reduce=None, reduction: str = 'mean')

举例:

inputs = torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
target = torch.tensor([0, 1, 1], dtype=torch.long)

weights = torch.tensor([1, 1], dtype=torch.float)
loss_f_none_w = nn.NLLLoss(weight=weights, reduction='none')
loss_none_w = loss_f_none_w(inputs, target)

print("\nweights: ", weights)
print("NLL Loss", loss_none_w, loss_sum, loss_mean)

输出为:

weights:  tensor([1., 1.])
NLL Loss tensor([-1., -3., -3.])

6.PoissonNLLLoss

功能:泊松分布的负对数似然损失函数。

torch.nn.PoissonNLLLoss(log_input: bool = True, full: bool = False, size_average=None, eps: float = 1e-08, reduce=None, reduction: str = 'mean')

主要参数:
在这里插入图片描述

  1. log_input:输入是否为对数形式,决定计算公式是哪一个。
  2. full:计算所有的loss,默认为False。
  3. eps:修正项,避免log(input)为nan。
  4. reduction:同上。

7.KLDivLoss

功能:计算KLD,KL散度。

torch.nn.KLDivLoss(size_average=None, reduce=None, reduction: str = 'mean', log_target: bool = False)

8.BCELoss

功能:二分类交叉熵。

torch.nn.BCELoss(weight: Optional[torch.Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean')

注意:输入值取值在[0,1]。

9.BCEWithLogitsLoss

功能:结合Sigmoid与二分类交叉熵。

torch.nn.BCEWithLogitsLoss(weight: Optional[torch.Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean', pos_weight: Optional[torch.Tensor] = None)

注意:网络最后不加sigmoid函数。

10.MarginRankingLoss

功能:计算两个向量之间的相似度,用于排序任务。

torch.nn.MarginRankingLoss(margin: float = 0.0, size_average=None, reduce=None, reduction: str = 'mean')

说明:该方法计算两组数据之间的差异,返回一个n×n的loss矩阵。

11.HingeEmbeddingLoss

功能:计算两个输入的相似性,常用于非线性embedding和半监督学习。

torch.nn.HingeEmbeddingLoss(margin: float = 1.0, size_average=None, reduce=None, reduction: str = 'mean')

12.MultiLabelMarginLoss

功能:多标签边界损失函数。

torch.nn.MultiLabelMarginLoss(size_average=None, reduce=None, reduction: str = 'mean')

13.SoftMarginLoss

功能:计算二分类的logistic损失。

torch.nn.SoftMarginLoss(size_average=None, reduce=None, reduction: str = 'mean')

14.MultiLabelSoftMarginLoss

功能:SoftMarginLoss多标签版本。

torch.nn.MultiLabelSoftMarginLoss(weight: Optional[torch.Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean')

15.nn.CosineEmbeddingLoss

功能:采用余弦相似度计算两个输入的相似性。

torch.nn.CosineEmbeddingLoss(margin: float = 0.0, size_average=None, reduce=None, reduction: str = 'mean')

16.MultiMarginLoss

功能:计算多分类的折页损失。

torch.nn.MultiMarginLoss(p: int = 1, margin: float = 1.0, weight: Optional[torch.Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean')

17.TripletMarginLoss

功能:三元组损失,人脸验证中常用。

torch.nn.TripletMarginLoss(margin: float = 1.0, p: float = 2.0, eps: float = 1e-06, swap: bool = False, size_average=None, reduce=None, reduction: str = 'mean')

18.CTCLoss

功能:计算CTC损失,解决时序类数据的分类。

torch.nn.CTCLoss(blank: int = 0, reduction: str = 'mean', zero_infinity: bool = False)
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值