m^t=mt1−β1t,v^t=vt1−β2t,t≥1\hat m_t=\frac{m_t}{1-\beta_1^t},\qquad \hat v_t=\frac{v_t}{1-\beta_2^t},\quad t\ge1
gt=c, m0=0⇒mt=(1−β1t)c, m^t=cg_t=c,\ m_0=0\Rightarrow m_t=(1-\beta_1^t)c,\ \hat m_t=c

完整講解與原文對照 / Full explanation and source comparison

RMSProp:用指數移動平均取代累積和

AdaGrad 的累積和只增不減,長期後學習率會過度衰減。RMSProp [42] 的改進靈感來自動量——用指數移動平均(exponentially decaying average)取代累積和,讓舊梯度資訊逐漸被遺忘。

維護梯度平方的移動平均(式 (40)):

v(k+1):=γv(k)+(1−γ)∥∇fi(w(k))∥22, v^{(k+1)}:=\gamma v^{(k)}+(1-\gamma)\left\|\nabla f_{i}\left(\boldsymbol{w}^{(k)}\right)\right\|_{2}^{2},

其中 γ∈[0,1]\gamma \in [0,1] 是遺忘因子(例如 γ=0.9\gamma=0.9)。參數更新(式 (41)):

w(k+1):=w(k)−η(k)ε+v(k+1)∇fj(wj(k)). \boldsymbol{w}^{(k+1)}:=\boldsymbol{w}^{(k)}-\frac{\eta^{(k)}}{\sqrt{\varepsilon+v^{(k+1)}}} \nabla f_{j}\left(\boldsymbol{w}_{j}^{(k)}\right) .

RMSProp 的行為類似 AdaGrad,但分母是指數衰減平均而非無限累加,避免了學習率過早歸零的問題。

Adam:動量 + RMSProp 的結合

Adam(Adaptive Moment Estimation)[25] 是目前深度學習中最廣泛使用的優化器。它同時維護梯度的一階矩(動量)與二階矩(RMSProp 風格的方差估計):

m(k+1):=γ1m(k)+(1−γ1)∇fi(w(k)),(42) \boldsymbol{m}^{(k+1)} :=\gamma_{1} \boldsymbol{m}^{(k)}+\left(1-\gamma_{1}\right) \nabla f_{i}\left(\boldsymbol{w}^{(k)}\right), \tag{42}

v(k+1):=γ2v(k)+(1−γ2)∥∇fi(w(k))∥22,(43) v^{(k+1)} :=\gamma_{2} v^{(k)}+\left(1-\gamma_{2}\right)\left\|\nabla f_{i}\left(\boldsymbol{w}^{(k)}\right)\right\|_{2}^{2}, \tag{43}

其中 γ1,γ2∈[0,1]\gamma_{1}, \gamma_{2} \in [0,1]。

偏置修正(Bias Correction)

一個容易忽略的細節:m\boldsymbol{m} 和 vv 初始為 0,早期迭代會系統性地偏向 0。Adam 用偏置修正(式 (44)–(45))補償:

m^(k+1):=11−γ1km(k+1),(44) \widehat{\boldsymbol{m}}^{(k+1)} :=\frac{1}{1-\gamma_{1}^{k}} \boldsymbol{m}^{(k+1)}, \tag{44}

v^(k+1):=11−γ2kv(k+1).(45) \widehat{v}^{(k+1)} :=\frac{1}{1-\gamma_{2}^{k}} v^{(k+1)} . \tag{45}

當 kk 很小時,1−γ1k1-\gamma_{1}^{k} 遠小於 1,修正因子把被壓低的矩估計「拉回來」;隨 kk 增大,修正因子趨近 1,影響消失。

最終更新(式 (46))

w(k+1):=w(k)−η(k)ε+v^(k+1)m^(k+1). \boldsymbol{w}^{(k+1)}:=\boldsymbol{w}^{(k)}-\frac{\eta^{(k)}}{\sqrt{\varepsilon+\widehat{v}^{(k+1)}}} \widehat{\boldsymbol{m}}^{(k+1)} .

這等價於帶動量的 SGD + 自適應縮放:m^\widehat{\boldsymbol{m}} 提供方向(含動量平滑),v^\sqrt{\widehat{v}} 提供逐維度的步幅調整。大多數深度學習框架(PyTorch、TensorFlow 等)都將 SGD(mini-batch 版)與 Adam 列為標準選項。

教授祕笈:RMSProp 與 Adam——健忘油表加上剛發動校正

