别再混淆了!PyTorch里NLLLoss和CrossEntropyLoss到底啥关系?一个例子讲清楚
在PyTorch框架中构建分类模型时,损失函数的选择往往让开发者陷入纠结——特别是当代码在nn.NLLLoss()和nn.CrossEntropyLoss()之间反复横跳时。许多教程对二者的解释要么过于理论化,要么直接给出"等价"结论却不说透底层逻辑。本文将通过一个完整的代码案例,带你穿透API文档的表层描述,真正理解这对"孪生兄弟"的设计哲学和使用边界。
1. 从分类任务看损失函数的本质
分类问题的核心是让模型输出类别概率分布。假设我们处理一个三分类任务,模型最后一层通常输出三个未归一化的数值(logits)。这些logits需要转化为概率形式,此时Softmax函数登场:
python复制import torch
logits = torch.tensor([[2.0, 1.0, 0.1]]) # 模型原始输出
probs = torch.softmax(logits, dim=1) # 得到概率分布
print(probs) # 输出: tensor([[0.6590, 0.2424, 0.0986]])
关键点在于:优秀的分类模型应该使目标类别的预测概率尽可能接近1。而衡量预测概率与真实分布差异的指标,正是损失函数的核心使命。这里就引出了两种视角:
- 负对数似然视角:概率越接近1,负对数越小
- 交叉熵视角:衡量两个概率分布之间的差异
实际上在分类任务中,这两种视角殊途同归。下面这个表格展示了二者的数学关系:
| 概念 | 数学表达式 | PyTorch实现 |
|---|---|---|
| 负对数似然 (NLL) | -log(p_target) | nn.NLLLoss() |
| 交叉熵 (CE) | -Σ(y_true * log(y_pred)) | `nn.Cross |
