⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

2.4 数值方法与训练检查 ​

核心问题: 数学公式正确时,计算为什么仍可能失败?

在线 Notebook

对应的交互式版本可在 Google Colab 打开,统一使用方式见 第0章说明。


浮点数不是实数 ​

计算机用有限位表示数值,因此会出现舍入、上溢和下溢。两个常见例子是:

  • 很大的数与很小的数相加,小数可能被舍弃;
  • 直接计算 exp⁡(x) 或 log⁡p,可能产生 inf 或 -inf。

Softmax 应使用减去最大值的稳定形式:

softmax(xi)=exp⁡(xi−maxjxj)∑kexp⁡(xk−maxjxj)

这不会改变结果,因为分子和分母乘了相同常数,但能降低指数上溢风险。

条件数 ​

条件数描述输入小变化可能被问题本身放大的程度。对可逆矩阵 A:

κ(A)=‖A‖‖A−1‖

条件数大时,即使算法实现正确,测量噪声或舍入误差也可能导致解明显变化。特征缩放、正则化和重新参数化可改善部分问题,但不能消除数据本身的不可辨识性。

数值梯度检查 ​

中心差分近似为:

∂L∂θi≈L(θi+h)−L(θi−h)2h

它可用于检查反向传播实现,但不适合训练:每个参数都要重复前向计算,而且 h 太大会有截断误差,太小会有舍入误差。

比较解析梯度 g 与数值梯度 g^ 时,可使用相对误差:

‖g−g^‖max(1,‖g‖,‖g^‖)

梯度检查应关闭 dropout 等随机操作,并使用较高精度和小规模输入。

深层网络中的数值问题 ​

链式法则会连续相乘 Jacobian。其尺度长期小于或大于 1 时,可能出现梯度消失或爆炸。常见控制手段包括:

  • 合理初始化和输入标准化;
  • 残差连接与归一化;
  • 梯度范数监控和裁剪;
  • 稳定的损失实现;
  • 混合精度下的损失缩放或更合适的数据类型。

不同硬件对 FP16、BF16 和 FP32 的支持不同。混合精度的速度、显存和误差收益需要实际测量,不能固定写成某个倍数。

排查顺序 ​

现象首先检查
损失为 NaN/Inf首个非有限张量、学习率、除零、指数与对数
损失不下降数据与标签、梯度是否存在、参数是否更新
梯度很大损失尺度、异常样本、归一化与梯度范数
结果不可复现随机种子、数据顺序、非确定算子和依赖版本

应定位“第一个出现异常的步骤”,而不是在训练结束后只看最终损失。


关联实验 ​

bash
python code/ch02_optimization/lms_vs_adam.py
python code/ch02_optimization/linear_logistic_regression.py

改变学习率或输入尺度,观察损失是否发散,并打印梯度范数与参数范围。实验结论只适用于当前精度、硬件和实现。


本节小结 ​

  • 浮点误差、问题条件数和算法实现是三个不同的误差来源。
  • 稳定 Softmax、梯度检查和非有限值监控能提前暴露实现问题。
  • 混合精度与梯度裁剪需要通过指标和日志验证,不能作为固定保证。

下一节: 2.5 线性回归与逻辑回归

本教程采用 CC BY-NC-SA 4.0 许可协议