共计 2204 个字符,预计需要花费 6 分钟才能阅读完成。
梯度下降算法演进脉络
在深度学习训练中,优化算法的选择直接影响模型的收敛速度和最终性能。传统的随机梯度下降(SGD)虽然简单,但在非凸优化问题中表现出明显的局限性:

- 学习率敏感:固定学习率难以适应不同参数的特性,容易导致震荡或收敛缓慢
- 梯度方向单一:仅依赖当前 batch 的梯度信息,缺乏历史梯度信息的利用
- 鞍点困扰:在高维非凸空间中容易陷入鞍点而无法逃脱
自适应优化器的出现解决了这些问题。从 Momentum、AdaGrad 到 RMSProp,最终 Adam 结合了动量估计和自适应学习率的优势,成为当前最流行的优化算法。
Adam 的数学本质
Adam 的核心思想是 动量估计 + 自适应学习率,其数学推导分为以下步骤:
-
动量估计(一阶矩估计):
$$m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t$$
其中 $g_t$ 是当前梯度,$\beta_1$ 通常取 0.9 -
自适应学习率(二阶矩估计):
$$v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2$$
$\beta_2$ 通常取 0.999,用于估计梯度的方差 -
偏差校正:
由于初始时刻 $m_0=v_0=0$,需要进行偏差校正:
$$\hat{m}_t = \frac{m_t}{1-\beta_1^t}$$
$$\hat{v}_t = \frac{v_t}{1-\beta_2^t}$$ -
参数更新:
$$\theta_{t+1} = \theta_t – \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon}\hat{m}_t$$
$\epsilon$ 是为数值稳定性添加的小常数(通常 1e-8)
关键理解:偏差校正确保了在训练初期(t 较小时)估计值不会偏向 0,这对稳定训练至关重要。
工程实现中的数值稳定性处理
以下是带完整注释的 Python 实现(使用 NumPy):
import numpy as np
from typing import Tuple, Callable
def update_parameters(params: np.ndarray, grads: np.ndarray,
m: np.ndarray, v: np.ndarray, t: int,
lr: float = 0.001, beta1: float = 0.9,
beta2: float = 0.999, eps: float = 1e-8,
grad_clip: float = 1.0) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Adam 参数更新实现
参数:
params: 当前参数值
grads: 当前梯度
m: 一阶矩估计
v: 二阶矩估计
t: 时间步(用于偏差校正)
lr: 学习率
beta1/beta2: 衰减率
eps: 数值稳定常数
grad_clip: 梯度裁剪阈值
返回:
更新后的参数、m、v
"""
# 梯度裁剪
grads = np.clip(grads, -grad_clip, grad_clip)
# 更新一阶矩估计
m = beta1 * m + (1 - beta1) * grads
# 更新二阶矩估计
v = beta2 * v + (1 - beta2) * (grads ** 2)
# 计算偏差校正后的估计
m_hat = m / (1 - beta1 ** t)
v_hat = v / (1 - beta2 ** t)
# 参数更新
params -= lr * m_hat / (np.sqrt(v_hat) + eps)
return params, m, v
实现要点:
- 使用类型注解提高代码可读性
- 内置梯度裁剪防止梯度爆炸
- 严格按照数学公式实现偏差校正
- 添加微小常数 eps 避免除以零错误
实验对比
在 MNIST 数据集上对比 Adam 与 RMSprop(两层全连接网络,hidden_size=128):
- 超参数设置:
- 学习率:Adam 0.001,RMSprop 0.01
- batch_size=64,epochs=10
- Adam: β1=0.9, β2=0.999
- RMSprop: ρ=0.9
实验结果:
- Adam 收敛速度更快,在 3 个 epoch 后达到 90% 准确率
- RMSprop 后期出现震荡,Adam 曲线更平滑
- Adam 对初始学习率的选择更鲁棒
生产建议
1. 学习率 warm-up 策略:
- 初始阶段使用较小学习率(如初始值的 1 /10)
- 逐步增加到设定值(通常 5 -10 个 epoch)
- 尤其对 Transformer 类模型效果显著
2. 批量大小与 β 参数的关系:
- 大 batch 训练时建议调大 β2(如 0.999→0.9999)
- 小 batch 时 β1 可适当减小(如 0.9→0.8)
- 经验公式:$\beta_2^{batch_size/256}$
3. 权重衰减注意事项:
- 不要与 AdamW 混淆(后者解耦了权重衰减)
- 推荐值:0.01~0.001
- 与学习率共同调整:$lr \times wd$ 应保持同一量级
典型应用场景与限制
适用场景:
- 绝大多数 CNN/RNN 架构
- 小样本学习(few-shot learning)
- 对抗训练(GANs)
局限性:
- 内存占用较高(需保存 m 和 v)
- 极端稀疏数据可能表现不佳
- 理论收敛性证明不如 SGD 严格
延伸思考题
如何改造 Adam 适应联邦学习场景?
- 客户端本地更新时保持各自的 m / v 状态
- 服务器聚合时采用加权平均(根据数据量)
- 添加差分隐私噪声时需调整学习率
- 跨设备异质性需要考虑 β 参数的自适应
总结:Adam 通过巧妙结合动量与自适应学习率,在实践中表现出色。理解其数学原理有助于针对特定任务进行调整,而正确的工程实现能避免许多训练陷阱。建议读者在自己的项目中使用本文提供的实现作为 baseline,再根据具体需求优化超参数。
