You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中CrossEntropyLoss计算疑问:为何结果为0.7437而非0?

PyTorch CrossEntropyLoss 计算结果与手动推导不符的原因分析

哈哈,这个问题我当初刚上手PyTorch的时候也踩过一模一样的坑!你手动计算的交叉熵是基于已经归一化完成的概率分布,但PyTorch的nn.CrossEntropyLoss()根本不是这么算的——它其实是把LogSoftmax和NLLLoss(负对数似然损失)打包在一起的组合函数,输入要求是未经过softmax的原始输出(也就是常说的logits),而不是直接输入概率值。

我们来一步步拆解你给出的例子,就能明白为什么结果是0.7437了:

1. CrossEntropyLoss的核心计算步骤

nn.CrossEntropyLoss()的完整计算逻辑是:

  • 第一步:对输入的logits执行softmax操作,得到归一化的概率分布
  • 第二步:对得到的概率值取自然对数(ln)
  • 第三步:针对目标类别,取对应对数概率的负值作为最终损失

2. 代入你的例子计算

你的输入logits是[0,0,0,1],目标类别是3:

  • 第一步:计算softmax
    softmax的公式是每个元素的e^x除以所有元素e^x的总和:
    sum = e^0 + e^0 + e^0 + e^1 = 1 + 1 + 1 + 2.71828 ≈ 5.71828
    目标类别3对应的softmax值 = e^1 / sum ≈ 2.71828 / 5.71828 ≈ 0.4754
  • 第二步:取自然对数
    ln(0.4754) ≈ -0.7437
  • 第三步:取负值得到损失
    最终损失 = -(-0.7437) = 0.7437

3. 如何得到你预期的0损失?

如果你想得到手动推导的0损失,需要先把输出转换成概率分布,再配合对应的损失函数:
比如先对logits做softmax得到[0,0,0,1],然后取对数得到[-inf, -inf, -inf, 0],再用nn.NLLLoss()计算,此时损失就是0。对应的测试代码大概是这样:

import torch
import torch.nn as nn
from torch.autograd import Variable

output = Variable(torch.FloatTensor([0,0,0,1])).view(1, -1)
target = Variable(torch.LongTensor([3]))

# 先做softmax+log
log_probs = torch.log(torch.softmax(output, dim=1))
criterion = nn.NLLLoss()
loss = criterion(log_probs, target)
print(loss)  # 输出0.0

内容的提问来源于stack exchange,提问作者MBT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:06:59