深度学习中的 log_softmax函数
概述
log_softmax 就是稳定版的:
log(softmax(x)) \log(\text{softmax}(x)) log(softmax(x))
它把模型输出的原始分数变成对数概率,常用于多分类任务。
1. softmax:把分数变成概率
神经网络最后一层通常输出 logits,比如:
[2.0,1.0,0.0] [2.0, 1.0, 0.0] [2.0,1.0,0.0]
这些数不是概率,可能为负、可能大于 1、和也不为 1。
softmax 负责把它们变成概率:
softmax(x)i=exp(xi)∑jexp(xj) \text{softmax}(x)_i = \frac{\exp(x_i)}{\sum_j \exp(x_j)} softmax(x)i=∑jexp(xj)exp(xi)
例如:
[2.0,1.0,0.0]→[0.665,0.245,0.090] [2.0, 1.0, 0.0] \rightarrow [0.665, 0.245, 0.090] [2.0,1.0,0.0]→[0.665,0.245,0.090]
特点:
- 每个值都大于 0;
- 所有值加起来等于 1;
- 可以表示每个类别的预测概率。
所以,softmax 的作用是:分数变概率。
2. log:把概率变成损失
多分类训练常用交叉熵损失。假设真实类别是第 yyy 类,模型预测它的概率是 pyp_ypy。
我们希望 pyp_ypy 越大越好,等价于让下面这个值越小越好:
−logpy -\log p_y −logpy
这就是负对数似然损失。
例如:
- py=0.9p_y = 0.9py=0.9,损失 −log0.9≈0.105-\log 0.9 \approx 0.105−log0.9≈0.105,很小;
- py=0.01p_y = 0.01py=0.01,损失 −log0.01≈4.605-\log 0.01 \approx 4.605−log0.01≈4.605,很大。
所以,log 的作用是:衡量模型对真实类别的预测有多差。
3. log_softmax:把两步合在一起
既然交叉熵需要:
log(softmax(x)) \log(\text{softmax}(x)) log(softmax(x))
那就可以直接定义一个函数:
log_softmax(x)i=log(softmax(x)i) \text{log\_softmax}(x)_i = \log(\text{softmax}(x)_i) log_softmax(x)i=log(softmax(x)i)
展开后:
log_softmax(x)i=xi−log∑jexp(xj) \text{log\_softmax}(x)_i = x_i - \log \sum_j \exp(x_j) log_softmax(x)i=xi−logj∑exp(xj)
实际实现会减去最大值,防止数值溢出:
log_softmax(x)i=xi−m−log∑jexp(xj−m) \text{log\_softmax}(x)_i = x_i - m - \log \sum_j \exp(x_j - m) log_softmax(x)i=xi−m−logj∑exp(xj−m)
其中 m=maxjxjm = \max_j x_jm=maxjxj。
它的输出是对数概率,对它取 exp 就得到 softmax:
softmax(x)=exp(log_softmax(x)) \text{softmax}(x) = \exp(\text{log\_softmax}(x)) softmax(x)=exp(log_softmax(x))
4. 稳定性
softmax 的输出可能非常小,比如 10−3010^{-30}10−30。再取 log,可能直接变成 −∞-\infty−∞,浮点精度损失严重。
而 log_softmax 把两步合并计算,数值更稳定,也更高效。
所以:
log_softmax= 数值稳定版的log(softmax(x))
5. PyTorch 用法
import torch
import torch.nn.functional as F
x = torch.tensor([[2.0, 1.0, 0.0]]) # logits
y = torch.tensor([0]) # 真实类别
log_probs = F.log_softmax(x, dim=1)
loss = F.nll_loss(log_probs, y)
# 更常用:CrossEntropyLoss 内部 = log_softmax + NLLLoss
loss2 = F.cross_entropy(x, y)
注意:
CrossEntropyLoss接收的是 logits;- 不要再手动加
softmax; NLLLoss接收的是log_softmax的结果。
6. 总结
| 函数 | 作用 |
|---|---|
softmax | 把 logits 变成概率 |
log | 把概率变成对数概率,用于计算损失 |
log_softmax | 稳定地计算 log(softmax(x)) |
CrossEntropyLoss | 内部执行 log_softmax + NLLLoss |
更多推荐

所有评论(0)