完整講解與原文對照 / Full explanation and source comparison
RMSProp:用指數移動平均取代累積和
AdaGrad 的累積和只增不減,長期後學習率會過度衰減。RMSProp [42] 的改進靈感來自動量——用指數移動平均(exponentially decaying average)取代累積和,讓舊梯度資訊逐漸被遺忘。
維護梯度平方的移動平均(式 (40)):
v(k+1):=γv(k)+(1−γ)∇fi(w(k))22,
其中 γ∈[0,1] 是遺忘因子(例如 γ=0.9)。參數更新(式 (41)):
w(k+1):=w(k)−ε+v(k+1)η(k)∇fj(wj(k)).
RMSProp 的行為類似 AdaGrad,但分母是指數衰減平均而非無限累加,避免了學習率過早歸零的問題。
Adam:動量 + RMSProp 的結合
Adam(Adaptive Moment Estimation)[25] 是目前深度學習中最廣泛使用的優化器。它同時維護梯度的一階矩(動量)與二階矩(RMSProp 風格的方差估計):
m(k+1):=γ1m(k)+(1−γ1)∇fi(w(k)),(42)
v(k+1):=γ2v(k)+(1−γ2)∇fi(w(k))22,(43)
其中 γ1,γ2∈[0,1]。
偏置修正(Bias Correction)
一個容易忽略的細節:m 和 v 初始為 0,早期迭代會系統性地偏向 0。Adam 用偏置修正(式 (44)–(45))補償:
m(k+1):=1−γ1k1m(k+1),(44)
v(k+1):=1−γ2k1v(k+1).(45)
當 k 很小時,1−γ1k 遠小於 1,修正因子把被壓低的矩估計「拉回來」;隨 k 增大,修正因子趨近 1,影響消失。
最終更新(式 (46))
w(k+1):=w(k)−ε+v(k+1)η(k)m(k+1).
這等價於帶動量的 SGD + 自適應縮放:m 提供方向(含動量平滑),v 提供逐維度的步幅調整。大多數深度學習框架(PyTorch、TensorFlow 等)都將 SGD(mini-batch 版)與 Adam 列為標準選項。
教授祕笈:RMSProp 與 Adam——健忘油表加上剛發動校正
同學,KP-10 的 AdaGrad 把每滴油耗都記在帳上、永不擦掉,最後油門被勒死。這一站換一個主線比喻:健忘油表。RMSProp 不記一輩子的平方和,只記「最近的油耗」——舊帳會被遺忘。Adam 再把 KP-5 的動量方向接上去,但儀表剛發動時指針從 0 起跳、讀數偏低,所以要做偏置修正:用 1/(1−γk) 把指針拉回真實。今天會親手算一組 γ=0.9、k=1 的修正因子——答案是整整 10 倍。
先把任務講成一句人話
一句話:RMSProp 用會遺忘的平方平均取代 AdaGrad 的死帳;Adam 再加動量,並把「剛發動讀數偏低」除以 1−γk 校正回來。
鷹架式:先直覺,再符號
AdaGrad 的分母只增不減,訓久了有效學習率趨近 0。RMSProp 的靈感來自動量:不要累加,改成指數移動平均——每一步,舊記憶乘上遺忘因子 γ(常見 0.9),再摻一點新的梯度平方。舊的大梯度會慢慢淡出,學習率才不會被早期的一次暴衝永久鎖死。
Adam(Adaptive Moment Estimation)把兩件事焊在一起:一階矩 m 管方向(動量),二階矩 v 管步幅(RMSProp 風格的平方平均)。大多數深度學習框架把它跟 mini-batch SGD 並列成預設選項。
還有一件容易被略過的事:m 和 v 都從 0 開始。早期它們會系統性地偏小。不修正的話,前幾步等於故意踩小油門。偏置修正就是把被壓低的估計除以 1−γk 拉回來;k 變大後這個因子趨近 1,影響自動消失。
符號逐個拆(式 (40)–(46))
RMSProp 維護梯度平方的移動平均(式 (40)):
v(k+1):=γv(k)+(1−γ)∇fi(w(k))22,
γ∈[0,1] 是遺忘因子。更新(式 (41)):
w(k+1):=w(k)−ε+v(k+1)η(k)∇fj(wj(k)).
Adam 同時維護一階矩與二階矩(式 (42)、(43)):
m(k+1):=γ1m(k)+(1−γ1)∇fi(w(k)),
v(k+1):=γ2v(k)+(1−γ2)∇fi(w(k))22.
偏置修正(式 (44)、(45)):
m(k+1):=1−γ1k1m(k+1),v(k+1):=1−γ2k1v(k+1).
最終更新(式 (46))是「帶動量的方向,除以自適應的步幅」:
w(k+1):=w(k)−ε+v(k+1)η(k)m(k+1).
真的算一遍:γ=0.9、k=1 的修正因子
先算修正因子表。γ=0.9 時,γ1=0.9,所以
1−γ11=1−0.91=10.
剛發動那一步,要把被壓低的矩估計放大十倍。後面幾步因子迅速掉回 1 附近:
| k | γk(γ=0.9) | 1−γk | 修正因子 1/(1−γk) |
| 1 | 0.900 | 0.100 | 10.00 |
| 2 | 0.810 | 0.190 | 5.26 |
| 5 | 0.590 | 0.410 | 2.44 |
| 10 | 0.349 | 0.651 | 1.54 |
| 20 | 0.122 | 0.878 | 1.14 |
| ∞ | 0 | 1 | 1.00 |
配一組真實梯度看「拉回來」在幹嘛。令 γ1=γ2=0.9,m(0)=0、v(0)=0,當前梯度 g=4,所以 g2=16。
| 量 | 未修正 | k=1 修正(除以 0.1) |
| 一階矩 m | 0.9⋅0+0.1⋅4=0.4 | 0.4/0.1=4.0(回到 g) |
| 二階矩 v | 0.1⋅16=1.6 | 1.6/0.1=16(回到 g2) |
| 有效方向 m/v | 0.4/1.6≈0.316 | 4/16=1 |
不修正時,第一步的方向長度只有約 0.316,整整被壓了三倍;修正後恰好是「單位化後的梯度方向」。這就是剛發動要校正指針的理由。
遺忘平方也可以對一下數字。設某維先來一筆 g=10(g2=100),之後梯度為 0。AdaGrad 的分母至少永遠是 100=10。RMSProp 從 v=10 開始(第一步 0.1×100),之後每步乘 0.9:十步後 10×0.910≈3.49,二十步後 ≈1.22。舊的暴衝被忘掉,油門重新活過來。
先留一個反轉
看到 m 的公式裡有 (1−γ1)g,有人會覺得「第一步本來就該小,溫和起步比較穩」。Adam 的設計剛好相反:它認為那一下偏小不是溫和,是偏差——因為起始值是 0,不是因為你想保守。所以 k=1 時硬把估計乘回 10,讓第一步看得到真正的梯度。溫和與否,該由 η 決定,不該由「從零啟動」偷偷決定。
換個場景,自己找出同一條路
把「矩估計」換成「體重計剛換電池」。指針從 0 爬升,前幾次讀數一定偏低;校正因子就是告訴你「現在只顯示了真實值的 1−γk,請除回去」。
自己算一題:γ=0.9、k=2,修正因子是多少?若未修正的 m=0.58,修正後的 m 是多少?(提示:0.92=0.81。)
大家最容易在這裡搞混
第一,「Adam 的一階矩、二階矩是權重的均值與方差」。錯。它們是梯度的動量與平方移動平均,不是參數本身的統計量。第二,「偏置修正是為了找尖銳極小值或取代正規化」。錯。它只補償 m、v 從 0 啟動造成的系統性偏低。第三,「RMSProp 跟 AdaGrad 分母一樣都在無限累加」。錯。RMSProp 會遺忘,這正是它相對 AdaGrad 的關鍵改進。
跨知識點掛勾
KP-5 的動量就是 Adam 的 m;KP-10 的 AdaGrad 就是「不會遺忘的 v」。KP-7、KP-8 的 SGD/mini-batch 仍是骨架,Adam 是在這副骨架上加方向平滑與逐維步幅。KP-9 提醒固定步長會在帶子裡晃——Adam 沒有取消 η,它只是讓各維的有效步長不再共用同一個數字。
換句話重述
RMSProp 用指數平均遺忘舊的梯度平方,避免學習率被勒死;Adam 再加動量,並用 1/(1−γk) 把剛發動偏低的讀數拉回。γ=0.9、k=1 時修正因子是 10。
一句話收尾: 舊帳要忘、剛發動要校正——γ=0.9 的第一步,指針得乘回十倍才是真的。