Adam(Adaptive Moment Estimation)是一種結合了動量法(Momentum)和 RMSProp 的自適應學習率優化算法。它通過計算梯度的一階矩(均值)和二階矩(未中心化的方差)來調整每個參數的學習率,從而在深度學習中表現出色。
1. Adam 的數學原理
1.1 動量法和 RMSProp 的回顧
- 動量法:通過引入動量變量,加速梯度下降并減少震蕩。
- RMSProp:通過指數加權移動平均計算歷史梯度平方和,自適應調整學習率。
Adam 結合了這兩種方法的優點,同時計算梯度的一階矩和二階矩。
1.2 Adam 的更新規則
Adam 的更新規則分為以下幾個步驟:
1.2.1 梯度計算
首先,計算當前時刻的梯度:
g t = ? θ J ( θ t ) g_t = \nabla_\theta J(\theta_t) gt?=?θ?J(θt?)
其中:
- g t g_t gt? 是當前時刻的梯度向量,形狀與參數 θ t \theta_t θt? 相同。
1.2.2 一階矩估計(動量)
Adam 使用指數加權移動平均來計算梯度的一階矩(均值):
m t = β 1 ? m t ? 1 + ( 1 ? β 1 ) ? g t m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t mt?=β1??mt?1?+(1?β1?)?gt?
其中:
- m t m_t mt? 是梯度的一階矩估計。
- β 1 \beta_1 β1? 是一階矩的衰減率,通常取值在 [ 0.9 , 0.99 ) [0.9, 0.99) [0.9,0.99) 之間。
- 初始時, m 0 m_0 m0? 通常設置為 0。
1.2.3 二階矩估計(RMSProp)
Adam 使用指數加權移動平均來計算梯度的二階矩(未中心化的方差):
v t = β 2 ? v t ? 1 + ( 1 ? β 2 ) ? g t 2 v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 vt?=β2??vt?1?+(1?β2?)?gt2?
其中:
- v t v_t vt? 是梯度的二階矩估計。
- β 2 \beta_2 β2? 是二階矩的衰減率,通常取值在 [ 0.99 , 0.999 ) [0.99, 0.999) [0.99,0.999) 之間。
- g t 2 g_t^2 gt2? 表示對梯度向量 g t g_t gt? 逐元素平方。
- 初始時, v 0 v_0 v0? 通常設置為 0。
1.2.4 偏差校正
由于 m t m_t mt? 和 v t v_t vt? 初始值為 0,在訓練初期會偏向 0,因此需要進行偏差校正:
m ^ t = m t 1 ? β 1 t \hat{m}_t = \frac{m_t}{1 - \beta_1^t} m^t?=1?β1t?mt??
v ^ t = v t 1 ? β 2 t \hat{v}_t = \frac{v_t}{1 - \beta_2^t} v^t?=1?β2t?vt??
其中:
- m ^ t \hat{m}_t m^t? 是校正后的一階矩估計。
- v ^ t \hat{v}_t v^t? 是校正后的二階矩估計。
- t t t 是當前時間步。
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 ? 是一個很小的常數(通常為 1 0 ? 8 10^{-8} 10?8),用于避免分母為零。
- v ^ t + ? \sqrt{\hat{v}_t} + \epsilon v^t??+? 是對校正后的二階矩估計逐元素開平方。
2. Adam 的詳細推導
2.1 一階矩和二階矩的意義
- 一階矩 m t m_t mt?:類似于動量法,表示梯度的指數加權移動平均,用于加速收斂。
- 二階矩 v t v_t vt?:類似于 RMSProp,表示梯度平方的指數加權移動平均,用于自適應調整學習率。
2.2 偏差校正的作用
偏差校正的目的是解決初始階段 m t m_t mt? 和 v t v_t vt? 偏向 0 的問題。通過除以 1 ? β 1 t 1 - \beta_1^t 1?β1t? 和 1 ? β 2 t 1 - \beta_2^t 1?β2t?,可以校正估計值,使其更接近真實值。
2.3 小常數 ? \epsilon ? 的作用
小常數 ? \epsilon ? 的作用是避免分母為零。具體來說:
- 當 v ^ t \hat{v}_t v^t? 很小時, v ^ t + ? \sqrt{\hat{v}_t} + \epsilon v^t??+? 接近于 ? \epsilon ?,避免學習率過大。
- 當 v ^ t \hat{v}_t v^t? 很大時, ? \epsilon ? 的影響可以忽略不計。
3. PyTorch 中的 Adam 實現
在 PyTorch 中,Adam 通過 torch.optim.Adam
實現。以下是 torch.optim.Adam
的主要參數:
參數名 | 含義 |
---|---|
params | 需要優化的參數(通常是模型的參數)。 |
lr | 全局學習率(learning rate),即 η \eta η,默認值為 1 0 ? 3 10^{-3} 10?3。 |
betas | 一階矩和二階矩的衰減率,即 ( β 1 , β 2 ) (\beta_1, \beta_2) (β1?,β2?),默認值為 (0.9, 0.999)。 |
eps | 分母中的小常數 ? \epsilon ?,用于避免除零,默認值為 1 0 ? 8 10^{-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 ? 用于避免分母為零,通常設置為 1 0 ? 8 10^{-8} 10?8。
-
權重衰減 (
weight_decay
):- 權重衰減系數用于 L2 正則化,防止過擬合。
-
AMSGrad (
amsgrad
):- 如果設置為
True
,則使用 AMSGrad 變體,解決 Adam 在某些情況下的收斂問題。
- 如果設置為
4. 總結
- Adam 的核心思想:結合動量法和 RMSProp,通過計算梯度的一階矩和二階矩,自適應調整學習率。
- Adam 的更新公式:
m t = β 1 ? m t ? 1 + ( 1 ? β 1 ) ? g t m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t mt?=β1??mt?1?+(1?β1?)?gt?
v t = β 2 ? v t ? 1 + ( 1 ? β 2 ) ? g t 2 v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 vt?=β2??vt?1?+(1?β2?)?gt2?
m ^ t = m t 1 ? β 1 t \hat{m}_t = \frac{m_t}{1 - \beta_1^t} m^t?=1?β1t?mt??
v ^ t = v t 1 ? β 2 t \hat{v}_t = \frac{v_t}{1 - \beta_2^t} v^t?=1?β2t?vt??
θ 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?)。