● 专题 · Deep Dive

softmax 的数值稳定技巧:减去最大值

为什么所有 softmax 实现都要先减去最大 logit?背后是浮点数的限制和一个数学上的小巧妙。

问题:浮点数会溢出

IEEE 754 双精度浮点数最大能表示约 1.8 × 10^308。看似很大,但 exp(710) 溢出成 inf 了:

🔒 登录后可在浏览器里直接运行 Python 代码(基于 Pyodide)。

解法:先减最大值

把每个 logit 都减去最大值 z_max

exp(zi)jexp(zj)=exp(zizmax)jexp(zjzmax)\frac{\exp(z_i)}{\sum_j \exp(z_j)} = \frac{\exp(z_i - z_{\max})}{\sum_j \exp(z_j - z_{\max})}

分子分母同时乘以 exp(-z_max),两边相等—— 但右边所有指数都 ≤ 0exp 结果都在 (0, 1],绝不会溢出。

用同一个案例对比

🔒 登录后可在浏览器里直接运行 Python 代码(基于 Pyodide)。

其他类似技巧:log-sum-exp、log_softmax 直接合并这两步避免中间溢出。深度学习框架的 cross_entropy 和 softmax 实现底层都用了这套数学。