Softmax 是深度学习和机器学习中非常核心的一个激活函数,用于多分类过程中,它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。
简单来说,Softmax 的作用是:将一组任意的实数,转换成一个合法的概率分布。
1. 数学公式
假设我们有一个包含 KKK 个实数的向量 z=z1,z2,...,zKz = z_1, z_2, \\dots, z_Kz=z1,z2,...,zK(在神经网络中,这通常是最后一层全连接层的原始输出,称为 Logits ),那么 Softmax 函数针对其中第 iii 个元素的计算公式为:
Softmax(zi)=ezi∑j=1Kezj \text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}} Softmax(zi)=∑j=1Kezjezi
- 分子 :对当前元素 ziz_izi 求指数(ezie^{z_i}ezi)。
- 分母:对所有元素的指数求和。
- 结果 :输出一个与输入维度相同的向量 p=p1,p2,...,pKp = p_1, p_2, \\dots, p_Kp=p1,p2,...,pK。
2. 核心特性
通过上述公式,Softmax 输出的向量 ppp 具有以下三个极其重要的特性:
- 非负性 :因为自然对数底数 e≈2.718e \approx 2.718e≈2.718 是一个正数,正数的任何次幂都是正数,所以 pi>0p_i > 0pi>0。
- 总和为 1 :因为分母是所有分子之和,所以 ∑i=1Kpi=1\sum_{i=1}^{K} p_i = 1∑i=1Kpi=1。
- 放大差异(保持相对大小):由于指数函数是单调递增的凸函数,它会把最大的值"放大"得更多,把较小的值"压缩"得更小。这使得最终的概率分布更加"自信"(即胜出者的概率特别高,其他人的概率特别低)。
举个直观的例子:
假设输入向量 z=2,1,0.1z = 2, 1, 0.1z=2,1,0.1
- 计算指数:e2≈7.389e^2 \approx 7.389e2≈7.389, e1≈2.718e^1 \approx 2.718e1≈2.718, e0.1≈1.105e^{0.1} \approx 1.105e0.1≈1.105
- 求和:7.389+2.718+1.105=11.2127.389 + 2.718 + 1.105 = 11.2127.389+2.718+1.105=11.212
- 计算 Softmax:
- p1=7.389/11.212≈0.659p_1 = 7.389 / 11.212 \approx 0.659p1=7.389/11.212≈0.659 (65.9%)
- p2=2.718/11.212≈0.242p_2 = 2.718 / 11.212 \approx 0.242p2=2.718/11.212≈0.242 (24.2%)
- p3=1.105/11.212≈0.099p_3 = 1.105 / 11.212 \approx 0.099p3=1.105/11.212≈0.099 (9.9%)
可以看到,原本只是 2:1:0.1 的差距,经过 Softmax 后变成了 65.9% : 24.2% : 9.9% 的概率分布,最大值的优势被放大了。
3. 为什么需要 Softmax?(应用场景)
在多分类任务中(例如:识别一张图片是猫、狗还是老虎),神经网络的最后一层会输出 3 个分数。但这 3 个分数可能是负数,也可能加起来不等于 1,我们无法直接把它们当作"概率"来解释。
加入 Softmax 层后,这 3 个分数就被转化成了"模型认为这张图是猫的概率是 90%,是狗的概率是 8%,是老虎的概率是 2%"。这样我们就可以取概率最大的类别作为最终的预测结果(这叫 Argmax 操作)。
4. Softmax 与 Sigmoid 的区别
很多人会混淆 Softmax 和 Sigmoid,因为两者都可将输出压缩到 (0,1) 区间,但设计目的、使用场景和数学定义完全不同:


5. 实际工程中的"隐藏陷阱":数值稳定性
在写代码实现 Softmax 时,绝对不能直接套用上面的基础公式。
原因 :如果输入的 ziz_izi 值很大(比如 1000),e1000e^{1000}e1000 会直接导致计算机浮点数溢出,变成 inf(无穷大),导致程序崩溃。
解决方案(数值稳定版 Softmax) :
因为对分子分母同时乘以一个常数不改变分数的值,我们通常会减去输入向量中的最大值:
Softmax(zi)=ezi−max(z)∑j=1Kezj−max(z) \text{Softmax}(z_i) = \frac{e^{z_i - \max(z)}}{\sum_{j=1}^{K} e^{z_j - \max(z)}} Softmax(zi)=∑j=1Kezj−max(z)ezi−max(z)
减去最大值后,最大的 ezi−max(z)e^{z_i - \max(z)}ezi−max(z) 会被控制在 e0=1e^0 = 1e0=1 以内,其他的都会变成 e负数e^{\text{负数}}e负数,从而完美避免了数值溢出的问题。在 PyTorch (F.softmax) 和 TensorFlow (tf.nn.softmax) 中,底层都是用这种稳定方式实现的。
6. 最佳搭档:交叉熵损失函数
在训练神经网络时,Softmax 几乎从不单独使用,它总是和交叉熵损失 组成"黄金搭档":
- Softmax 负责:把网络输出的生硬数字变成概率分布。
- 交叉熵 负责:计算这个预测概率分布与真实标签的 One-Hot 分布之间的差异(损失),并指导网络反向传播更新权重。
在 PyTorch 中,甚至有一个专门把这两步合并在一起的函数叫 CrossEntropyLoss(它内部自动包含了 Softmax 操作,所以使用它时,网络的最后一层不需要再加 Softmax)。
扩展问题 :之前我们已经介绍了sigmoid、tanh、Relu等常见的激活函数,在实际应用中,神经网络一般怎样选择这些激活函数?


(图中笔记中提到回归任务选择线性激活,防止有人不理解什么是线性激活,这里解释一下:线性激活就是什么都不做,输入是什么,输出就是什么,公式是 f(x)=x))