同學,KP-10 的 AdaGrad 把每滴油耗都記在帳上、永不擦掉,最後油門被勒死。這一站換一個主線比喻:健忘油表。RMSProp 不記一輩子的平方和,只記「最近的油耗」——舊帳會被遺忘。Adam 再把 KP-5 的動量方向接上去,但儀表剛發動時指針從 0 起跳、讀數偏低,所以要做偏置修正:用 1/(1−γk)1/(1-\gamma^{k}) 把指針拉回真實。今天會親手算一組 γ=0.9\gamma=0.9、k=1k=1 的修正因子——答案是整整 10 倍。

先把任務講成一句人話

一句話:RMSProp 用會遺忘的平方平均取代 AdaGrad 的死帳;Adam 再加動量,並把「剛發動讀數偏低」除以 1−γk1-\gamma^{k} 校正回來。

鷹架式:先直覺,再符號

AdaGrad 的分母只增不減,訓久了有效學習率趨近 0。RMSProp 的靈感來自動量:不要累加,改成指數移動平均——每一步,舊記憶乘上遺忘因子 γ\gamma(常見 0.90.9),再摻一點新的梯度平方。舊的大梯度會慢慢淡出,學習率才不會被早期的一次暴衝永久鎖死。

Adam(Adaptive Moment Estimation)把兩件事焊在一起:一階矩 m\boldsymbol{m} 管方向(動量),二階矩 vv 管步幅(RMSProp 風格的平方平均)。大多數深度學習框架把它跟 mini-batch SGD 並列成預設選項。

還有一件容易被略過的事:m\boldsymbol{m} 和 vv 都從 0 開始。早期它們會系統性地偏小。不修正的話,前幾步等於故意踩小油門。偏置修正就是把被壓低的估計除以 1−γk1-\gamma^{k} 拉回來;kk 變大後這個因子趨近 1,影響自動消失。

符號逐個拆(式 (40)–(46))

RMSProp 維護梯度平方的移動平均(式 (40)):

v(k+1):=γv(k)+(1−γ)∥∇fi(w(k))∥22, v^{(k+1)}:=\gamma v^{(k)}+(1-\gamma)\bigl\|\nabla f_{i}(\boldsymbol{w}^{(k)})\bigr\|_{2}^{2},

γ∈[0,1]\gamma\in[0,1] 是遺忘因子。更新(式 (41)):

w(k+1):=w(k)−η(k)ε+v(k+1) ∇fj(wj(k)). \boldsymbol{w}^{(k+1)}:=\boldsymbol{w}^{(k)}-\frac{\eta^{(k)}}{\sqrt{\varepsilon+v^{(k+1)}}}\,\nabla f_{j}\bigl(\boldsymbol{w}_{j}^{(k)}\bigr).

Adam 同時維護一階矩與二階矩(式 (42)、(43)):

m(k+1):=γ1m(k)+(1−γ1)∇fi(w(k)), \boldsymbol{m}^{(k+1)}:=\gamma_{1}\boldsymbol{m}^{(k)}+(1-\gamma_{1})\nabla f_{i}(\boldsymbol{w}^{(k)}),

v(k+1):=γ2v(k)+(1−γ2)∥∇fi(w(k))∥22. v^{(k+1)}:=\gamma_{2}v^{(k)}+(1-\gamma_{2})\bigl\|\nabla f_{i}(\boldsymbol{w}^{(k)})\bigr\|_{2}^{2}.

偏置修正(式 (44)、(45)):

m^(k+1):=11−γ1k m(k+1),v^(k+1):=11−γ2k v(k+1). \widehat{\boldsymbol{m}}^{(k+1)}:=\frac{1}{1-\gamma_{1}^{k}}\,\boldsymbol{m}^{(k+1)},\qquad \widehat{v}^{(k+1)}:=\frac{1}{1-\gamma_{2}^{k}}\,v^{(k+1)}.

最終更新(式 (46))是「帶動量的方向,除以自適應的步幅」:

w(k+1):=w(k)−η(k)ε+v^(k+1) m^(k+1). \boldsymbol{w}^{(k+1)}:=\boldsymbol{w}^{(k)}-\frac{\eta^{(k)}}{\sqrt{\varepsilon+\widehat{v}^{(k+1)}}}\,\widehat{\boldsymbol{m}}^{(k+1)}.

真的算一遍:γ=0.9\gamma=0.9、k=1k=1 的修正因子

先算修正因子表。γ=0.9\gamma=0.9 時,γ1=0.9\gamma^{1}=0.9,所以

11−γ1=11−0.9=10. \frac{1}{1-\gamma^{1}}=\frac{1}{1-0.9}=10.

