一个框架看懂优化算法之异同 SGD/AdaGrad/Adam
Adam那么棒,為什么還對SGD念念不忘 (1) —— 一個框架看懂優(yōu)化算法
?
機(jī)器學(xué)習(xí)界有一群煉丹師,他們每天的日常是:
?
拿來藥材(數(shù)據(jù)),架起八卦爐(模型),點(diǎn)著六味真火(優(yōu)化算法),就搖著蒲扇等著丹藥出爐了。
?
不過,當(dāng)過廚子的都知道,同樣的食材,同樣的菜譜,但火候不一樣了,這出來的口味可是千差萬別。火小了夾生,火大了易糊,火不勻則半生半糊。
?
機(jī)器學(xué)習(xí)也是一樣,模型優(yōu)化算法的選擇直接關(guān)系到最終模型的性能。有時候效果不好,未必是特征的問題或者模型設(shè)計(jì)的問題,很可能就是優(yōu)化算法的問題。
?
說到優(yōu)化算法,入門級必從SGD學(xué)起,老司機(jī)則會告訴你更好的還有AdaGrad/AdaDelta,或者直接無腦用Adam。可是看看學(xué)術(shù)界的最新paper,卻發(fā)現(xiàn)一眾大神還在用著入門級的SGD,最多加個Moment或者Nesterov ,還經(jīng)常會黑一下Adam。比如 UC Berkeley的一篇論文就在Conclusion中寫道:
?
Despite the fact that our experimental evidence demonstrates that adaptive methods are not advantageous for machine learning, the Adam algorithm remains incredibly popular. We are not sure exactly as to why ……
?
無奈與酸楚之情溢于言表。
?
這是為什么呢?難道平平淡淡才是真?
一個框架回顧優(yōu)化算法
?
首先我們來回顧一下各類優(yōu)化算法。
?
深度學(xué)習(xí)優(yōu)化算法經(jīng)歷了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 這樣的發(fā)展歷程。Google一下就可以看到很多的教程文章,詳細(xì)告訴你這些算法是如何一步一步演變而來的。在這里,我們換一個思路,用一個框架來梳理所有的優(yōu)化算法,做一個更加高屋建瓴的對比。
?
首先定義:待優(yōu)化參數(shù):??,目標(biāo)函數(shù):??,初始學(xué)習(xí)率?。
而后,開始進(jìn)行迭代優(yōu)化。在每個epoch??:
- 計(jì)算目標(biāo)函數(shù)關(guān)于當(dāng)前參數(shù)的梯度:?
- 根據(jù)歷史梯度計(jì)算一階動量和二階動量:,
- 計(jì)算當(dāng)前時刻的下降梯度:?
- 根據(jù)下降梯度進(jìn)行更新:?
掌握了這個框架,你可以輕輕松松設(shè)計(jì)自己的優(yōu)化算法。
?
我們拿著這個框架,來照一照各種玄乎其玄的優(yōu)化算法的真身。步驟3、4對于各個算法都是一致的,主要的差別就體現(xiàn)在1和2上。
?
SGD
先來看SGD。SGD沒有動量的概念,也就是說:
代入步驟3,可以看到下降梯度就是最簡單的
SGD最大的缺點(diǎn)是下降速度慢,而且可能會在溝壑的兩邊持續(xù)震蕩,停留在一個局部最優(yōu)點(diǎn)。
?
SGD with Momentum
為了抑制SGD的震蕩,SGDM認(rèn)為梯度下降過程可以加入慣性。下坡的時候,如果發(fā)現(xiàn)是陡坡,那就利用慣性跑的快一些。SGDM全稱是SGD with momentum,在SGD基礎(chǔ)上引入了一階動量:
一階動量是各個時刻梯度方向的指數(shù)移動平均值,約等于最近??個時刻的梯度向量和的平均值。
?
也就是說,t時刻的下降方向,不僅由當(dāng)前點(diǎn)的梯度方向決定,而且由此前累積的下降方向決定。??的經(jīng)驗(yàn)值為0.9,這就意味著下降方向主要是此前累積的下降方向,并略微偏向當(dāng)前時刻的下降方向。想象高速公路上汽車轉(zhuǎn)彎,在高速向前的同時略微偏向,急轉(zhuǎn)彎可是要出事的。
?
SGD with Nesterov Acceleration
SGD 還有一個問題是困在局部最優(yōu)的溝壑里面震蕩。想象一下你走到一個盆地,四周都是略高的小山,你覺得沒有下坡的方向,那就只能待在這里了。可是如果你爬上高地,就會發(fā)現(xiàn)外面的世界還很廣闊。因此,我們不能停留在當(dāng)前位置去觀察未來的方向,而要向前一步、多看一步、看遠(yuǎn)一些。
?
NAG全稱Nesterov Accelerated Gradient,是在SGD、SGD-M的基礎(chǔ)上的進(jìn)一步改進(jìn),改進(jìn)點(diǎn)在于步驟1。我們知道在時刻t的主要下降方向是由累積動量決定的,自己的梯度方向說了也不算,那與其看當(dāng)前梯度方向,不如先看看如果跟著累積動量走了一步,那個時候再怎么走。因此,NAG在步驟1,不計(jì)算當(dāng)前位置的梯度方向,而是計(jì)算如果按照累積動量走了一步,那個時候的下降方向:
然后用下一個點(diǎn)的梯度方向,與歷史累積動量相結(jié)合,計(jì)算步驟2中當(dāng)前時刻的累積動量。
?
AdaGrad
此前我們都沒有用到二階動量。二階動量的出現(xiàn),才意味著“自適應(yīng)學(xué)習(xí)率”優(yōu)化算法時代的到來。SGD及其變種以同樣的學(xué)習(xí)率更新每個參數(shù),但深度神經(jīng)網(wǎng)絡(luò)往往包含大量的參數(shù),這些參數(shù)并不是總會用得到(想想大規(guī)模的embedding)。對于經(jīng)常更新的參數(shù),我們已經(jīng)積累了大量關(guān)于它的知識,不希望被單個樣本影響太大,希望學(xué)習(xí)速率慢一些;對于偶爾更新的參數(shù),我們了解的信息太少,希望能從每個偶然出現(xiàn)的樣本身上多學(xué)一些,即學(xué)習(xí)速率大一些。
?
怎么樣去度量歷史更新頻率呢?那就是二階動量——該維度上,迄今為止所有梯度值的平方和:
我們再回顧一下步驟3中的下降梯度:
可以看出,此時實(shí)質(zhì)上的學(xué)習(xí)率由??變成了??。 一般為了避免分母為0,會在分母上加一個小的平滑項(xiàng)。因此?是恒大于0的,而且參數(shù)更新越頻繁,二階動量越大,學(xué)習(xí)率就越小。
?
這一方法在稀疏數(shù)據(jù)場景下表現(xiàn)非常好。但也存在一些問題:因?yàn)?是單調(diào)遞增的,會使得學(xué)習(xí)率單調(diào)遞減至0,可能會使得訓(xùn)練過程提前結(jié)束,即便后續(xù)還有數(shù)據(jù)也無法學(xué)到必要的知識。
?
AdaDelta / RMSProp
?
由于AdaGrad單調(diào)遞減的學(xué)習(xí)率變化過于激進(jìn),我們考慮一個改變二階動量計(jì)算方法的策略:不累積全部歷史梯度,而只關(guān)注過去一段時間窗口的下降梯度。這也就是AdaDelta名稱中Delta的來歷。
?
修改的思路很簡單。前面我們講到,指數(shù)移動平均值大約就是過去一段時間的平均值,因此我們用這一方法來計(jì)算二階累積動量:
這就避免了二階動量持續(xù)累積、導(dǎo)致訓(xùn)練過程提前結(jié)束的問題了。
?
Adam
?
談到這里,Adam和Nadam的出現(xiàn)就很自然而然了——它們是前述方法的集大成者。我們看到,SGD-M在SGD基礎(chǔ)上增加了一階動量,AdaGrad和AdaDelta在SGD基礎(chǔ)上增加了二階動量。把一階動量和二階動量都用起來,就是Adam了——Adaptive + Momentum。
?
SGD的一階動量:
加上AdaDelta的二階動量:
?
優(yōu)化算法里最常見的兩個超參數(shù)??就都在這里了,前者控制一階動量,后者控制二階動量。
?
Nadam
?
最后是Nadam。我們說Adam是集大成者,但它居然遺漏了Nesterov,這還能忍?必須給它加上,按照NAG的步驟1:
這就是Nesterov + Adam = Nadam了。
?
說到這里,大概可以理解為什么j經(jīng)常有人說 Adam / Nadam 目前最主流、最好用的優(yōu)化算法了。新手上路,先拿來一試,收斂速度嗖嗖滴,效果也是杠杠滴。
?
那為什么Adam還老招人黑,被學(xué)術(shù)界一頓鄙夷?難道只是為了發(fā)paper灌水嗎?
?
請繼續(xù)閱讀:
Adam那么棒,為什么還對SGD念念不忘 (2)—— Adam的兩宗罪
Adam那么棒,為什么還對SGD念念不忘 (3)—— 優(yōu)化算法的選擇與使用策略
?
————————————————————
補(bǔ)充:指數(shù)移動平均值的偏差修正
?
前面我們講到,一階動量和二階動量都是按照指數(shù)移動平均值進(jìn)行計(jì)算的:
實(shí)際使用過程中,參數(shù)的經(jīng)驗(yàn)值是
初始化:
這個時候我們看到,在初期,??都會接近于0,這個估計(jì)是有問題的。因此我們常常根據(jù)下式進(jìn)行誤差修正:
?
————————————————————
行有所思,學(xué)有所得,陋鄙之言,請多指教。
歡迎關(guān)注我的微信公眾號 Julius-AI
總結(jié)
以上是生活随笔為你收集整理的一个框架看懂优化算法之异同 SGD/AdaGrad/Adam的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Adam那么棒,为什么还对SGD念念不忘
- 下一篇: Adam那么棒,为什么还对SGD念念不忘