Softmax 是深度学习中最经典的函数之一,几乎所有多分类模型的输出层都少不了它。本文将从原理、数学公式、代码实现到实际应用,带你彻底搞懂 Softmax。
一、什么是 Softmax?
Softmax 函数(归一化指数函数)是一种将任意实数向量转换为概率分布的函数。它是深度学习中多分类任务的"标配"输出函数。
直观理解
| |
它的作用可以用一句话概括:
把一组"分数"转换成一组"概率",分数越高的类别获得越大的概率。
名字的含义
- Soft(软):相对于
argmax(硬性地选最大值),Softmax 给出"软"的概率分布,保留了所有类别的信息 - max:最大的输入值仍会获得最大的概率(放大效应)
二、数学原理
2.1 核心公式
对于一个 $n$ 维实数向量 $\mathbf{x} = [x_1, x_2, …, x_n]$,Softmax 函数定义为:
$$ \text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j=1}^{n} e^{x_j}} $$
公式分解:
| 部分 | 作用 |
|---|---|
| 分子 $e^{x_i}$ | 对每个元素取指数,保证输出为正,且放大数值差异 |
| 分母 $\sum_j e^{x_j}$ | 所有指数值之和,作为归一化因子 |
2.2 为什么用指数函数?
- 保证非负:$e^x > 0$ 恒成立,概率必须非负
- 放大差异:指数函数会让大的更大、小的更小,使"赢家"更突出
- 可微分:处处可导,便于反向传播
- 信息论意义:对应最大熵原理下的解
2.3 手动计算示例
以输入 [2.0, 1.0, 0.1] 为例:
Step 1:计算每个 $e^{x_i}$
$$ e^{2.0} \approx 7.389, \quad e^{1.0} \approx 2.718, \quad e^{0.1} \approx 1.105 $$
Step 2:计算总和
$$ \text{sum} = 7.389 + 2.718 + 1.105 = 11.212 $$
Step 3:归一化
$$ p_1 = \frac{7.389}{11.212} \approx 0.659 $$
$$ p_2 = \frac{2.718}{11.212} \approx 0.242 $$
$$ p_3 = \frac{1.105}{11.212} \approx 0.099 $$
验证:$0.659 + 0.242 + 0.099 = 1.000$ ✅
三、Softmax 的三大特性
1️⃣ 输出是概率分布
- 每个输出值 $p_i \in (0, 1)$
- 所有输出值之和 $\sum_i p_i = 1$
2️⃣ 保持单调性
输入大的,输出也大,排序不变:
$$ x_i > x_j \iff p_i > p_j $$
3️⃣ 指数放大效应
数值差距会被指数函数显著放大:
| |
最大值会"吃掉"大部分概率。
四、代码实现
4.1 NumPy 基础实现
| |
4.2 数值稳定版本(推荐)⭐
直接实现在面对大数值时会溢出:
| |
解决方案:减去最大值
| |
数学证明(减最大值不改变结果):
$$ \frac{e^{x_i - c}}{\sum_j e^{x_j - c}} = \frac{e^{x_i} \cdot e^{-c}}{e^{-c} \cdot \sum_j e^{x_j}} = \frac{e^{x_i}}{\sum_j e^{x_j}} $$
4.3 PyTorch 实现
| |
4.4 批量处理
| |
💡 dim 参数记忆法:对哪个维度做 softmax,哪个维度的和就是 1。
五、梯度与反向传播
5.1 Softmax 的梯度
设 $p_i = \text{Softmax}(x_i)$,其雅可比矩阵为:
$$ \frac{\partial p_i}{\partial x_j} = \begin{cases} p_i(1 - p_i), & i = j \ -p_i \cdot p_j, & i \neq j \end{cases} $$
5.2 与交叉熵的完美配合 🎯
当 Softmax 与交叉熵损失(CrossEntropy)组合使用时,梯度变得异常简洁:
$$ \frac{\partial L}{\partial x_i} = p_i - y_i $$
- $p_i$:Softmax 的预测概率
- $y_i$:真实标签(one-hot 编码)
例子:
| |
这就是为什么分类任务中 Softmax + CrossEntropy 是黄金搭档——梯度形式简洁且不会梯度消失。
六、Softmax vs Sigmoid 🔥
这是面试和实际应用中的高频考点,必须搞清楚!
6.1 对比表格
| 特性 | Softmax | Sigmoid |
|---|---|---|
| 输出维度 | 多维向量(n 维) | 单个标量 |
| 输出范围 | 每个值 $\in (0, 1)$ | $\in (0, 1)$ |
| 概率总和 | $\sum p_i = 1$ | 独立,不受约束 |
| 公式 | $\frac{e^{x_i}}{\sum_j e^{x_j}}$ | $\frac{1}{1+e^{-x}}$ |
| 适用场景 | 多分类(互斥) | 二分类 / 多标签(独立) |
| 类别关系 | 竞争关系 | 独立关系 |
| 常搭配损失 | CrossEntropyLoss | BCEWithLogitsLoss |
6.2 场景对比
场景 A:多分类(互斥)→ 用 Softmax
一张图片识别是猫、狗、鸟中的哪一种,三者只能选一个。
| |
场景 B:多标签(独立)→ 用 Sigmoid
一张图片可能同时包含猫和室内两个独立标签。
| |
6.3 有趣的数学关系
当 Softmax 用于二分类时,它等价于 Sigmoid:
$$ \text{Softmax}([x_1, x_2])_1 = \frac{e^{x_1}}{e^{x_1}+e^{x_2}} = \frac{1}{1+e^{-(x_1-x_2)}} = \text{Sigmoid}(x_1-x_2) $$
所以 Sigmoid 可以看作 Softmax 的二维特例。
6.4 选择决策树
| |
七、Softmax 的进阶变体
7.1 带温度的 Softmax(Temperature Scaling)
通过引入"温度"参数 $T$ 调整分布的平滑程度:
$$ \text{Softmax}(x_i / T) = \frac{e^{x_i/T}}{\sum_j e^{x_j/T}} $$
| |
温度的影响:
| 温度 | 效果 | 应用场景 |
|---|---|---|
| $T < 1$ | 分布更尖锐,更自信 | 模型蒸馏(学生模型) |
| $T = 1$ | 标准 Softmax | 常规训练 |
| $T > 1$ | 分布更平滑 | 探索性采样 |
| $T \to 0$ | 趋近于 argmax(one-hot) | 确定性输出 |
| $T \to \infty$ | 趋近于均匀分布 | 完全随机 |
💡 温度的直觉:温度越高,模型越"犹豫"(概率越平均);温度越低,模型越"自信"(概率越集中)。这与物理中的热力学分布同源。
7.2 LogSoftmax
在实际工程中,常用 LogSoftmax 代替 Softmax,即对 Softmax 的结果取对数:
$$ \text{LogSoftmax}(x_i) = \log\left(\frac{e^{x_i}}{\sum_j e^{x_j}}\right) = x_i - \log\sum_j e^{x_j} $$
| |
为什么用 LogSoftmax?
- 数值稳定:避免概率值过小导致的下溢
- 计算高效:交叉熵损失中需要 $\log p$,直接用 LogSoftmax 省去一次对数运算
- 配合
NLLLoss:LogSoftmax + NLLLoss等价于CrossEntropyLoss
| |
八、实际应用场景
8.1 图像分类
多分类模型(ResNet、ViT 等)的输出层几乎都用 Softmax:
| |
⚠️ 常见错误:训练时在模型里加了 Softmax,又用
CrossEntropyLoss,会导致"双重 Softmax",训练效果变差!
8.2 注意力机制(Attention)
Transformer 的核心——注意力权重就是用 Softmax 归一化的:
$$ \text{Attention}(Q, K, V) = \text{Softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right) V $$
| |
8.3 强化学习中的策略
在策略梯度方法中,Softmax 把动作价值转为动作选择的概率分布:
| |
8.4 知识蒸馏
用带温度的 Softmax 让学生模型学习教师模型的"软标签":
| |
九、常见陷阱与注意事项 ⚠️
9.1 数值溢出
| |
9.2 双重 Softmax
| |
9.3 dim 参数搞错
| |
💡 口诀:分类任务中,
dim要指向类别所在的维度。
十、常见问题 FAQ
Q1:Softmax 和 argmax 有什么区别?
argmax直接返回最大值的索引(硬决策,不可导)Softmax返回一个概率分布(软决策,可导),训练中必须用 Softmax 才能反向传播
Q2:为什么训练时推荐用 CrossEntropyLoss 而不手动写 Softmax?
因为 CrossEntropyLoss 内部融合了 LogSoftmax + NLLLoss,数值更稳定、计算更高效,还能避免双重 Softmax 的坑。
Q3:Softmax 一定要配交叉熵吗?
绝大多数多分类场景是的,因为两者组合后梯度形式最简洁($p_i - y_i$),训练稳定。但在某些场景(如蒸馏、强化学习)也会配 KL 散度等其他损失。
Q4:输入全是负数,Softmax 还能用吗?
可以。$e^x$ 对任意实数都为正,负数输入只是让对应概率变小,不影响归一化。
十一、总结
| 要点 | 内容 |
|---|---|
| 本质 | 把实数向量转为概率分布 |
| 公式 | $\text{Softmax}(x_i) = \dfrac{e^{x_i}}{\sum_j e^{x_j}}$ |
| 三大特性 | 输出为概率、保持单调、指数放大 |
| 数值稳定 | 计算前减去最大值 |
| 黄金搭档 | Softmax + CrossEntropy(梯度为 $p_i - y_i$) |
| vs Sigmoid | 多分类互斥用 Softmax,多标签独立用 Sigmoid |
| 工程实践 | 用 CrossEntropyLoss,别手动加 Softmax |
Softmax 看似简单,却贯穿了分类、注意力、强化学习、知识蒸馏等几乎所有深度学习的核心场景。理解它的原理、数值技巧和使用陷阱,是打好深度学习基础的关键一步。
📌 下一篇预告:交叉熵损失(Cross-Entropy Loss)—— 揭开 Softmax 最佳拍档的神秘面纱。