nn.CrossEntropyLoss必须接收raw logits而非概率,因其内部已集成LogSoftmax+NLLLoss防溢出计算;输入logits形状为[N,C],target为[N]的LongTensor且取值∈[0,C-1];训练时禁止手动添加Softmax,推理时才需独立调用F.softmax并禁用梯度。

nn.CrossEntropyLoss 的输入必须是 raw logits
它不接受概率,只认未归一化的预测值。传入 torch.softmax 后的结果,会被 nn.CrossEntropyLoss 再次处理——相当于做了两次 softmax,数值会严重失真,loss 可能趋近于 0 或 nan,梯度几乎消失。
常见错误现象包括:loss 下降极慢、准确率卡在随机水平、验证 loss 突然爆掉(如变成 nan 或极大值)。
- 模型最后一层
fc输出后,直接 return,不要接nn.Softmax或F.softmax - 训练时喂给
criterion的必须是原始logits,shape 为[N, C],其中C是类别数 - target 必须是
torch.LongTensor,shape 为[N],每个值 ∈ [0, C-1],不能是 one-hot
内部其实是 LogSoftmax + NLLLoss 的组合
nn.CrossEntropyLoss 不是“先 softmax 再算交叉熵”,而是等价于先执行 F.log_softmax(logits, dim=1),再喂给 F.nll_loss。这个组合比分开写更稳:log_softmax 内部做了 log(sum(exp(x - x.max()))) + x.max() 这类防溢出操作,避免 exp(1000) 直接崩掉。
如果你手动拆开写,得这么配对:
log_probs = F.log_softmax(logits, dim=1) loss = F.nll_loss(log_probs, targets)
但没必要——nn.CrossEntropyLoss 就是为此封装的,少写错、少溢出、少一层 tensor 拷贝。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
推理阶段才需要 Softmax,且必须独立调用
训练时不用 softmax,但部署或看预测概率时,你得自己加。注意:此时用的是 F.softmax(logits, dim=1),不是 F.log_softmax,而且必须在 with torch.no_grad(): 下做,避免影响计算图。
- 别在 model.forward() 里永久加上 softmax——这会让训练和推理行为不一致
- 如果要用概率做阈值过滤或可视化,只在 inference 路径显式调用
F.softmax - 某些导出工具(如 TorchScript、ONNX)对模型结构敏感,输出层含 softmax 可能导致部署失败或精度偏差
和 nn.NLLLoss 的区别不能混用
nn.NLLLoss 的输入预期是 log-probabilities,也就是 log(softmax(x))。如果你误把 raw logits 丢给它,loss 会是负数甚至报错;而把 F.log_softmax 结果喂给 nn.CrossEntropyLoss,也会因重复 log 导致数值异常。
简单记法:
-
nn.CrossEntropyLoss← 接logits -
nn.NLLLoss← 接log_softmax(logits) -
nn.BCEWithLogitsLoss← 类似,但用于二分类,也自带 sigmoid
最易忽略的点:很多人查文档只看函数名,不看参数类型和 shape 要求,结果把 target 写成 one-hot 或 float,或者把 logits 和 probs 搞反——这两个张量看着像,但数学含义和数值范围完全不同。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










