Softmax、LogSoftmax、交叉熵、NLLLoss 全套公式
设:
- z:模型输出原始分数,logits,没有 0‑1 约束
- (z_i):第 i 个类别的得分
- C:总类别数量
- y:真实标签,是类别索引((y\in{0,1,...,C-1}))
1. Softmax 公式
把 logits 转为概率分布,(\sum_{i=1}^C p_i = 1)
(p_i = \text{Softmax}(z_i) = \frac{e{z_i}}{\sum_{j=1}{C} e^{z_j}})
输出 (p_i\in(0,1)),代表模型预测第 i 类的概率。
数值问题:(z_i)很大时 (e^{z_i}) 会溢出;工程实现会减去最大值做稳定。
2. LogSoftmax
Softmax 之后取对数,PyTorch CrossEntropyLoss 内部第一步
(\log p_i = \text{LogSoftmax}(z_i) = \log\left(\frac{e{z_i}}{\sum_{j=1}{C} e^{z_j}}\right))## 3. 交叉熵 Cross‑Entropy(针对单标签分类)
原始交叉熵定义(输入是概率p):
(\mathcal L_{\text{CE}} = -\sum_{i=1}^{C} y_i^\text{one‑hot}\cdot \log(p_i))
(y_i^\text{one‑hot}):真实标签的 one‑hot 向量,只有真实类别位置为 1,其余全 0。
所以求和只剩下一项:
(\mathcal L_{\text{CE}} = -\log(p_y))
(p_y):模型对真实类别y预测出来的概率。
含义:真实类别预测概率越大,loss 越小;概率趋近 0,loss 趋向无穷大。
4. NLLLoss(负对数似然损失)
输入是 (\log(p_i))(LogSoftmax 输出),不是原始概率!
(\mathcal L_{\text{NLL}} = -\log(p_y))>
📌 数学关系:
(\text{CrossEntropyLoss}(z,y) = \text{NLLLoss}\big(\text{LogSoftmax}(z),\ y\big))
PyTorch
nn.CrossEntropyLoss输入原始 logits z,内部执行 LogSoftmax → NLLLoss。
❗ 易错提醒
如果你已经手动算出 (p_i=\text{Softmax}(z_i)),不能直接喂给CrossEntropyLoss;
需要先 (\log(p_i)),再送入 NLLLoss:
(\mathcal L_{\text{NLL}} = \text{NLLLoss}\big(\log(\text{Softmax}(z)),y\big))
和上面等价。
5. 平均 loss(batch 版本)
一个 batch 有 N 个样本,总损失对样本求平均:
(\mathcal L_{\text{batch}} = \frac{1}{N}\sum_{n=1}^N -\log(p_{y_n}^{(n)}))
(y_n):第n个样本的真实类别。