在计算机中执行数学运算需要使用有限的比特位来表达实数,这会引入近似误差。近似误差可以在多步数值运算中传递、积累,从而导致理论上成功的算法失败。因此数值算法设计时要考虑将累计误差最小化。
溢出
- 一种严重的误差是下溢出
underflow:当接近零的数字四舍五入为零时,发生下溢出。
许多函数在参数为零和参数为一个非常小的正数时,行为是不同的。如:对数函数要求自变量大于零,除法中要求除数非零。
- 一种严重的误差是上溢出
overflow:当数值非常大,超过了计算机的表示范围时,发生上溢出。
softmax 溢出
- 设 x = {({x_1},{x_2}, \cdots ,{x_n})^T},则softmax函数定义为:
\operatorname{softmax}(\overrightarrow{\mathbf{x}})=\left(\frac{\exp \left(x_{1}\right)}{\sum_{j=1}^{n} \exp \left(x_{j}\right)}, \frac{\exp \left(x_{2}\right)}{\sum_{j=1}^{n} \exp \left(x_{j}\right)}, \cdots, \frac{\exp \left(x_{n}\right)}{\sum_{j=1}^{n} \exp \left(x_{j}\right)}\right)^{T}- 当所有的 x_i 都等于常数 c 时,softmax函数的每个分量的理论值都为\frac { 1 } { n } 考虑 c 是一个非常大的负数(比如趋近负无穷), 此时 \exp © 下溢出。此时 \frac{\exp ©}{\sum_{j=1}^{n} \exp ©} 分母为零, 结果 未定义。 Q考虑 c 是一个非常大的正数(比如趋近正无穷),此时 \exp © 上溢出。 \frac{\exp ©}{\sum_{j=1}^{n} \exp ©} 的结果未定义。
解决方案
- 为了解决 softmax 函数的数值稳定性问题, 令 z=\overrightarrow{x}-\max_{i}x_{i}, 则有 {softmax}(\overrightarrow{\mathbf{z}}) 的第 i 个分量为:
- 当 \overrightarrow{\mathbf{x}} 的分量较小时, \overrightarrow{\mathbf{z}} 的分量至少有一个为零,从而导致 \operatorname{softmax}(\overrightarrow{\mathbf{z}})_{i} 的分母至少有一项为 1 , 从而解 决了下溢出的问题。
- 当 \overrightarrow{\mathbf{x}} 的分量较大时, \operatorname{softmax}(\overrightarrow{\mathbf{z}})_{i} 相当于分子分母同时除以一个非常大的数 \exp \left(\max {i} x{i}\right), 从而解决 了上溢出。
log softmax 溢出风险
- 当 \overrightarrow{\mathbf{x}} 的分量 x_{i} 较小时, \operatorname{softmax}(\overrightarrow{\mathbf{x}})_{i} 的计算结果可能为 0 。此时 \log \operatorname{softmax}(\overrightarrow{\mathbf{x}}) 趋向于负无穷,因此存在 数值稳定性问题。
- 通常需要设计专门的函数来计算 \log softmax,而不是将 \operatorname{softmax} 的结果传递给 \log 函数。
- \log \operatorname{softmax}(\cdot) 函数应用非常广泛。通常将 \operatorname{softmax} 函数的输出作为模型的输出。由于一般使用样本的 交叉商作为目标函数,因此需要用到 \operatorname{softmax} 输出的对数。
参考资料