【Pytorch】对比CrossEntropyLoss与NLLLoss

CrossEntropyLoss(交叉熵损失)与NLLLoss(negative log likelihood,负对数似然损失)都是适用于分类问题,基于log似然损失,即交叉熵损失函数的实现方式,其体现了两个分布的近似程度: L ( p , q ) = − ∑ i p i log ⁡ q i L(p,q)=-\sum_ip_i\log q_i L(p,q)=ipilogqi对于分类问题,其只在真实所属类别 k k k上的编码为1,其他均为0(即one-hot编码),所以该损失函数可进一步写为: L = − C k log ⁡ q k L=-C_k\log q_k L=Cklogqk

CrossEntropyLoss和NLLLoss的区别在于:
(1)CrossEntropyLoss对输出层结果自动进行softmax概率归一化运算以及对数处理,然后再基于 L = − C k log ⁡ q k L=-C_k\log q_k L=Cklogqk进行计算;
(2)NLLLoss直接计算 L = − C k log ⁡ q k L=-C_k\log q_k L=Cklogqk,因此为了保证计算的正确,必须接在logsoftmax函数后面。

也就是说,在pytorch中:CrossEntropyLoss()=logsoftmax()+NLLLoss()

下面以一个例子来验证该结论:

import torch
import torch.nn as nn
output = torch.rand(3, 5)   # 随机输出的3*5未归一化结果
target = torch.tensor([0, 1, 4])   # 对应3个样本的真实分类

criterion1 = nn.NLLLoss()
criterion2 = nn.CrossEntropyLoss()

# 方案一:直接采用CrossEntropyLoss()
print(criterion2(output, target))

# 方案二:在output后接入logsoftmax(),再计算NLLLoss()
logsoftmax = nn.LogSoftmax(dim=1)
output_logsoftmax = logsoftmax(output)
print(criterion1(output_logsoftmax, target))

# 方案三:手动计算交叉熵损失函数的平均值
target_onehot = torch.zeros_like(output)
for i,j in enumerate(target):
    target_onehot[i][j] = 1
crossentropy = - (target_onehot * output_logsoftmax).sum()/len(target)
print(crossentropy)

结果表明,上述三种方法计算的结果是完全相同的。

此外,还有一个注意值得的细节为:作为Target的分类编码要从0开始计起

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值