Adam 算法(Adaptive Moment Estimation)是深度学习中目前最流行、最常用的优化算法之一,它结合了 AdaGrad 和 RMSProp 两种算法的优点,能够自适应地调整每个参数的学习率,从而在训练深度神经网络时表现出快速收敛和高稳定性的特点。
以下是对 Adam 算法的详细解析,包括其核心思想、数学原理、优势以及使用建议。
核心思想
Adam 算法的名字来源于 Adaptive Moment Estimation(自适应矩估计),它的核心思想是计算梯度的一阶矩估计(均值)和二阶矩估计(未中心化的方差),并利用这些统计量来动态调整每个参数的学习率。
- 一阶矩(Mean):类似于动量(Momentum),它利用了梯度的历史信息,帮助加速收敛并减少震荡。
- 二阶矩(Variance):类似于 RMSProp,它根据梯度的大小自适应地调整学习率,梯度大的参数学习率小,梯度小的参数学习率大。
数学原理
假设在第 $t$ 步,我们有一个待优化的参数 $theta_t$,其梯度为 $gt = nablatheta J(theta_t)$,Adam 算法通过以下步骤更新参数:
第一步:计算一阶矩估计(均值)
$$ m_t = beta1 m{t-1} + (1 – beta_1) g_t $$
- $m_t$ 是梯度的指数加权移动平均(一阶矩估计)。
- $beta_1$ 是超参数,通常设为

9
。
第二步:计算二阶矩估计(未中心化的方差)
$$ v_t = beta2 v{t-1} + (1 – beta_2) g_t^2 $$
- $v_t$ 是梯度平方的指数加权移动平均(二阶矩估计)。
- $beta_2$ 是超参数,通常设为 999。
第三步:偏差校正(Bias Correction)
由于 $m_0 = 0$ 和 $v_0 = 0$,在训练初期,$m_t$ 和 $v_t$ 会偏向于 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 $$
- $eta$ 是初始学习率(Learning Rate),通常设为 $0.001$。
- $epsilon$ 是一个很小的常数(如 $10^{-8}$),用于防止分母为零。
Adam 的优势
- 自适应学习率:每个参数都有独立的学习率,无需手动调参学习率(相比 SGD 更友好)。
- 收敛速度快:结合了动量和自适应学习率,通常在较少迭代次数内就能收敛。
- 对噪声梯度鲁棒:在稀疏梯度或噪声较大的数据集中表现良好。
- 默认参数效果好:即使使用默认超参数($beta_1=0.9, beta_2=0.999, epsilon=10^{-8}$),在许多任务上也能取得不错的结果。
Adam 的局限性

尽管 Adam 非常流行,但它并非完美:
- 泛化能力可能略逊于 SGD:一些研究表明,在图像分类等任务中,使用 SGD + Momentum 可能比 Adam 获得更好的最终泛化性能(尽管收敛更慢)。
- 可能陷入局部最优:由于自适应学习率,Adam 可能在某些复杂损失曲面上过早停止更新。
- 超参数敏感:虽然默认参数好用,但调整初始学习率 $eta$ 仍然很重要。
常见变体
为了解决 Adam 的一些问题,研究者提出了多种改进版本:
| 变体 | 特点 |
|---|---|
| AdamW | Weight Decay 解耦:将权重衰减(L2 正则化)从梯度更新中分离出来,通常比标准 Adam 泛化能力更强,是目前推荐的首选。 |
| RAdam | Rectified Adam:对 Adam 的偏差校正进行了改进,解决了训练初期学习率不稳定的问题。 |
| AdaGrad | 早期自适应算法,学习率单调递减,适合稀疏数据,但后期学习率可能过小导致停止更新。 |
| RMSProp | 仅使用二阶矩估计,没有动量项,适合非平稳目标函数。 |
代码示例(PyTorch)
在 PyTorch 中,使用 Adam 非常简单:

import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的模型
model = nn.Linear(10, 1)
# 定义损失函数
criterion = nn.MSELoss()
# 使用 Adam 优化器
# lr: 学习率, weight_decay: L2 正则化系数
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
# 训练循环
for epoch in range(100):
optimizer.zero_grad() # 清零梯度
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward() # 反向传播
optimizer.step() # 更新参数 使用建议
- 默认设置:如果没有特殊需求,直接使用
Adam(lr=0.001)即可。 - 优先使用 AdamW:在大多数现代深度学习任务中,推荐使用 AdamW,因为它能更好地处理正则化。
- 学习率调度:结合学习率衰减策略(如 Cosine Annealing)可以进一步提升性能。
- 对比实验:如果任务对泛化能力要求极高(如图像分类),可以尝试对比 SGD + Momentum 和 Adam/AdamW 的效果。
Adam 算法因其易用性、快速收敛和稳定性,成为深度学习中的“默认优化器”,虽然它在某些场景下可能不如 SGD 泛化能力强,但通过结合 AdamW 和学习率调度,它仍然是绝大多数深度学习任务的首选优化方案。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复