梯度下降优化算法-Adam
Adam 的核心思想:结合动量法和 RMSProp,通过计算梯度的一阶矩和二阶矩,自适应调整学习率。Adam 的更新公式mtβ1⋅mt−11−β1⋅gtmtβ1⋅mt−11−β1⋅gtvtβ2⋅vt−11−β2⋅gt2vtβ2⋅vt−11−β2⋅gt2mtmt1−β1tmt1−β1tmt。
Adam(Adaptive Moment Estimation)是一种结合了动量法(Momentum)和 RMSProp 的自适应学习率优化算法。它通过计算梯度的一阶矩(均值)和二阶矩(未中心化的方差)来调整每个参数的学习率,从而在深度学习中表现出色。
1. Adam 的数学原理
1.1 动量法和 RMSProp 的回顾
- 动量法:通过引入动量变量,加速梯度下降并减少震荡。
- RMSProp:通过指数加权移动平均计算历史梯度平方和,自适应调整学习率。
Adam 结合了这两种方法的优点,同时计算梯度的一阶矩和二阶矩。
1.2 Adam 的更新规则
Adam 的更新规则分为以下几个步骤:
1.2.1 梯度计算
首先,计算当前时刻的梯度:
gt=∇θJ(θt) g_t = \nabla_\theta J(\theta_t) gt=∇θJ(θt)
其中:
- gtg_tgt 是当前时刻的梯度向量,形状与参数 θt\theta_tθt 相同。
1.2.2 一阶矩估计(动量)
Adam 使用指数加权移动平均来计算梯度的一阶矩(均值):
mt=β1⋅mt−1+(1−β1)⋅gt m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t mt=β1⋅mt−1+(1−β1)⋅gt
其中:
- mtm_tmt 是梯度的一阶矩估计。
- β1\beta_1β1 是一阶矩的衰减率,通常取值在 [0.9,0.99)[0.9, 0.99)[0.9,0.99) 之间。
- 初始时,m0m_0m0 通常设置为 0。
1.2.3 二阶矩估计(RMSProp)
Adam 使用指数加权移动平均来计算梯度的二阶矩(未中心化的方差):
vt=β2⋅vt−1+(1−β2)⋅gt2 v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 vt=β2⋅vt−1+(1−β2)⋅gt2
其中:
- vtv_tvt 是梯度的二阶矩估计。
- β2\beta_2β2 是二阶矩的衰减率,通常取值在 [0.99,0.999)[0.99, 0.999)[0.99,0.999) 之间。
- gt2g_t^2gt2 表示对梯度向量 gtg_tgt 逐元素平方。
- 初始时,v0v_0v0 通常设置为 0。
1.2.4 偏差校正
由于 mtm_tmt 和 vtv_tvt 初始值为 0,在训练初期会偏向 0,因此需要进行偏差校正:
m^t=mt1−β1t \hat{m}_t = \frac{m_t}{1 - \beta_1^t} m^t=1−β1tmt
v^t=vt1−β2t \hat{v}_t = \frac{v_t}{1 - \beta_2^t} v^t=1−β2tvt
其中:
- m^t\hat{m}_tm^t 是校正后的一阶矩估计。
- v^t\hat{v}_tv^t 是校正后的二阶矩估计。
- ttt 是当前时间步。
1.2.5 参数更新
最后,Adam 的参数更新公式为:
θt+1=θt−ηv^t+ϵ⋅m^t \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \cdot \hat{m}_t θt+1=θt−v^t+ϵη⋅m^t
其中:
- η\etaη 是全局学习率。
- ϵ\epsilonϵ 是一个很小的常数(通常为 10−810^{-8}10−8),用于避免分母为零。
- v^t+ϵ\sqrt{\hat{v}_t} + \epsilonv^t+ϵ 是对校正后的二阶矩估计逐元素开平方。
2. Adam 的详细推导
2.1 一阶矩和二阶矩的意义
- 一阶矩 mtm_tmt:类似于动量法,表示梯度的指数加权移动平均,用于加速收敛。
- 二阶矩 vtv_tvt:类似于 RMSProp,表示梯度平方的指数加权移动平均,用于自适应调整学习率。
2.2 偏差校正的作用
偏差校正的目的是解决初始阶段 mtm_tmt 和 vtv_tvt 偏向 0 的问题。通过除以 1−β1t1 - \beta_1^t1−β1t 和 1−β2t1 - \beta_2^t1−β2t,可以校正估计值,使其更接近真实值。
2.3 小常数 ϵ\epsilonϵ 的作用
小常数 ϵ\epsilonϵ 的作用是避免分母为零。具体来说:
- 当 v^t\hat{v}_tv^t 很小时,v^t+ϵ\sqrt{\hat{v}_t} + \epsilonv^t+ϵ 接近于 ϵ\epsilonϵ,避免学习率过大。
- 当 v^t\hat{v}_tv^t 很大时,ϵ\epsilonϵ 的影响可以忽略不计。
3. PyTorch 中的 Adam 实现
在 PyTorch 中,Adam 通过 torch.optim.Adam 实现。以下是 torch.optim.Adam 的主要参数:
| 参数名 | 含义 |
|---|---|
params |
需要优化的参数(通常是模型的参数)。 |
lr |
全局学习率(learning rate),即 η\etaη,默认值为 10−310^{-3}10−3。 |
betas |
一阶矩和二阶矩的衰减率,即 (β1,β2)(\beta_1, \beta_2)(β1,β2),默认值为 (0.9, 0.999)。 |
eps |
分母中的小常数 ϵ\epsilonϵ,用于避免除零,默认值为 10−810^{-8}10−8。 |
weight_decay |
权重衰减(L2 正则化)系数,默认值为 0。 |
amsgrad |
是否使用 AMSGrad 变体,默认值为 False。 |
3.1 使用 Adam 的代码示例
以下是一个使用 Adam 的完整代码示例:
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的线性模型
model = nn.Linear(10, 1)
# 定义损失函数
criterion = nn.MSELoss()
# 定义优化器,使用 Adam
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.01)
# 模拟输入数据和目标数据
inputs = torch.randn(32, 10) # 32 个样本,每个样本 10 维
targets = torch.randn(32, 1) # 32 个目标值
# 训练过程
for epoch in range(100):
# 前向传播
outputs = model(inputs)
loss = criterion(outputs, targets)
# 反向传播
optimizer.zero_grad() # 清空梯度
loss.backward() # 计算梯度
# 更新参数
optimizer.step() # 更新参数
# 打印损失
if (epoch + 1) % 10 == 0:
print(f"Epoch [{epoch+1}/100], Loss: {loss.item():.4f}")
3.2 参数设置说明
-
学习率 (
lr):- 学习率 η\etaη 控制每次参数更新的步长。
- 在 Adam 中,学习率会自适应调整,因此初始学习率可以设置得稍小一些。
-
衰减率 (
betas):- 一阶矩衰减率 β1\beta_1β1 和二阶矩衰减率 β2\beta_2β2 分别控制一阶矩和二阶矩的衰减速度。
- 默认值为 (0.9, 0.999),适用于大多数情况。
-
小常数 (
eps):- 小常数 ϵ\epsilonϵ 用于避免分母为零,通常设置为 10−810^{-8}10−8。
-
权重衰减 (
weight_decay):- 权重衰减系数用于 L2 正则化,防止过拟合。
-
AMSGrad (
amsgrad):- 如果设置为
True,则使用 AMSGrad 变体,解决 Adam 在某些情况下的收敛问题。
- 如果设置为
4. 总结
- Adam 的核心思想:结合动量法和 RMSProp,通过计算梯度的一阶矩和二阶矩,自适应调整学习率。
- Adam 的更新公式:
mt=β1⋅mt−1+(1−β1)⋅gt m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t mt=β1⋅mt−1+(1−β1)⋅gt
vt=β2⋅vt−1+(1−β2)⋅gt2 v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 vt=β2⋅vt−1+(1−β2)⋅gt2
m^t=mt1−β1t \hat{m}_t = \frac{m_t}{1 - \beta_1^t} m^t=1−β1tmt
v^t=vt1−β2t \hat{v}_t = \frac{v_t}{1 - \beta_2^t} v^t=1−β2tvt
θt+1=θt−ηv^t+ϵ⋅m^t \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \cdot \hat{m}_t θt+1=θt−v^t+ϵη⋅m^t - PyTorch 实现:使用
torch.optim.Adam,设置lr、betas、eps等参数。 - 优缺点:
- 优点:自适应学习率,适合非凸优化问题,收敛速度快。
- 缺点:需要手动调整超参数(如 β1\beta_1β1 和 β2\beta_2β2)。
更多推荐


所有评论(0)