作者|Juliuszh 鏈接 | https://zhuanlan.zhihu.com/juliuszh 本文僅作學(xué)術(shù)分享,,若侵權(quán),請(qǐng)聯(lián)系后臺(tái)刪文處理 機(jī)器學(xué)習(xí)界有一群煉丹師,,他們每天的日常是: 拿來藥材(數(shù)據(jù)),,架起八卦爐(模型),點(diǎn)著六味真火(優(yōu)化算法),就搖著蒲扇等著丹藥出爐了,。 不過,,當(dāng)過廚子的都知道,同樣的食材,,同樣的菜譜,,但火候不一樣了,這出來的口味可是千差萬別,?;鹦×藠A生,火大了易糊,,火不勻則半生半糊,。 機(jī)器學(xué)習(xí)也是一樣,模型優(yōu)化算法的選擇直接關(guān)系到最終模型的性能,。有時(shí)候效果不好,,未必是特征的問題或者模型設(shè)計(jì)的問題,很可能就是優(yōu)化算法的問題,。 說到優(yōu)化算法,,入門級(jí)必從SGD學(xué)起,老司機(jī)則會(huì)告訴你更好的還有AdaGrad/AdaDelta,,或者直接無腦用Adam,。可是看看學(xué)術(shù)界的最新paper,,卻發(fā)現(xiàn)一眾大神還在用著入門級(jí)的SGD,,最多加個(gè)Moment或者Nesterov ,還經(jīng)常會(huì)黑一下Adam,。比如 UC Berkeley的一篇論文就在Conclusion中寫道:
無奈與酸楚之情溢于言表,。 這是為什么呢?難道平平淡淡才是真,? 1 一個(gè)框架回顧優(yōu)化算法首先我們來回顧一下各類優(yōu)化算法。 深度學(xué)習(xí)優(yōu)化算法經(jīng)歷了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 這樣的發(fā)展歷程,。Google一下就可以看到很多的教程文章,,詳細(xì)告訴你這些算法是如何一步一步演變而來的。在這里,,我們換一個(gè)思路,,用一個(gè)框架來梳理所有的優(yōu)化算法,做一個(gè)更加高屋建瓴的對(duì)比,。 首先定義:待優(yōu)化參數(shù): ,,目標(biāo)函數(shù): ,初始學(xué)習(xí)率 ,。 而后,,開始進(jìn)行迭代優(yōu)化,。在每個(gè)epoch :
掌握了這個(gè)框架,,你可以輕輕松松設(shè)計(jì)自己的優(yōu)化算法,。 我們拿著這個(gè)框架,來照一照各種玄乎其玄的優(yōu)化算法的真身,。步驟3,、4對(duì)于各個(gè)算法都是一致的,主要的差別就體現(xiàn)在1和2上,。 SGD先來看SGD,。SGD沒有動(dòng)量的概念,也就是說: 代入步驟3,,可以看到下降梯度就是最簡(jiǎn)單的 SGD最大的缺點(diǎn)是下降速度慢,,而且可能會(huì)在溝壑的兩邊持續(xù)震蕩,停留在一個(gè)局部最優(yōu)點(diǎn),。 SGD with Momentum為了抑制SGD的震蕩,,SGDM認(rèn)為梯度下降過程可以加入慣性。下坡的時(shí)候,,如果發(fā)現(xiàn)是陡坡,,那就利用慣性跑的快一些。SGDM全稱是SGD with momentum,,在SGD基礎(chǔ)上引入了一階動(dòng)量: 一階動(dòng)量是各個(gè)時(shí)刻梯度方向的指數(shù)移動(dòng)平均值,,約等于最近 個(gè)時(shí)刻的梯度向量和的平均值。 也就是說,,t時(shí)刻的下降方向,,不僅由當(dāng)前點(diǎn)的梯度方向決定,而且由此前累積的下降方向決定,。 的經(jīng)驗(yàn)值為0.9,,這就意味著下降方向主要是此前累積的下降方向,并略微偏向當(dāng)前時(shí)刻的下降方向,。想象高速公路上汽車轉(zhuǎn)彎,,在高速向前的同時(shí)略微偏向,急轉(zhuǎn)彎可是要出事的,。 SGD with Nesterov AccelerationSGD 還有一個(gè)問題是困在局部最優(yōu)的溝壑里面震蕩,。想象一下你走到一個(gè)盆地,四周都是略高的小山,,你覺得沒有下坡的方向,,那就只能待在這里了。可是如果你爬上高地,,就會(huì)發(fā)現(xiàn)外面的世界還很廣闊,。因此,我們不能停留在當(dāng)前位置去觀察未來的方向,,而要向前一步,、多看一步、看遠(yuǎn)一些,。 NAG全稱Nesterov Accelerated Gradient,,是在SGD、SGD-M的基礎(chǔ)上的進(jìn)一步改進(jìn),,改進(jìn)點(diǎn)在于步驟1,。我們知道在時(shí)刻t的主要下降方向是由累積動(dòng)量決定的,自己的梯度方向說了也不算,,那與其看當(dāng)前梯度方向,,不如先看看如果跟著累積動(dòng)量走了一步,那個(gè)時(shí)候再怎么走,。因此,,NAG在步驟1,不計(jì)算當(dāng)前位置的梯度方向,,而是計(jì)算如果按照累積動(dòng)量走了一步,,那個(gè)時(shí)候的下降方向: 然后用下一個(gè)點(diǎn)的梯度方向,與歷史累積動(dòng)量相結(jié)合,,計(jì)算步驟2中當(dāng)前時(shí)刻的累積動(dòng)量,。 AdaGrad此前我們都沒有用到二階動(dòng)量。二階動(dòng)量的出現(xiàn),,才意味著“自適應(yīng)學(xué)習(xí)率”優(yōu)化算法時(shí)代的到來,。SGD及其變種以同樣的學(xué)習(xí)率更新每個(gè)參數(shù),但深度神經(jīng)網(wǎng)絡(luò)往往包含大量的參數(shù),,這些參數(shù)并不是總會(huì)用得到(想想大規(guī)模的embedding),。對(duì)于經(jīng)常更新的參數(shù),我們已經(jīng)積累了大量關(guān)于它的知識(shí),,不希望被單個(gè)樣本影響太大,,希望學(xué)習(xí)速率慢一些;對(duì)于偶爾更新的參數(shù),,我們了解的信息太少,希望能從每個(gè)偶然出現(xiàn)的樣本身上多學(xué)一些,,即學(xué)習(xí)速率大一些,。 怎么樣去度量歷史更新頻率呢?那就是二階動(dòng)量——該維度上,迄今為止所有梯度值的平方和: 我們?cè)倩仡櫼幌虏襟E3中的下降梯度: 可以看出,,此時(shí)實(shí)質(zhì)上的學(xué)習(xí)率由 變成了 ,。一般為了避免分母為0,會(huì)在分母上加一個(gè)小的平滑項(xiàng),。因此 是恒大于0的,,而且參數(shù)更新越頻繁,二階動(dòng)量越大,,學(xué)習(xí)率就越小,。 這一方法在稀疏數(shù)據(jù)場(chǎng)景下表現(xiàn)非常好。但也存在一些問題:因?yàn)?span role='presentation' data-formula='\sqrt{V_t}' data-formula-type='inline-equation'> 是單調(diào)遞增的,,會(huì)使得學(xué)習(xí)率單調(diào)遞減至0,,可能會(huì)使得訓(xùn)練過程提前結(jié)束,即便后續(xù)還有數(shù)據(jù)也無法學(xué)到必要的知識(shí),。 AdaDelta / RMSProp由于AdaGrad單調(diào)遞減的學(xué)習(xí)率變化過于激進(jìn),,我們考慮一個(gè)改變二階動(dòng)量計(jì)算方法的策略:不累積全部歷史梯度,而只關(guān)注過去一段時(shí)間窗口的下降梯度,。這也就是AdaDelta名稱中Delta的來歷,。 修改的思路很簡(jiǎn)單。前面我們講到,,指數(shù)移動(dòng)平均值大約就是過去一段時(shí)間的平均值,,因此我們用這一方法來計(jì)算二階累積動(dòng)量: 這就避免了二階動(dòng)量持續(xù)累積、導(dǎo)致訓(xùn)練過程提前結(jié)束的問題了,。 Adam談到這里,,Adam和Nadam的出現(xiàn)就很自然而然了——它們是前述方法的集大成者。我們看到,,SGD-M在SGD基礎(chǔ)上增加了一階動(dòng)量,,AdaGrad和AdaDelta在SGD基礎(chǔ)上增加了二階動(dòng)量。把一階動(dòng)量和二階動(dòng)量都用起來,,就是Adam了——Adaptive + Momentum,。 SGD的一階動(dòng)量: 加上AdaDelta的二階動(dòng)量: 優(yōu)化算法里最常見的兩個(gè)超參數(shù) 就都在這里了,前者控制一階動(dòng)量,,后者控制二階動(dòng)量,。 Nadam最后是Nadam。我們說Adam是集大成者,,但它居然遺漏了Nesterov,,這還能忍?必須給它加上,,按照NAG的步驟1: 這就是Nesterov + Adam = Nadam了,。 補(bǔ)充:指數(shù)移動(dòng)平均值的偏差修正前面我們講到,,一階動(dòng)量和二階動(dòng)量都是按照指數(shù)移動(dòng)平均值進(jìn)行計(jì)算的: 實(shí)際使用過程中,參數(shù)的經(jīng)驗(yàn)值是 初始化: 這個(gè)時(shí)候我們看到,,在初期,, 都會(huì)接近于0,這個(gè)估計(jì)是有問題的,。因此我們常常根據(jù)下式進(jìn)行誤差修正: 說到這里,,大概可以理解為什么j經(jīng)常有人說 Adam / Nadam 目前最主流、最好用的優(yōu)化算法了,。新手上路,,先拿來一試,收斂速度嗖嗖滴,,效果也是杠杠滴,。 那為什么Adam還老招人黑,被學(xué)術(shù)界一頓鄙夷,?難道只是為了發(fā)paper灌水嗎,? 請(qǐng)繼續(xù)閱讀: 2 Adam的兩宗罪可以看到,一代又一代的研究者們?yōu)榱宋覀兡軣挘▁un)好(hao)金(mo)丹(xing)可謂是煞費(fèi)苦心,。從理論上看,,一代更比一代完善,Adam/Nadam已經(jīng)登峰造極了,,為什么大家還是不忘初心SGD呢,? 舉個(gè)栗子。很多年以前,,攝影離普羅大眾非常遙遠(yuǎn),。十年前,傻瓜相機(jī)開始風(fēng)靡,,游客幾乎人手一個(gè),。智能手機(jī)出現(xiàn)以后,攝影更是走進(jìn)千家萬戶,,手機(jī)隨手一拍,,前后兩千萬,照亮你的美(咦,,這是什么亂七八糟的),。但是專業(yè)攝影師還是喜歡用單反,孜孜不倦地調(diào)光圈,、快門,、ISO、白平衡……一堆自拍黨從不care的名詞,。技術(shù)的進(jìn)步,,使得傻瓜式操作就可以得到不錯(cuò)的效果,,但是在特定的場(chǎng)景下,,要拍出最好的效果,,依然需要深入地理解光線、理解結(jié)構(gòu),、理解器材,。 優(yōu)化算法大抵也如此。在上一篇中,,我們用同一個(gè)框架讓各類算法對(duì)號(hào)入座,。可以看出,,大家都是殊途同歸,,只是相當(dāng)于在SGD基礎(chǔ)上增加了各類學(xué)習(xí)率的主動(dòng)控制。如果不想做精細(xì)的調(diào)優(yōu),,那么Adam顯然最便于直接拿來上手,。 但這樣的傻瓜式操作并不一定能夠適應(yīng)所有的場(chǎng)合。如果能夠深入了解數(shù)據(jù),,研究員們可以更加自如地控制優(yōu)化迭代的各類參數(shù),,實(shí)現(xiàn)更好的效果也并不奇怪。畢竟,,精調(diào)的參數(shù)還比不過傻瓜式的Adam,,無疑是在挑戰(zhàn)頂級(jí)研究員們的煉丹經(jīng)驗(yàn)! 最近,,不少paper開懟Adam,,我們簡(jiǎn)單看看都在說什么: Adam罪狀一:可能不收斂這篇是正在深度學(xué)習(xí)領(lǐng)域頂級(jí)會(huì)議之一 ICLR 2018 匿名審稿中的 On the Convergence of Adam and Beyond,探討了Adam算法的收斂性,,通過反例證明了Adam在某些情況下可能會(huì)不收斂,。 回憶一下上文提到的各大優(yōu)化算法的學(xué)習(xí)率: 其中,SGD沒有用到二階動(dòng)量,,因此學(xué)習(xí)率是恒定的(實(shí)際使用過程中會(huì)采用學(xué)習(xí)率衰減策略,,因此學(xué)習(xí)率遞減)。AdaGrad的二階動(dòng)量不斷累積,,單調(diào)遞增,,因此學(xué)習(xí)率是單調(diào)遞減的。因此,,這兩類算法會(huì)使得學(xué)習(xí)率不斷遞減,,最終收斂到0,模型也得以收斂,。 但AdaDelta和Adam則不然,。二階動(dòng)量是固定時(shí)間窗口內(nèi)的累積,,隨著時(shí)間窗口的變化,遇到的數(shù)據(jù)可能發(fā)生巨變,,使得 可能會(huì)時(shí)大時(shí)小,,不是單調(diào)變化。這就可能在訓(xùn)練后期引起學(xué)習(xí)率的震蕩,,導(dǎo)致模型無法收斂,。 這篇文章也給出了一個(gè)修正的方法。由于Adam中的學(xué)習(xí)率主要是由二階動(dòng)量控制的,,為了保證算法的收斂,,可以對(duì)二階動(dòng)量的變化進(jìn)行控制,避免上下波動(dòng),。 通過這樣修改,,就保證了 ,從而使得學(xué)習(xí)率單調(diào)遞減,。 Adam罪狀二:可能錯(cuò)過全局最優(yōu)解深度神經(jīng)網(wǎng)絡(luò)往往包含大量的參數(shù),,在這樣一個(gè)維度極高的空間內(nèi),非凸的目標(biāo)函數(shù)往往起起伏伏,,擁有無數(shù)個(gè)高地和洼地,。有的是高峰,通過引入動(dòng)量可能很容易越過,;但有些是高原,,可能探索很多次都出不來,于是停止了訓(xùn)練,。 近期Arxiv上的兩篇文章談到這個(gè)問題,。 第一篇就是前文提到的吐槽Adam最狠的 The Marginal Value of Adaptive Gradient Methods in Machine Learning 。文中說到,,同樣的一個(gè)優(yōu)化問題,,不同的優(yōu)化算法可能會(huì)找到不同的答案,但自適應(yīng)學(xué)習(xí)率的算法往往找到非常差的答案,。他們通過一個(gè)特定的數(shù)據(jù)例子說明,,自適應(yīng)學(xué)習(xí)率算法可能會(huì)對(duì)前期出現(xiàn)的特征過擬合,后期才出現(xiàn)的特征很難糾正前期的擬合效果,。 另外一篇是 Improving Generalization Performance by Switching from Adam to SGD,,進(jìn)行了實(shí)驗(yàn)驗(yàn)證。他們CIFAR-10數(shù)據(jù)集上進(jìn)行測(cè)試,,Adam的收斂速度比SGD要快,,但最終收斂的結(jié)果并沒有SGD好。他們進(jìn)一步實(shí)驗(yàn)發(fā)現(xiàn),,主要是后期Adam的學(xué)習(xí)率太低,,影響了有效的收斂,。他們?cè)囍鴮?duì)Adam的學(xué)習(xí)率的下界進(jìn)行控制,發(fā)現(xiàn)效果好了很多,。 于是他們提出了一個(gè)用來改進(jìn)Adam的方法:前期用Adam,,享受Adam快速收斂的優(yōu)勢(shì);后期切換到SGD,,慢慢尋找最優(yōu)解,。這一方法以前也被研究者們用到,不過主要是根據(jù)經(jīng)驗(yàn)來選擇切換的時(shí)機(jī)和切換后的學(xué)習(xí)率,。這篇文章把這一切換過程傻瓜化,給出了切換SGD的時(shí)機(jī)選擇方法,,以及學(xué)習(xí)率的計(jì)算方法,,效果看起來也不錯(cuò)。 到底該用Adam還是SGD,?所以,,談到現(xiàn)在,到底Adam好還是SGD好,?這可能是很難一句話說清楚的事情,。去看學(xué)術(shù)會(huì)議中的各種paper,用SGD的很多,,Adam的也不少,,還有很多偏愛AdaGrad或者AdaDelta??赡苎芯繂T把每個(gè)算法都試了一遍,,哪個(gè)出來的效果好就用哪個(gè)了。 而從這幾篇怒懟Adam的paper來看,,多數(shù)都構(gòu)造了一些比較極端的例子來演示了Adam失效的可能性,。這些例子一般過于極端,實(shí)際情況中可能未必會(huì)這樣,,但這提醒了我們,,**理解數(shù)據(jù)對(duì)于設(shè)計(jì)算法的必要性。**優(yōu)化算法的演變歷史,,都是基于對(duì)數(shù)據(jù)的某種假設(shè)而進(jìn)行的優(yōu)化,,那么某種算法是否有效,就要看你的數(shù)據(jù)是否符合該算法的胃口了,。 算法固然美好,,數(shù)據(jù)才是根本。 另一方面,,Adam之流雖然說已經(jīng)簡(jiǎn)化了調(diào)參,,但是并沒有一勞永逸地解決問題,,默認(rèn)參數(shù)雖然好,但也不是放之四海而皆準(zhǔn),。因此,,在充分理解數(shù)據(jù)的基礎(chǔ)上,依然需要根據(jù)數(shù)據(jù)特性,、算法特性進(jìn)行充分的調(diào)參實(shí)驗(yàn),,找到自己煉丹的最優(yōu)解。而這個(gè)時(shí)候,,不論是Adam,,還是SGD,于你都不重要了,。 少年,,好好煉丹吧。 關(guān)于優(yōu)化算法的選擇和tricks,,歡迎繼續(xù)閱讀: 3 優(yōu)化算法的選擇與使用策略上文中,,我們用一個(gè)框架梳理了各大優(yōu)化算法,并且指出了以Adam為代表的自適應(yīng)學(xué)習(xí)率優(yōu)化算法可能存在的問題,。那么,,在實(shí)踐中我們應(yīng)該如何選擇呢? 下文介紹Adam+SGD的組合策略,,以及一些比較有用的tricks,。 不同優(yōu)化算法的核心差異:下降方向從第一篇的框架中我們看到,不同優(yōu)化算法最核心的區(qū)別,,就是第三步所執(zhí)行的下降方向: 這個(gè)式子中,,前半部分是實(shí)際的學(xué)習(xí)率(也即下降步長(zhǎng)),后半部分是實(shí)際的下降方向,。SGD算法的下降方向就是該位置的梯度方向的反方向,,帶一階動(dòng)量的SGD的下降方向則是該位置的一階動(dòng)量方向。自適應(yīng)學(xué)習(xí)率類優(yōu)化算法為每個(gè)參數(shù)設(shè)定了不同的學(xué)習(xí)率,,在不同維度上設(shè)定不同步長(zhǎng),,因此其下降方向是縮放過(scaled)的一階動(dòng)量方向。 由于下降方向的不同,,可能導(dǎo)致不同算法到達(dá)完全不同的局部最優(yōu)點(diǎn),。 An empirical analysis of the optimization of deep network loss surfaces這篇論文中做了一個(gè)有趣的實(shí)驗(yàn),他們把目標(biāo)函數(shù)值和相應(yīng)的參數(shù)形成的超平面映射到一個(gè)三維空間,,這樣我們可以直觀地看到各個(gè)算法是如何尋找超平面上的最低點(diǎn)的,。 上圖是論文的實(shí)驗(yàn)結(jié)果,橫縱坐標(biāo)表示降維后的特征空間,區(qū)域顏色則表示目標(biāo)函數(shù)值的變化,,紅色是高原,,藍(lán)色是洼地。他們做的是配對(duì)兒實(shí)驗(yàn),,讓兩個(gè)算法從同一個(gè)初始化位置開始出發(fā),,然后對(duì)比優(yōu)化的結(jié)果??梢钥吹?,幾乎任何兩個(gè)算法都走到了不同的洼地,他們中間往往隔了一個(gè)很高的高原,。這就說明,,不同算法在高原的時(shí)候,選擇了不同的下降方向,。 Adam+SGD 組合策略正是在每一個(gè)十字路口的選擇,,決定了你的歸宿。如果上天能夠給我一個(gè)再來一次的機(jī)會(huì),,我會(huì)對(duì)那個(gè)女孩子說:SGD! 不同優(yōu)化算法的優(yōu)劣依然是未有定論的爭(zhēng)議話題,。據(jù)我在paper和各類社區(qū)看到的反饋,,主流的觀點(diǎn)認(rèn)為:Adam等自適應(yīng)學(xué)習(xí)率算法對(duì)于稀疏數(shù)據(jù)具有優(yōu)勢(shì),且收斂速度很快,;但精調(diào)參數(shù)的SGD(+Momentum)往往能夠取得更好的最終結(jié)果,。 那么我們就會(huì)想到,可不可以把這兩者結(jié)合起來,,先用Adam快速下降,,再用SGD調(diào)優(yōu),一舉兩得,?思路簡(jiǎn)單,,但里面有兩個(gè)技術(shù)問題:
上文中提到的論文 Improving Generalization Performance by Switching from Adam to SGD 提出了解決這兩個(gè)問題的思路。 首先來看第二個(gè)問題,切換之后用什么樣的學(xué)習(xí)率,。Adam的下降方向是 而SGD的下降方向是 . 必定可以分解為 所在方向及其正交方向上的兩個(gè)方向之和,,那么其在 方向上的投影就意味著SGD在Adam算法決定的下降方向上前進(jìn)的距離,而在 的正交方向上的投影是 SGD 在自己選擇的修正方向上前進(jìn)的距離,。 圖片來自原文,這里p為Adam下降方向,,g為梯度方向,,r為SGD的學(xué)習(xí)率。 如果SGD要走完Adam未走完的路,,那就首先要接過Adam的大旗——沿著 方向走一步,,而后在沿著其正交方向走相應(yīng)的一步。 這樣我們就知道該如何確定SGD的步長(zhǎng)(學(xué)習(xí)率)了——SGD在Adam下降方向上的正交投影,,應(yīng)該正好等于Adam的下降方向(含步長(zhǎng)),。也即: 解這個(gè)方程,我們就可以得到接續(xù)進(jìn)行SGD的學(xué)習(xí)率: 為了減少噪聲影響,,作者使用移動(dòng)平均值來修正對(duì)學(xué)習(xí)率的估計(jì): 這里直接復(fù)用了Adam的 參數(shù),。 然后來看第一個(gè)問題,何時(shí)進(jìn)行算法的切換,。 作者的回答也很簡(jiǎn)單,,那就是當(dāng) SGD的相應(yīng)學(xué)習(xí)率的移動(dòng)平均值基本不變的時(shí)候,即: . 每次迭代玩都計(jì)算一下SGD接班人的相應(yīng)學(xué)習(xí)率,,如果發(fā)現(xiàn)基本穩(wěn)定了,,那就SGD以 為學(xué)習(xí)率接班前進(jìn)。 優(yōu)化算法的常用tricks最后,,分享一些在優(yōu)化算法的選擇和使用方面的一些tricks,。
這里只列舉出一些在優(yōu)化算法方面的trick,,如有遺漏,,歡迎各位在評(píng)論中補(bǔ)充,我將持續(xù)更新此文,。提前致謝,! |
|