文章

Softmax 函数

Softmax 函数

Softmax 将包含 $k$ 个值的输入 $Z = (z_1, z_2, \cdots, z_K)$ 归一化为概率分布 $P = (p_1, p_2, \cdots, p_K)$,常用于多分类。

\[p_i = \cfrac{e ^ {z_i}}{\sum^{K}_{j = 1}e^{z_j}}, 1 \le i \le K\]

Softmax 一般应用于模型最后的输出,作为激活函数且与交叉熵损失函数一起使用。Softmax 函数具有以下性质:

  1. Softmax 输出的值为概率,满足 $0 < p_i < 1$
  2. Softmax 输出概率的和为 $1$,即 $\sum^{K}_{i = 1} p_i = 1$
  3. Softmax 的输出保持与输入一致的相对大小,即如果 $z_i < z_j$,则 $p_i < p_j$
  4. 对于常数 $c$,有 $Softmax(Z+c) = Softmax(Z)$

反向传播

用 $L$ 表示交叉熵损失,$Z = (z_1, z_2, \cdots, z_K)$ 表示 Softmax 的输入,$P = (p_1, p_2, \cdots, p_K)$ 表示 Softmax 的输出,$Y = (y_1, y_2, \cdots, y_K)$ 表示多分类标签,则 Softmax 的反向传播可以表示为:

\[\cfrac{\mathrm{d}L}{\mathrm{d}Z} = \cfrac{\mathrm{d}L}{\mathrm{d}P} · \cfrac{\mathrm{d}P}{\mathrm{d}Z}\]

对于 $\cfrac{\mathrm{d}L}{\mathrm{d}P}$:

\[J_1 = \cfrac{\mathrm{d}L}{\mathrm{d}P} = \begin{bmatrix} \cfrac{y_1}{p_1} & 0 & \cdots & 0 \\ 0 & \cfrac{y_2}{p_2} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \cfrac{y_K}{p_K} \end{bmatrix}\]

对于 $\cfrac{\mathrm{d}P}{\mathrm{d}Z}$:

\[J_2 = \cfrac{\mathrm{d}P}{\mathrm{d}Z} = \begin{bmatrix} \cfrac{\mathrm d p_1}{\mathrm d z_1} & \cfrac{\mathrm d p_1}{\mathrm d z_2} & \cdots & \cfrac{\mathrm d p_1}{\mathrm d z_k} \\ \cfrac{\mathrm d p_2}{\mathrm d z_1} & \cfrac{\mathrm d p_2}{\mathrm d z_2} & \cdots & \cfrac{\mathrm d p_2}{\mathrm d z_k} \\ \vdots & \vdots & \ddots & \vdots \\ \cfrac{\mathrm d p_k}{\mathrm d z_1} & \cfrac{\mathrm d p_k}{\mathrm d z_2} & \cdots & \cfrac{\mathrm d p_k}{\mathrm d z_k} \\ \end{bmatrix}\]

对于 $J_2$ 对角线上的元素:

\[\begin{split} \cfrac{\mathrm{d} p_i}{\mathrm{d} z_i} &= \cfrac{\mathrm{d}\frac{e^{z_i}}{\sum^{k}_{j = 1}e^{z_j}}}{\mathrm{d}z_i} \\ &= \cfrac{e^{z_i}\sum^{k}_{j=1}e^{z_j} - e^{z_i}e^{z_i}}{(\sum^{k}_{j=1}e^{z_j})^2} \\ &= \cfrac{e^{z_i}}{\sum^{k}_{j=1}e^{z_j}} · \cfrac{\sum^{k}_{j=1}e^{z_j} - e^{z_i}}{\sum^{k}_{j=1}e^{z_j}} \\ &= p_i · (1 - p_i) \end{split}\]

对于 $J_2$ 对角线以外的元素:

\[\begin{split} \cfrac{\mathrm{d} p_i}{\mathrm{d} z_j} &= \cfrac{\mathrm{d}\frac{e^{z_i}}{\sum^{k}_{j = 1}e^{z_j}}}{\mathrm{d}z_j} \\ &= \cfrac{-e^{z_i}e^{z_j}}{(\sum^{k}_{j=1}e^{z_j})^2} \\ &= -\cfrac{e^{z_i}}{\sum^{k}_{j=1}e^{z_j}}·\cfrac{e^{z_j}}{\sum^{k}_{j=1}e^{z_j}} \\ &= -p_i · p_j \end{split}\]

进而矩阵 $J_2$ 可以表示为:

\[J_2 = -P^TP + diag(P)\]

数值稳定性

Softmax 计算中使用了指数运算,当部分 $z_i$ 值过大时,容易造成溢出。在 Softmax 中对最大值非常关注,因此在计算 Softmax 时要防止溢出。具体而言,首先计算 $Z = (z_1, z_2, \cdots, z_K)$ 中的最大值 $z_{max}$:

\[z_{max} = \max(z_i), 1 \le i \le K\]

然后根据 Softmax 函数的第四条性质,将计算转化为:

\[Softmax(Z) = Softmax(Z - z_{max})\]

PyTorch 等深度学习框架中均使用了数值稳定版本的 Softmax 函数。

平稳的 Softmax

Softmax 中的指数运算也容易输出非常尖锐的概率分布,即对于 $Z = (1, 2, 8)$ 输入而言,产生的输出为 $P = (0.001, 0.002, 0.997)$,输入中的最大值 ($8$)几乎贡献了所有的概率($0.997$)。

在不改变输出相对大小的前提下,为了缓解 Softmax 输出尖锐的问题,引入温度参数 $\tau, \tau \in (0, +\infty)$,有:

\[Softmax_{\tau}(Z) = Softmax(\cfrac{Z}{\tau})\]

关于常量 $\tau$ 的选取:

  1. 当 $\tau > 1$ 时,将会得到相对平稳的分布;当 $\tau \rightarrow +\infty$ 时,成为均匀分布
  2. 当 $0 < \tau < 1$ 时,将会得到更加尖锐的分布

这也被称为带温度的 Softmax(Softmax with temperature),被用于注意力机制、模型蒸馏等算法中。

本文由作者按照 CC BY 4.0 进行授权