剛發動那一步,要把被壓低的矩估計放大十倍。後面幾步因子迅速掉回 1 附近:

kk γk\gamma^{k}(γ=0.9\gamma=0.9) 1−γk1-\gamma^{k} 修正因子 1/(1−γk)1/(1-\gamma^{k})
11 0.9000.900 0.1000.100 10.0010.00
22 0.8100.810 0.1900.190 5.265.26
55 0.5900.590 0.4100.410 2.442.44
1010 0.3490.349 0.6510.651 1.541.54
2020 0.1220.122 0.8780.878 1.141.14
∞\infty 00 11 1.001.00

配一組真實梯度看「拉回來」在幹嘛。令 γ1=γ2=0.9\gamma_{1}=\gamma_{2}=0.9,m(0)=0\boldsymbol{m}^{(0)}=0、v(0)=0v^{(0)}=0,當前梯度 g=4g=4,所以 g2=16g^{2}=16。

量 未修正 k=1k=1 修正(除以 0.10.1)
一階矩 mm 0.9⋅0+0.1⋅4=0.40.9\cdot 0+0.1\cdot 4=0.4 0.4/0.1=4.00.4/0.1=4.0(回到 gg)
二階矩 vv 0.1⋅16=1.60.1\cdot 16=1.6 1.6/0.1=161.6/0.1=16(回到 g2g^{2})
有效方向 m/vm/\sqrt{v} 0.4/1.6≈0.3160.4/\sqrt{1.6}\approx 0.316 4/16=14/\sqrt{16}=1

不修正時,第一步的方向長度只有約 0.3160.316,整整被壓了三倍;修正後恰好是「單位化後的梯度方向」。這就是剛發動要校正指針的理由。

遺忘平方也可以對一下數字。設某維先來一筆 g=10g=10(g2=100g^{2}=100),之後梯度為 0。AdaGrad 的分母至少永遠是 100=10\sqrt{100}=10。RMSProp 從 v=10v=10 開始(第一步 0.1×1000.1\times 100),之後每步乘 0.90.9:十步後 10×0.910≈3.4910\times 0.9^{10}\approx 3.49,二十步後 ≈1.22\approx 1.22。舊的暴衝被忘掉,油門重新活過來。

先留一個反轉

看到 mm 的公式裡有 (1−γ1)g(1-\gamma_{1})g,有人會覺得「第一步本來就該小,溫和起步比較穩」。Adam 的設計剛好相反:它認為那一下偏小不是溫和,是偏差——因為起始值是 0,不是因為你想保守。所以 k=1k=1 時硬把估計乘回 10,讓第一步看得到真正的梯度。溫和與否,該由 η\eta 決定,不該由「從零啟動」偷偷決定。

換個場景,自己找出同一條路

把「矩估計」換成「體重計剛換電池」。指針從 0 爬升,前幾次讀數一定偏低;校正因子就是告訴你「現在只顯示了真實值的 1−γk1-\gamma^{k},請除回去」。

自己算一題:γ=0.9\gamma=0.9、k=2k=2,修正因子是多少?若未修正的 m=0.58m=0.58,修正後的 m^\widehat{m} 是多少?(提示:0.92=0.810.9^{2}=0.81。)

大家最容易在這裡搞混

第一,「Adam 的一階矩、二階矩是權重的均值與方差」。錯。它們是梯度的動量與平方移動平均,不是參數本身的統計量。第二,「偏置修正是為了找尖銳極小值或取代正規化」。錯。它只補償 mm、vv 從 0 啟動造成的系統性偏低。第三,「RMSProp 跟 AdaGrad 分母一樣都在無限累加」。錯。RMSProp 會遺忘,這正是它相對 AdaGrad 的關鍵改進。

跨知識點掛勾

KP-5 的動量就是 Adam 的 m\boldsymbol{m};KP-10 的 AdaGrad 就是「不會遺忘的 vv」。KP-7、KP-8 的 SGD/mini-batch 仍是骨架,Adam 是在這副骨架上加方向平滑與逐維步幅。KP-9 提醒固定步長會在帶子裡晃——Adam 沒有取消 η\eta,它只是讓各維的有效步長不再共用同一個數字。

換句話重述

RMSProp 用指數平均遺忘舊的梯度平方,避免學習率被勒死;Adam 再加動量,並用 1/(1−γk)1/(1-\gamma^{k}) 把剛發動偏低的讀數拉回。γ=0.9\gamma=0.9、k=1k=1 時修正因子是 10。

一句話收尾: 舊帳要忘、剛發動要校正——γ=0.9\gamma=0.9 的第一步,指針得乘回十倍才是真的。