ARTICLE

数值下溢

数值下溢 (Numerical Underflow) 数值下溢(Numerical Underflow)是计算机浮点运算中的一种异常现象:当某个运算的结果的绝对值小于计算机所能表示的最小正数时,该结果被舍入为零,从而导致精度丧失。在统计学和机器学习中,数值下溢是似然函数求值和概率建模中极为常见的实际问题——大量小于1的概率值连乘后,结果可以轻易跌破双精度浮点

浏览 3 更新 2025-10-26

数值下溢 (Numerical Underflow)

数值下溢(Numerical Underflow)是计算机浮点运算中的一种异常现象:当某个运算的结果的绝对值小于计算机所能表示的最小正数时,该结果被舍入为零,从而导致精度丧失。在统计学和机器学习中,数值下溢是似然函数求值和概率建模中极为常见的实际问题——大量小于1的概率值连乘后,结果可以轻易跌破双精度浮点数的表示下限(约 10308 10^{-308} ),直接归零。

IEEE 754 浮点数与表示极限

现代计算机遵循 IEEE 754 标准来表示实数。双精度浮点数(64 位)由 1 位符号位、11 位指数(偏移量 1023)和 52 位尾数构成,能够表示的最小正规格化数约为:

minnormal=210222.225×10308\min_{\text{normal}} = 2^{-1022} \approx 2.225 \times 10^{-308}

小于此值的非零数只能以非规格化数(subnormal / denormal)的形式存在,最小正非规格化数约为 210744.94×10324 2^{-1074} \approx 4.94 \times 10^{-324} 。一旦运算结果低于这一阈值,硬件便无法表示,发生硬下溢(hard underflow),结果被置为零。这在单精度(32 位)下更早发生——最小正规格化数仅约 1.175×1038 1.175 \times 10^{-38}

下溢在统计计算中的危害

最大似然估计(MLE)中,给定独立同分布样本 x1,,xn x_1, \ldots, x_n ,似然函数为:

L(θ)=i=1nP(xiθ)L(\theta) = \prod_{i=1}^n P(x_i \mid \theta)

每个 P(xiθ)(0,1] P(x_i \mid \theta) \in (0, 1] 。当 n n 达到数百或数千时,乘积可能迅速暴跌至 10500 10^{-500} 甚至更小。此时计算机将 L(θ) L(\theta) 记为零,优化器无法区分不同 θ \theta 对应的似然值,梯度信号消失,整个估计过程崩溃。类似的问题也出现在隐马尔可夫模型的前向算法、贝叶斯推断的边际似然计算以及朴素贝叶斯分类器的概率乘积中。

标准对策:对数变换

最经典且有效的防御手段是对数变换。由于对数函数 ln \ln 单调递增,最大化 L(θ) L(\theta) 等价于最大化对数似然函数

(θ)=lnL(θ)=i=1nlnP(xiθ)\ell(\theta) = \ln L(\theta) = \sum_{i=1}^n \ln P(x_i \mid \theta)

乘积变为和,每个 lnP(xiθ) \ln P(x_i \mid \theta) 的数量级通常在 100 -10^0 102 -10^2 之间,求和后远在上限之内。在需要还原概率时,使用 exp((θ)) \exp(\ell(\theta)) 即可。绝大多数 MLE 标准软件(如 R 的 \verb|optim|、Python 的 \verb|scipy.optimize| 和 Stan)都默认使用对数尺度。

对于需要加法的归一化操作(如计算后验概率的归一化常数),对数-和-指数技巧(log-sum-exp trick)可避免指数溢出:

logiexi=M+logiexiM,M=maxixi\log \sum_i e^{x_i} = M + \log \sum_i e^{x_i - M}, \quad M = \max_i x_i

减去最大值 M M 保证指数项 exiM1 e^{x_i - M} \leq 1 ,避免上溢的同时防止下溢。该技巧在softmax函数、隐马尔可夫模型前向-后向算法词性标注中极其常用。

其他缓解策略

缩放与递推。在卡尔曼滤波和 HMM 的前向算法中,每步递推后对概率向量进行重新归一化,令其分量之和为 1。缩放因子(对数形式)单独累积,最终可以从对数缩放因子中恢复对数似然。

对数概率空间运算。与其将概率存为 p[0,1] p \in [0,1] ,不如全程维护 logp \log p ,并定义对数域上的加法与乘法:

log(p×q)=logp+logq\log(p \times q) = \log p + \log q
log(p+q)=logp+log(1+elogqlogp),pq\log(p + q) = \log p + \log(1 + e^{\log q - \log p}), \quad p \geq q

这套"对数半环"(log-semiring)在有限状态机的加权计算、语音识别的解码器和生物序列分析中有系统应用。

使用更高精度。在关键节点切换到 \verb|long double|(80 位,x86 扩展精度)或任意精度库(如 GMP、MPFR)可临时扩展表示范围,但这会显著降低计算速度,通常仅用于验证而非生产环境。

下溢与上溢、数值稳定性的统一视角

数值下溢并非孤立问题。它的"镜像"是数值上溢(numerical overflow)——运算结果超出可表示的最大正数(双精度约 1.798×10308 1.798 \times 10^{308} ),被记为 + +\infty 。下溢与上溢常同时出现:指数函数的输入稍大即导致上溢,稍小即下溢为零。两者的共同根源是浮点数的有限范围。有效的数值策略必须兼顾两端,例如:

  • Sigmoid 稳定版σ(x)=11+ex \sigma(x) = \frac{1}{1+e^{-x}} ,当 x x \to -\infty 时直接返回 0(而非计算 ex+ e^{-x} \to +\infty ),当 x+ x \to +\infty 时直接返回 1。
  • Softmax 稳定版softmax(xi)=exiMjexjM \operatorname{softmax}(x_i) = \frac{e^{x_i - M}}{\sum_j e^{x_j - M}} ,其中 M=maxkxk M = \max_k x_k ,一次减法同时防御上溢和下溢。
  • 归一化顺序v2=vi2 \| \mathbf{v} \|_2 = \sqrt{\sum v_i^2} 中,若某些 vi |v_i| 极大或极小,先除以 M=maxivi M = \max_i |v_i| 再做平方和可防双溢。

数值下溢是一个表面简单却反复出现的工程陷阱。它的解决方案——对数变换、log-sum-exp、逐步重标定——如今已成为计算统计学和数值线性代数的基础技术,任何涉及概率建模的算法实现都应将其纳入设计考量。