一文搞懂负对数似然(Negative Log-Likelihood)

1 阅读2分钟

做分类任务时,你一定见过这个损失函数。它到底在算什么?为什么几乎所有深度学习框架都默认用它?

从直观理解开始

假设你有一个分类模型,预测一张图是猫的概率是 0.8,是狗的概率是 0.2。如果这张图真的是猫,你希望模型对"猫"的预测概率越接近 1 越好。

似然(Likelihood) 就是衡量"模型预测与实际标签有多匹配"的指标。预测越准,似然值越大。本质上,它在回答:给定当前模型参数,观察到这些训练数据的概率有多大?

为什么要取对数?

概率都是小于 1 的数,连乘起来会越乘越小,甚至下溢为 0。比如 0.1 的 100 次方,计算机直接当成 0 处理。

取对数有两个好处:

  • 把乘法变加法,计算更稳定
  • 把指数运算拉平,求导更简单

为什么要加负号?

对数后的似然值通常是负数(因为 log(0.8) < 0)。而损失函数习惯上越小越好,加个负号就顺理成章了。于是"最大化似然"变成了"最小化负对数似然",完美融入梯度下降的框架。

公式长这样

NLL = -\sum{i=1}^{N} \log(p(y_i|x_i))

简单说:对每个样本,取模型预测正确类别的概率的对数,累加后取负。

举个例子:三分类任务,真实标签是第 2 类,模型输出 softmax 概率是 [0.2, 0.7, 0.1]。NLL = -log(0.7) ≈ 0.36。如果模型更自信,输出 [0.1, 0.9, 0.0],则 NLL = -log(0.9) ≈ 0.11,损失更低。

和交叉熵的关系

二分类时,NLL 等价于二元交叉熵;多分类时,等价于交叉熵损失。所以你在 PyTorch 里看到的 CrossEntropyLoss,底层就是 NLL 加上 Softmax。

区别是:NLLLoss 要求输入已经过 log-softmax,而 CrossEntropyLoss 帮你做了 softmax + log + NLL 的打包操作。

为什么不用准确率当损失?

准确率不可导。预测从 0.51 变到 0.99,准确率都是"对",但模型明显进步了。NLL 能捕捉这种细微变化,给出连续的梯度信号。


一句话总结:负对数似然就是在问"模型对正确答案有多自信",然后惩罚那些不自信(或自信错了)的预测。它是连接概率统计和梯度优化的桥梁。


💡 下次写代码时,你就知道 criterion = nn.CrossEntropyLoss() 背后在算什么了。