Pytorch详解NLLLoss和CrossEntropyLoss、以及softmax和log_softmax

数据

import torch
import torch.nn.functional as F
import numpy as np

# 随机新建3个样例数据,每个样例数据包含4个属性特征
input = torch.randn(3,4)
tensor([[ 0.0054, -0.8030, -0.5758, -0.6518],
        [-0.5518,  0.3904,  0.5296,  0.4973],
        [ 0.1608,  0.5822,  0.9536, -0.3173]])

softmax

使用softmax对数据进行处理:

F.softmax(input, dim=1)

dim=1表示跨列操作,行数不变。输出结果:

tensor([[0.3963, 0.1766, 0.2216, 0.2054],
        [0.1067, 0.2738, 0.3147, 0.3047],
        [0.1868, 0.2847, 0.4127, 0.1158]])

每一行元素相加为1.

log_softmax

使用log_softmax进行处理:

F.log_softmax(input, dim=1)

输出结果:

tensor([[-0.9255, -1.7339, -1.5067, -1.5827],
        [-2.2375, -1.2953, -1.1561, -1.1883],
        [-1.6778, -1.2564, -0.8850, -2.1558]])

softmax和log_softmax联系

log_softmax相当于对softmax做了log操作,下面进行验证:

# 首先将tensor类型转为numpy类型
np_data = F.softmax(input, dim=1).data.numpy()
np.log(np_data)

输出结果为:

array([[-0.9255125 , -1.7338518 , -1.5066911 , -1.5826656 ],
       [-2.2374916 , -1.2952974 , -1.1560525 , -1.1883242 ],
       [-1.6778362 , -1.2563533 , -0.88496906, -2.155847  ]],
      dtype=float32)

可以看出与log_softmax的结果一致,log_softmax就是对softmax的结果做了log
softmax将数值压缩至0~1,而log_softmax将数据压缩至负无穷~0

NLLLoss

NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来,再去掉负号,再求均值。

NLLLoss的输入是一个log_softmax和一个目标label

假设我们的数据正确的label是[0,2,3],第一行取第0个元素,第二行取第2个,第三行取第3个,去掉负号,得到[0.9255125,1.1560525,2.155847],然后求平均,结果是:(0.9255125+1.1560525 + 2.155847)/3=1.4124706666666667

下面使用NLLLoss函数验证一下:

target = torch.tensor([0,2,3])
loss = F.nll_loss(F.log_softmax(input, dim=1),target)

得到loss=tensor(1.4125)
结果一致。

CrossEntropyLoss

交叉熵的计算公式为:
c r o s s e n t r o p y = − ∑ k = 1 N ( p k ∗ l o g q k ) cross_entropy=-\sum_{k=1}^N(p_k*log q_k) crossentropy=k=1N(pklogqk)

其中 p p p表示真实值,在这个公式中是one-hot形式; q q q是预测值,在这里假设已经是经过 s o f t m a x softmax softmax后的结果了。

仔细观察可以知道,因为 p p p的元素不是0就是1,而且又是乘法,所以很自然地我们如果知道1所对应的index,那么就不用做其他无意义的运算了。所以在pytorch代码中target不是以one-hot形式表示的,而是直接用scalar表示。所以交叉熵的公式(m表示真实类别)可变形为:
c r o s s _ e n t r o p y = − ∑ k = 1 N ( p k ∗ l o g q k ) = − ∑ k = 1 N q m cross\_entropy=-\sum_{k=1}^N(p_k*log q_k)=-\sum_{k=1}^Nq_m cross_entropy=k=1N(pklogqk)=k=1Nqm
仔细看看,是不是就是等同于log_softmax和nll_loss两个步骤。

CrossEntropyLoss就是把以上Softmax–Log–NLLLoss合并成一步,我们用刚刚随机出来的input直接验证一下结果是不是1.4125

F.cross_entropy(input,target)

输出结果为tensor(1.4125),结果一致

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
nn.NLLLoss()和nn.CrossEntropyLoss()是用于多分类任务的损失函数,在PyTorch中它们实际上是相同的。唯一的区别在于它们接收的输入不同: - nn.NLLLoss()的输入是一个对数概率向量和一个目标标签,它不会为我们计算对数概率。适合网络的最后一层是log_softmax损失函数的情况。 - nn.CrossEntropyLoss()的输入是一个预测值和一个目标标签,它会为我们自动计算预测值的对数概率,即先做softmax,再做log处理。在实际使用中,两者可以互换使用,效果是一样的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [paddle中nll_loss()与CrossEntropyLoss()损失函数区别](https://blog.csdn.net/weixin_43848436/article/details/115448659)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Pytorch中损失函数 NLLLOSS 和 CROSSENTROPYLOSS 的区别](https://blog.csdn.net/cnhwl/article/details/125518586)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值