Softmax 函数简介及其Python实现
Softmax 函数简介
在数学,尤其是概率论和相关领域中,Softmax函数,或称归一化指数函数,是Logistic
函数的一种推广。它能将一个含任意实数的K维向量
z z z “压缩”到另一个K维实向量 σ \sigma σ 中,使得每一个元素的范围都在 ( 0 , 1 ) (0,1) (0,1)之间,并且所有元素的和为1(也可视为一个 (k-1)维的hyperplane或subspace)。该函数的形式通常按下面的式子给出:
σ ( z ) j = e z j ∑ k = 1 K e z k j = 1 , 2 , … , K \sigma (\mathbf {z} )_{j} = \frac{e^{z_{j}}}{\sum_{k=1}^{K}e^{z_{k}}}\qquad j = 1, 2, \ldots , K σ(z)j=∑k=1Kezkezjj=1,2,…,K
其中, z z z是输入向量, K K K是类别数。公式通过指数运算放大数值差异,再归一化得到概率。
Softmax函数实际上是有限项离散概率分布的梯度对数归一化。因此,Softmax函数在包括多项逻辑回归,多项线性判别分析,朴素贝叶斯分类器和人工神经网络等的多种基于概率的多分类问题方法中都有着广泛应用。 特别地,在多项逻辑回归和线性判别分析中,函数的输入是从K个不同的线性函数得到的结果,而样本向量 x x x 属于第 j j j 个分类的概率为:
P ( y = j ∣ x ) = e x T w j ∑ k = 1 K e x T w k \displaystyle P(y=j|\mathbf {x} )={\frac {e^{\mathbf {x} ^{\mathsf {T}}\mathbf {w} _{j}}}{\sum _{k=1}^{K}e^{\mathbf {x} ^{\mathsf {T}}\mathbf {w} _{k}}}} P(y=j∣x)=∑k=1KexTwkexTwj
这可以被视作K个线性函数
x ↦ x T w 1 , … , x ↦ x T w K \displaystyle \mathbf {x} \mapsto \mathbf {x} ^{\mathsf {T}}\mathbf {w} _{1},\ldots ,\mathbf {x} \mapsto \mathbf {x} ^{\mathsf {T}}\mathbf {w} _{K} x↦xTw1,…,x↦xTwK Softmax函数的复合:
x T w x w \mathbf {x} ^{\mathsf {T}}\mathbf {w} \displaystyle \mathbf {x} \displaystyle \mathbf {w} xTwxw
实际实现的时候,为了防止溢出,会先把每个元素减去原先的最大值 m \displaystyle m m。
σ ( z ) i = e x i ∑ j e x j = e − m e − m e x i ∑ j e x j = e x i − m ∑ j e x j − m \displaystyle \sigma (\mathbf {z} )_{i}={\frac {e^{x_{i}}}{\sum _{j}e^{x_{j}}}}={\frac {e^{-m}}{e^{-m}}}{\frac {e^{x_{i}}}{\sum _{j}e^{x_{j}}}}={\frac {e^{x_{i}-m}}{\sum _{j}e^{x_{j}-m}}} σ(z)i=∑jexjexi=e−me−m∑jexjexi=∑jexj−mexi−m
一、Softmax函数的作用
Softmax函数主要用于多分类任务,将神经网络的原始输出转换为概率分布,确保每个类别的概率在[0,1]范围内且总和为1。例如,在图像分类中,输出层的Softmax可以将得分映射为各类别的概率,如识别猫、狗、鸟的模型输出可能为[0.1, 0.7, 0.2]。
二、Python实现代码与优化
1. 基础实现(存在数值溢出风险)
import numpy as np
def softmax(x):e_x = np.exp(x)return e_x / e_x.sum(axis=0)
问题:当输入值较大时(如1000),指数运算会导致溢出(结果为NaN
)。
2. 优化实现(数值稳定性处理)
通过减去输入向量中的最大值,避免指数运算溢出:
def softmax(x):e_x = np.exp(x - np.max(x)) # 防止溢出return e_x / e_x.sum(axis=0)
示例:
输入[1000, 1010, 1020]
时,优化后输出为[2.06e-09, 4.54e-05, 9.99e-01]
,避免了NaN
。
三、实现细节解析
-
数值稳定性
• 减去最大值后,指数运算的最大值为( e^0 = 1 ),大幅降低溢出风险。
• 适用于任意维度的输入(如单样本向量或批量数据矩阵)。 -
轴(axis)参数
• 若输入为二维矩阵(如批量数据),需指定axis=1
对每行独立计算:def softmax(x):e_x = np.exp(x - np.max(x, axis=1, keepdims=True))return e_x / e_x.sum(axis=1, keepdims=True)
四、程序应用示例
以下代码是Softmax函数的实现与应用参考。
import numpy as npdef softmax(x, axis=0, keepdims=True):"""Compute softmax values for each sets of scores in x."""dims = len(np.shape(x))if axis == 0 and dims > 1:axis = dims - 1e_x = np.exp(x - np.max(x, axis, keepdims=keepdims))return e_x / e_x.sum(axis=axis, keepdims=keepdims)
- 输入为一维数组
arr = [1, 2, 1, 2, 1, 1, 3]
result = softmax(arr)
print(result)
- 输入为二维矩阵
x = [[1000, 1010, 1020], [1030, 1040, 1050]]
y = softmax(x, axis=1)
print(y)
- 三维数组使用示例
cube = [[[1000, 1010, 1020], [1050, 1040, 1050]], [[1060, 1070, 1080], [1090, 1100, 1110]]]
cube_softmax = softmax(cube)
print(cube_softmax)
五、与其他激活函数的对比
特性 | Softmax | Sigmoid | ReLU |
---|---|---|---|
适用任务 | 多分类(输出概率和=1) | 二分类/回归(输出∈(0,1)) | 隐藏层(缓解梯度消失) |
输出范围 | [0,1],和为1 | (0,1) | [0, +∞) |
梯度问题 | 可能饱和(概率接近1) | 易饱和(梯度消失) | 缓解梯度消失 |
典型应用 | 输出层(分类) | 输出层(二分类) | 隐藏层(通用) |
关联性:Sigmoid可视为二分类时的Softmax特例。
六、注意事项
- 输入数据类型
• 输入需为浮点型(float32
/float64
),避免整数计算误差。 - 极端值处理
• 若输入中存在极大负值(如-1e6),可能导致概率全为0,需结合损失函数设计(如添加极小值ε避免除零)。 - 与损失函数结合
• 多分类任务中,Softmax通常与交叉熵损失联合使用,避免单独计算时的数值不稳定。