🎯 优化算法全解析:Adam、RMSProp、Adagrad、Momentum
🚀 1️⃣ Momentum(动量算法)
🧠 思想
在梯度下降中加入"惯性"思想,让参数更新时考虑过去的方向,从而加快收敛、减少震荡。
📘 公式
vt=βvt−1+(1−β)∇θJ(θt)v_t = \beta v_{t-1} + (1 - \beta) \nabla_\theta J(\theta_t)vt=βvt−1+(1−β)∇θJ(θt)
θt+1=θt−ηvt\theta_{t+1} = \theta_t - \eta v_tθt+1=θt−ηvt
| 符号 | 含义 |
|---|---|
| vtv_tvt | 动量项(梯度的指数加权平均) |
| β\betaβ | 动量系数(通常取 0.9) |
| η\etaη | 学习率 |
✅ 优点
- 加快收敛速度,尤其在沟壑型损失面中(如深层网络)。
- 抑制梯度震荡,使曲线更平滑。
❌ 缺点
- 学习率固定,不会自适应调整。
- 对不同维度参数的学习率相同。
💻 示例代码
python
import torch
# 初始化权重参数
w = torch.tensor([1.0], requires_grad=True,
dtype=torch.float32)
# 实例化优化器
optimizer = torch.optim.SGD([w], lr=0.01, momentum=0.9)
# 迭代更新
num_iterations = 3
for i in range(num_iterations):
# 计算目标函数
y = (w ** 2) / 2.0
# 清空梯度
optimizer.zero_grad()
# 计算梯度
y.backward()
# 更新参数
optimizer.step()
# 输出结果
print(f'第{i + 1}次: 梯度w.grad: {w.grad.item()}, 更新后的权重: {w.item()}')
💼 典型应用
- 深度神经网络(DNN) 早期经典模型(如LeNet、AlexNet)中常用。
- 与SGD结合使用(称为 SGD with Momentum)。
⚙️ 2️⃣ Adagrad(Adaptive Gradient Algorithm)
🧠 思想
对每个参数使用不同的自适应学习率;更新次数多的参数学习率自动减小,更新次数少的参数学习率较大。
📘 公式
Gt=Gt−1+(∇θJ(θt))2G_t = G_{t-1} + (\nabla_\theta J(\theta_t))^2Gt=Gt−1+(∇θJ(θt))2
θt+1=θt−ηGt+ϵ∇θJ(θt)\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \nabla_\theta J(\theta_t)θt+1=θt−Gt+ϵ η∇θJ(θt)
| 符号 | 含义 |
|---|---|
| GtG_tGt | 梯度平方的累积和 |
| ϵ\epsilonϵ | 防止除零的小常数(如10−810^{-8}10−8) |
✅ 优点
- 自动调整每个参数的学习率。
- 对稀疏特征(如NLP中的embedding)表现出色。
❌ 缺点
- 学习率单调递减 →\to→ 最终可能"太小",停止学习。
- 不能很好地适应长期训练。
💼 典型应用
- 自然语言处理(NLP)、文本分类、词嵌入(Word2Vec)训练初期常用。
⚡ 3️⃣ RMSProp(Root Mean Square Propagation)
🧠 思想
是 Adagrad 的改进版,使用滑动平均代替累积,使学习率不会无限下降。
📘 公式
E[g2]t=βE[g2]t−1+(1−β)(∇θJ(θt))2E[g^2]t = \beta E[g^2]{t-1} + (1 - \beta)(\nabla_\theta J(\theta_t))^2E[g2]t=βE[g2]t−1+(1−β)(∇θJ(θt))2
θt+1=θt−ηE[g2]t+ϵ∇θJ(θt)\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[g^2]t + \epsilon}} \nabla\theta J(\theta_t)θt+1=θt−E[g2]t+ϵ η∇θJ(θt)
| 符号 | 含义 |
|---|---|
| E[g2]tE[g^2]_tE[g2]t | 梯度平方的指数加权平均 |
| β\betaβ | 平滑系数(通常 0.90.90.9) |
✅ 优点
- 保持自适应学习率。
- 避免 Adagrad 学习率衰减过快。
- 对非平稳目标函数(如RNN训练)效果很好。
❌ 缺点
- 仍需手动调整学习率 η\etaη。
- 不考虑梯度的"方向性"(只有大小调整)。
💼 典型应用
- 循环神经网络(RNN、LSTM)
- 在线学习(online learning)
🧩 4️⃣ Adam(Adaptive Moment Estimation)
🧠 思想
融合了 Momentum + RMSProp 的优点:既有"动量"平滑方向,又有"自适应学习率"。
🧩 4.1 Adam 优化算法完整更新流程
Adam = Momentum(动量) + RMSProp(自适应学习率)
🚩 Step 0:初始化
初始化参数:
m0=0,v0=0,t=0m_0 = 0, \quad v_0 = 0, \quad t = 0m0=0,v0=0,t=0
常用超参数取值:
| 参数 | 含义 | 默认值 |
|---|---|---|
| η\etaη | 学习率 | 0.0010.0010.001 |
| β1\beta_1β1 | 一阶矩衰减系数 | 0.90.90.9 |
| β2\beta_2β2 | 二阶矩衰减系数 | 0.9990.9990.999 |
| ϵ\epsilonϵ | 防止除零的平滑常数 | 10−810^{-8}10−8 |
⚙️ Step 1:计算梯度
对当前参数 θt\theta_tθt,计算目标函数 J(θt)J(\theta_t)J(θt) 的梯度:
gt=∇θJ(θt)g_t = \nabla_\theta J(\theta_t)gt=∇θJ(θt)
⚙️ Step 2:更新一阶矩(动量)
计算梯度的指数加权平均(即"动量"):
mt=β1mt−1+(1−β1)gtm_t = \beta_1 m_{t-1} + (1 - \beta_1) g_tmt=β1mt−1+(1−β1)gt
⚙️ Step 3:更新二阶矩(方差)
计算梯度平方的指数加权平均(类似于 RMSProp 的思路):
vt=β2vt−1+(1−β2)gt2v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2vt=β2vt−1+(1−β2)gt2
⚙️ Step 4:偏差修正(Bias Correction)
由于在初期 (m0=v0=0)(m_0 = v_0 = 0)(m0=v0=0),它们会偏向于 000,因此需进行无偏估计修正:
mt^=mt1−β1t\hat{m_t} = \frac{m_t}{1 - \beta_1^t}mt^=1−β1tmt
vt^=vt1−β2t\hat{v_t} = \frac{v_t}{1 - \beta_2^t}vt^=1−β2tvt
⚙️ Step 5:更新参数(最终公式)
利用修正后的动量与方差,对参数执行更新:
θt+1=θt−η⋅mt^vt^+ϵ\theta_{t+1} = \theta_t - \eta \cdot \frac{\hat{m_t}}{\sqrt{\hat{v_t}} + \epsilon}θt+1=θt−η⋅vt^ +ϵmt^
💻 示例代码
python
import torch
# 初始化权重参数
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 实例优化器
"""
lr=0.01: 学习率 $\eta$ 设为 $0.01$。betas=(0.9, 0.999):
Adam 算法的两个动量衰减率参数,这里使用了默认值
"""
optimizer = torch.optim.Adam([w], lr=0.01, betas=(0.9, 0.999))
# 迭代的次数
count = 30
for i in range(count):
# 目标函数
y = (w ** 2) / 2
# 清空梯度
optimizer.zero_grad()
# 计算梯度
y.backward()
# 更新参数
optimizer.step()
# 打印结果
print(f'梯度:{w.grad.item():.3f}, 权重: {w.item(): .3f}')
🧩 4.2 Adam 偏差校正因子计算案例
背景: 由于 m0=v0=0m_0 = v_0 = 0m0=v0=0,在训练初期,需要除以 (1−βt)(1 - \beta^t)(1−βt) 来放大修正,补偿初期低估。
给定:
β1=0.9,β2=0.999\beta_1 = 0.9, \quad \beta_2 = 0.999β1=0.9,β2=0.999
📊 计算结果表 (部分)
| 迭代步数 ttt | β1t\beta_1^tβ1t | 1−β1t1-\beta_1^t1−β1t | 1/(1−β1t)1/(1-\beta_1^t)1/(1−β1t) | β2t\beta_2^tβ2t | 1−β2t1-\beta_2^t1−β2t | 1/(1−β2t)1/(1-\beta_2^t)1/(1−β2t) |
|---|---|---|---|---|---|---|
| 1 | 0.90.90.9 | 0.10.10.1 | 10.0010.0010.00 | 0.9990.9990.999 | 0.0010.0010.001 | 1000.001000.001000.00 |
| 5 | 0.590490.590490.59049 | 0.409510.409510.40951 | 2.442.442.44 | 0.9950100.9950100.995010 | 0.0049900.0049900.004990 | 200.40200.40200.40 |
| 50 | 0.005150.005150.00515 | 0.994850.994850.99485 | 1.001.001.00 | 0.951230.951230.95123 | 0.048770.048770.04877 | 20.5120.5120.51 |
| 100 | 2.65×10−52.65 \times 10^{-5}2.65×10−5 | 0.999970.999970.99997 | 1.001.001.00 | 0.904790.904790.90479 | 0.095210.095210.09521 | 10.5110.5110.51 |
🔍 案例分析总结
| 项目 | 说明 |
|---|---|
| 偏差原因 | 初期 m0,v0=0m_0, v_0 = 0m0,v0=0,导致指数加权平均偏小 |
| 修正目的 | 补偿初期低估,使估计无偏 |
| 修正效果 | 初期放大权重(如 β2\beta_2β2 修正因子初期达 1000 倍 ),后期趋于 111 |
| 是否必须 | 是的,尤其在前几十步非常重要 |
✅ 优点
- 收敛快、稳定性强。
- 适合稀疏梯度与大规模数据。
- 几乎不需要手动调学习率。
❌ 缺点
- 可能陷入局部最优,泛化能力有时弱于SGD。
- 对 β1\beta_1β1、β2\beta_2β2 参数略敏感。
💼 典型应用
- 几乎所有深度学习模型默认选择(CNN、Transformer、GAN、BERT、GPT等)。
📊 五、四种算法对比表
| 算法 | 自适应学习率 | 动量机制 | 优点 | 缺点 | 典型应用 |
|---|---|---|---|---|---|
| Momentum | ❌ | ✅ | 平滑震荡,加快收敛 | 学习率固定 | CNN早期训练 |
| Adagrad | ✅ | ❌ | 稀疏特征友好 | 学习率过早衰减 | NLP词向量 |
| RMSProp | ✅ | ⚠️(隐含) | 学习率稳定 | 超参敏感 | RNN训练 |
| Adam | ✅ | ✅ | 稳定快速,默认首选 | 泛化略差 | CNN、Transformer、GAN等 |
🎓 六、简单总结口诀
🧩
- Momentum:加惯性,加速收敛。
- Adagrad:调速快,但太勤奋(衰减太快)。
- RMSProp:改良版Adagrad,更持久。
- Adam :全能型选手,几乎通吃。
