為什麼Adam常常打不過SGD?癥結點與改善方案
為什麼Adam常常打不過SGD?癥結點與改善方案
對於做deep learning的人,Adam是個令人又愛又恨的優化器。Adam擁有收斂速度快、調參容易的優點,卻也存在時常被人攻擊的泛化性與收斂問題。因此,在許多論文中實驗會使用傳統的SGD+momentum來做分析。但實際上Adam並非不堪用,仍然有不少大名鼎鼎的模型使用,包含Transformer與BigGAN等。
這篇文章會先介紹Adam與Adam最常被攻擊的兩大癥結點,就Adam的實際問題產生原因作分析,並分享幾個改進方案。除了討論Adam問題以外,再這篇文章也會給一些調用Adam的經驗談。
本篇文章 keywords: Adam, RMSProp, SGD, momentum, AMSGrad, AdaBound, AdamW, RAdam, RANGER, SWATS, Lookahead, Nadam, L2 regulization, weight decay, learning rate scheduling, warm up.
Adam方法與其概論問題
相信看大部分讀這篇文章的人都對Adam 不陌生了,基於我對Adam的理解,我會這樣描述Adam:在RMSProp的基礎上結合momentum的概念 (反過來說也可以啦),並且透過額外的超參數 (beta1、beta2、epsilon) 使其穩定化,在於初始化或是連續遇到小的gradient時,可以參數更新更穩定。
在討論模型泛化能力時,我們會希望模型找到的minimum是一個比較平緩 (flat) 、而非陡峭 (sharp) 的位置,而原因可以很直接地從下圖看出來。一般來說real world或testing set應該與training set相當接近,但有一定的小小的差距,如果我們找到的minimum是sharp的,就很容易造成相當大的誤差。
以上的說法是個很好理解的方式,但其實我們也無法直接證明Adam總是找到sharp minimum。不過相當多的論文指出或討論了Adam在testing時error較大的事實。
以上提供兩篇論文 (上圖+文章封面圖) 的實驗結果,Adam的training時確實收斂速度快,但在testing時造成的誤差卻都比training時差上許多。
Adam另一個被大量攻擊的點是在某些情況會無法收斂,最知名的論點之一是2018 ICLR的best paper:On the Convergence of Adam and Beyond ,論文中設計的特殊例子會使得Adam無法收斂。
不過個人認為Adam無法收斂的問題其實相當稀少,而且即使產生無法收斂的狀況,問題是很相當明顯的,真正對於開發者或研究人員的困擾是可能在測試集或真實環境表現稍差的狀況。
Adam Troubleshooting
Adam作為目前(2020)最主流的自適學習率 (adaptive learning rate) 方法,快速收斂、調參容易是他最大的優勢。而收斂問題與泛化問題則是一直不如SGDM的結果。目前筆者的認知,相當合理的討論為:weight decay與訓練後期不穩定的optimization step。
AdamW 觀察到了一個小小的細節:在Adam這類自適學習率的optimizer下,加入L2 regularization不等價於weight decay。一般情況下,weight decay是對所有的weights採用相同的係數進行更新,本身比較大的一些權重對應的梯度也會比較大,那麼penalty也會越大。但由於Adam會透過除以梯度平方的累積調整步長,這導原本大的weights實際得到的penalty與weight decay不同。AdamW在這篇調整了計算regularization term的位置,讓Adam的weight decay與SGD這類optimizer的行為一致。
其實AdamW投稿過程崎嶇,多次被拒,整體影響力目前也不算大。不過個人認為整體論文方法簡單,而且帶來令人眼睛為之一亮的實驗結果。 Adam一作 Durk Kingma和 Kaggle知名的 Jeremy Howard都在Twitter用相當浮誇的用詞稱讚這篇論文,當時是 2017年,最終論文在 2019才被 accepted。
由於Adam容易在後期產生泛化性的優化結果,於是許多研究方向開始觀察Adam在training的後期發生了什麼事。一般來說,訓練模型到後期大部分時間gradient都會很小,可能上千上萬個batch中只有幾個batch有比較大的gradient,但依照Adam的算法,這些大的gradient影響力卻會不如那些大量的小gradient。
AMSGrad 即是2018 ICLR打Adam打到爆的那篇best paper所提出的改良方法。基於上面描述的問題,AMSGrad僅僅在二次動量的v上增加了一個取捨,在更新v時選擇保留較大的v,如此一來,v只會一路變大,永遠不會不會變小。這聽起來有點難以理解改善在哪,其實只要把AMSGrad用AdaGrad角度來看就相當好理解,AMSGrad這樣的設計會讓optimizer記住一路上大的gradient,因此在訓練的後期不會因為一堆小的gradient盲走很多錯誤的路。
摁~這不就回到 AdaGrad的思路,一樣會遭受 AdaGrad的所有問題?確實是如此,AMSGrad雖然在論文的特殊實驗條件下解決了 Adam不收斂問題,但實務上大部分人卻發現了 AMSGrad並不會帶來更穩定的 testing結果。不過總體上,對這篇關於訓練後期的討論,我是大致信服的。
題外話一談,如果讓大 gradient的樣本影響力等同或大於一堆小 gradient的累積,是不是也代表了對 training data中 outlier抵抗力下降?不過這樣子解釋 Adam與 testing結果也是對不起來。或許之後會有關於這個方向的研究吧!
除了上述兩點,這邊會再介紹一些改進Adam,不過論點沒有完全說服筆者、與一些並不是針對Adam,卻可引薦使用的方法。
要認真討論learning rate scheduling大概又可以寫一篇完整文章,這邊想介紹的就是簡單的warm-up加上decay (annealing)。learning rate scheduling其實是所有optimizer都適合採用的技巧,Warm-up指的是不要一開始就使用高的learning rate,應該要從低慢慢長到base learning rate。而decay則是隨著optimization的步數累加,降低learning rate。
Decay的部分大概很容易理解,藉由調小learning rate將model調整到較平緩穩定的狀態。而warm-up就有點弔詭了,最早可以在ResNet的論文中就看到蹤跡,但整體上是個大家默認有效,卻沒有單獨分析討論的論文。我個人認為比較直覺的是RAdam 論文中下圖的這段討論,透過gradient解釋了一開始訓練的不確定性 (instability)。
而RAdam 則是在warm up的時候提出了一些有效的策略,透過近似v的variance,減少前期因樣本數不足而造成的訓練誤差。
實際上RAdam在訓練開始時因為無法近似v的variance,是不能直接使用RAdam或是Adam的,而取代方案是先從SGDM開始,再可以近似後再切換到RAdam。而這邊剛好與SWATS概念有點相似卻相反,SWATS是從Adam開始,訓練到後期切換成SGDM。而兩個方法在切換時都有一些criteria與learning rate adaption的技巧,有興趣的人可以交互看一下。
Lookahead 與其他optimizer是個很平行的思路,源自Hinton以前slow weights與fast weights的研究,論文作者群中包含Hinton與Adam作者Jimmy Ba,算是最佳化理論中的黃金陣容。這篇論文是這樣做的:先讓fast weights走k步,再回頭看看slow weights的位置退回去一點。講白話點,就是偷看k步未來的走向,再決定自己要怎麼走。論文在實驗中與SGDM比較得到了不錯的結果,雖然實驗設計有點水分,但這個方法可以直接與任何optimizer組合,而且無須特別調參。
另外,最近網路上廣為流傳一個 RANGER為 lookahead + RAdam,不少網路媒體平台都稱為最強優化器,對這個看法我個人是相當地保留啦。如果有人真的試過很厲害,請務必讓我知道。
AdaBound 論文中描述得很浮誇,論文中以”trains as fast as Adam and as good as SGD”描述自己的方法。AdaBound的作法是把梯度剪裁的想法用在學系率上,也就是學習率剪裁。不過這樣的結果想然而造成了自適學習率方法不再那麼的自適,但或許可以解決一些自適學習率方法更新過大或過小的問題。雖然原論文錄取了ICLR 2019,也有很詳盡的理論分析,個人認為這個方法終究比較適個empirical上的想法,可能有用但也有更多的超參數 (learning rate 上下界) 要調整,某種程度上失去了Adam輕鬆好train的樂趣性。
這邊最後點了Nadam只是一個不得不順便提起的感覺,事實上Nadam可以視為加上Nesterov的Adam,也因此的確有一些人比起使用Adam更加偏好Nadam。不過實際上Nadam並沒有辦法解決Adam的主要問題,只能說是個稍微強化的Adam。
小小結論
一個Adam用起來簡單,討論起來卻落落長。實際上就我個人所知,至今所有已提出的方法,其實都沒有能真正的解決adaptive optimizer泛化性較差的問題,都是在努力減小與SGDM的差距。但在實務上,其實並不是所有case都存在這樣明顯差距,只能說有機會造成這樣的問題。
說實話筆者個人對於Adam還是愛多於恨很多很多,畢竟真的是一個相當好用、快速的優化器。對於一個新的題目產生,還是Adam或AdamW加上learning rate scheduling直接用下去最簡單。畢竟真相可能是永遠不存在一個最強優化器,永遠都是要從任務中挑選適合的那一個。
如果你近期在選擇一個訓練模型prototype的優化器,我依然會推薦Adam、AdamW配上learning rate warm-up & decay,簡單、好實作、不用調太多參數,整體上也經得起考驗,或許也可以輕鬆寫意地加個lookahead做實驗也。不過如果想追求新穎一點的方法,AMSGrad、AdaBound、RAdan也是一個值得嘗試的方法。
這篇文章先討論到這邊。老話一句,Deep Learning領域每年都會有大量高質量的論文產出,說真的要跟緊不是一件容易的事。所以我的觀點可能也會存在瑕疵,若有發現什麼錯誤或值得討論的地方,歡迎回覆文章或來信一起討論 :)