一文告訴你Adam、AdamW、Amsgrad區別和聯系 重點


**序言:**Adam自2014年出現之后,一直是受人追捧的參數訓練神器,但最近越來越多的文章指出:Adam存在很多問題,效果甚至沒有簡單的SGD + Momentum好。因此,出現了很多改進的版本,比如AdamW,以及最近的ICLR-2018年最佳論文提出的Adam改進版Amsgrad。那么,Adam究竟是否有效?改進版AdamW、Amsgrad與Adam之間存在什么聯系與區別?改進版是否真的比Adam更好呢?相信這篇文章將會給你一個清晰的答案。

(內容翻譯整理自網絡)

Adam Roller-Coaster

Adamoptimizer的發展歷程就像坐過山車一樣。Adam最先於2014年提出,其核心是一個簡單而直觀的想法:當我們知道某些參數確實需要比其他參數移動地更快時,為什么要對每個參數都使用相同的學習速率呢?由於最近的梯度的平方告訴我們可以從每個權重得到多少信息,我們可以除以這一點,以確保即使變化最緩慢的權重也能獲得發光的機會。Adam借鑒了這個思路,在標准方法里面加入了動量,並且(通過一些調整來保持早期Bathes不被biased)就是這樣!

Adam首次發布后,深度學習社區在看到原始論文中的效果圖(下圖)之后,非常的興奮:

 

 

Adam和其他optimizer之間的比較

訓練速度加快了200%!“總的來說,我們發現Adam非常強大,非常適合解決機器學習的各種非凸優化問題” 論文總結道。但是,那是三年前了,是一個深度學習發展的一個黃金epochs。但也漸漸逐漸清晰,這一切並不如我們所希望的那樣。實際情況是,很少有研究論文使用Adam來訓練他們的模型,一些新的研究,如《The Marginal Value of Adaptive Gradient Methods in Machine Learning》建議不要使用Adam,並通過多個實驗中表明,傳統的SGD+momentum的方法得到的結果更好。

但是在2017年底,Adam似乎獲得了新生。Ilya Loshchilov和Frank Hutter在他們的論文《Fixing Weight Decay Regularization in Adam》中指出,所有的深度學習庫中的Adam optimizer中實現的weight decay方法似乎都是錯誤的,並提出了一種簡單的方法(他們稱之為AdamW)來解決它。盡管他們的結果略有不同,但從下圖的效果對比圖中可以發現,結果令人振奮,:

Adam和AdamW的對比

我們當然期待看到Adam的回歸,因為似乎最初的結果可能會再次被發現。但事情並非如此。實際上,所有深度學習框架中,只有fastai,由Sylvain編寫的代碼中的的算法實現修復了這一bug。如果沒有廣泛的框架可用性,大多數人仍舊會被old、“broken”adam所困擾。

但這不是唯一的問題。未來會遇到更多的問題。兩篇相互獨立的論文都明確指出並證明了Adam中存在的收斂性問題,盡管其中一人聲稱修復了這一問題(並獲得了ICLR-2018年的“最佳論文”獎),他們的算法稱為Amsgrad。但是,如果我們是否從這個最具戲劇性的歷史生活中學到了任何東西(至少在optimizer standards上是戲劇性的)呢?看起來似乎並沒有。事實上,博士生Jeremy Bernstein 已經指出,聲稱的收斂問題實際上只是因為超參數的選擇不當導致的,而且無論如何,Amsgrad也許無法解決這一問題。另一名博士生Filip Korzeniowski展示了一些早期的結果,這些結果似乎也支持這種關於Amsgrad的,令人沮喪的觀點。

脫離Roller-coaster

那么對於我們這些只想快速且准確訓練模型的人來說,我們該怎么辦呢?讓我們用經歷數百年時間的,科學的方式來解決這場爭論:通過實驗!我們會在短時間內告訴你所有細節,首先,給出一個結果概述:

· 適當調整,Adam是真的有效!我們在各種任務上都獲得了最新的成績(就訓練時間而言)

o 在DAWNBench競賽中,通訓練CIFAR10達到> 94%的准確度,評測當采用Augmentation時,只需要18個epoch;或不采用Augmentation時,只需要30個epochs;

o 采用Cars Stanford Dataset數據集,訓練60個epochs,fine-tuning Resnet50達到90%的精確度(之前達到相同的結果需要600 epochs);

o 從頭開始訓練AWD LSTM或QRNN,需要90個epochs(或單個GPU上需要1個半小時),在Wikitext-2數據集上的達到state-of-the-art的perplexity(之前的report的對於LSTM需要750個epochs,對於QRNN需要500個epochs)。

· 這意味着我們已經看到(我們第一次意識到)在論文《Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates》使用Adam所獲得的超級收斂效果(Super-Convergence)!超級收斂是在采用較大的學習率訓練神經網絡時發生的一種現象,使訓練速度加快一倍。在了解這一現象之前,將CIFAR10訓練達到94%的准確度大約需要100個epochs。

· 與之前的工作相比,我們看到Adam在我們嘗試過的每個CNN圖像問題上獲得與SGD + Momentum一樣的精確度,只要它經過適當調整,並且它幾乎總是更快一點。

· Amsgrad是一個糟糕的“fix”的這一suggestion是正確的。我們一直發現,與普通的Adam / AdamW相比,Amsgrad在准確度(或其他相關指標)方面沒有獲得任何提升。

當你聽到有人們說Adam沒有像SGD + Momentum那樣generalize的時候,你幾乎總會發現,根本原因使他們為他們的模型選擇了較差的超參數。Adam通常需要比SGD更多的regularization,因此在從SGD切換到Adam時,請務必調整正則化超參數。

以下是本文其余部分的概述:

1 AdamW

1.1 了解AdamW

1.2 實現AdamW

1.3 AdamW實驗的結果

2 Amsgrad

2.1 了解Amsgrad

2.2 實現Amsgrad

2.3 Amsgrad實驗的結果

3 完整結果表

1 AdamW

1.1 了解AdamW:weight decay or L2正規?

L2正則是一種減少過擬合的一種經典方法,它在損失函數中加入對模型所有權重的平方和,乘以給定的超參數(本文中的所有方程都使用python,numpy,和pytorch表示):

final_loss = loss + wd * all_weights.pow(2).sum() / 2

…其中wd是要設置的l2正則的超參數。這也稱為weight decay,因為在應用普通的SGD時,它相當於采用如下所示來更新權重:

w = w - lr * w.grad - lr * wd * w

(注意,w 2相對於w的導數是2w。)在這個等式中,我們看到我們如何在每一步中減去一小部分權重,因此成為衰減。

我們查看過的所有深度學習庫,都使用了第一種形式。(實際上,它幾乎總是通過向gradients中添加wd * w來實現,而不是去改變損失函數:我們不希望在有更簡單的方法時,通過修改損失來增加更多計算量。)

那么為什么要區分這兩個概念,它們是否起到了相同的作用呢?答案是,它們對於vanilla SGD來說是一樣的東西,但只要我們在公式中增加動量項,或者使用像Adam這樣更復雜的一階或二階的optimizer,L2正則化(第一個等式)和權重衰減(第二個等式)就會變得不同。在本文的其余部分,當我們談論weight decay時,我們將始終參考第二個公式(梯度更新時,稍微減輕權重)並談談L2正則化,如果我們想提一下經典的方法。

以SGD + momentum為例。使用L2正則化,並添加wd * w衰減項到公式中(如前所述),但不直接從權重中減去梯度。首先我們計算移動平均值(moving average):

moving_avg = alpha * moving_avg + (1-alpha) * (w.grad + wd*w)

…這個移動平均值將乘以學習率並從w中減去。因此,與將從w取得的正則化相關聯的部分是lr (1-alpha) wd * w加上前一步的moving_avg值。

另一方面,weight decay的梯度更新如下式:

moving_avg = alpha * moving_avg + (1-alpha) * w.grad w = w - lr * moving_avg - lr * wd * w

我們可以看到,從與正則化相關聯的w中減去的部分在兩種方法中是不同的。當使用Adam optimizer時,它會變得更加不同:在L2正則化的情況下,我們將這個wd * w添加到gradients,然后計算gradients及其平方值的移動平均值,然后再使用它們進行梯度更新。而weight decay的方法只是在進行更新,然后減去每個權重。

顯然,這是兩種不同的方法。在嘗試了這個之后,Ilya Loshchilov和Frank Hutter在他們的文章中建議我們應該使用Adam的權重衰減,而不是經典深度學習庫實現的L2正則化方法。

1.2 實現AdamW

我們應該怎么做?基於fastai庫為例,具體來說,如果使用fit函數,只需添加參數 use_wd_sched = True:

learn.fit(lr, 1, wds=1e-4, use_wd_sched=

True)

如果您更喜歡新的API,則可以在每個訓練階段使用參數wd_loss = False(計算損失函數時,不使用weight decay):

phases = [TrainingPhase(1, optim.Adam, lr, wds=1-e4, wd_loss=False)]

learn.fit_opt_sched(phases)

以下給出基於fast庫的一個簡單實現。在optimizer的step函數的內部,只使用gradients來更新參數,根本不使用參數本身的值(除了weight decay,但我們將在外圍處理)。然后我們可以在optimizer處理之前,簡單地執行權重衰減。在計算梯度之后仍然必須進行相同操作(否則會影響gradients值),所以在訓練循環中,你必須找到這個位置。

loss.backward()

#Do the weight decay here!

optimizer.step()

當然,optimizer應該設置為wd = 0,否則它會進行L2正則化,這正是我們現在不想要的。現在,在那個位置,我們必須循環所有參數,並做weight decay更新。你的參數應該都在optimizer的字典param_groups中,因此循環看起來像這樣:

loss.backward()

for group in optimizer.param_groups():

for param in group[‘params’]:

param.data = param.data.add(-wd * group[‘lr’], param.data)

optimizer.step()

1.3 AdamW實驗的結果:它有效嗎?

我們在計算機視覺問題上第一次進行測試得到的結果非常令人驚訝。具體來說,我們采用Adam+L2正規化在30個epochs內獲得的准確率(這是SGD通過去1 cycle policy達到94%准確度所需要的必要時間)的平均為93.96%,其中一半超過了94%。使用Adam + weight decay則達到94%和94.25%之間。為此,我們發現使用1 cycle policy時,beta2的最佳值為0.99。我們將beta1參數視為SGD的動量(意味着它隨着學習率的增長從0.95變為0.85,然后當學習率變低時再回到0.95)。

L2正則化或權重衰減的准確性

更令人印象深刻的是,使用Test Time Augmentation(即對測試集上的一個圖像,取四個和他相同data-augmented版本的預測的平均值作為最終預測結果),我們可以在18個epochs內達到94%的准確率(平均預測值為93.98%) )!通過簡單的Adam和L2正規,超過20個epochs時,達到94%。

在這些比較中要考慮的一件事是,改變我們正則的方式會改變weight decay或學習率的最佳值。在我們進行的測試中,L2正則化的最佳學習率是1e-6(最大學習率為1e-3),而0.3是weight decay的最佳值(學習率為3e-3)。在我們的所有測試中,數量級的差異非常一致,主要原因是,L2正則於梯度的平均范數(相當小)相除后,變得非常有效,且Adam使用的學習速率非常小(因此,weight decay的更新需要更強的系數)。

那么,**使用Adam時,權重衰減總是比L2正規化更好嗎?**我們還沒有發現一個明顯更糟的情況,但對於遷移學習問題或RNN而言(例如在Stanford cars數據集上對Resnet50進行微調),它沒有獲得更好的結果。

2 Amsgrad

2.1 了解Amsgrad

最近 Sashank J. Reddi,Satyen Kale和Sanjiv Kumar 在ICLR-2018的最佳論文《On the Convergence of Adam and Beyond》了中提出了Amsgrad。通過分析Adam optimizer的收斂證明,他們發現更新規則中的存在錯誤,且可能導致算法收斂到sub-optimal point。他們設計了理論實驗,展示了Adam失敗的場景,並提出了一個簡單的解決方案。

為了理解錯誤和修復,讓我們先看看Adam的更新公式:

avg_grads = beta1 * avg_grads + (1-beta1) * w.grad

avg_squared = beta2 * (avg_squared) +

(1-beta2) * (w.grad ** 2)

w = w - lr * avg_grads / sqrt(avg_squ

ared)

我們剛剛忽略了bias項(對訓練開始時很有用),專注於重點。作者發現的Adam的proof中的存在的錯誤是它需要值(quantity)

lr / sqrt(avg_squared)

…這是我們在平均梯度方向上采取的step,隨着訓練過程減少。由於學習率通常是恆定的或降低的(除了像我們這樣,試圖獲得超收斂的瘋狂的人),作者提出的修正是通過添加另一個變量來跟蹤他們的最大值來強制avg_squared值增加。

2.2 實現Amsgrad

相關文章獲得了ICLR 2018的最佳論文獎,並非常受歡迎,以至於它已經在兩個主要的深度學習庫都實現了,pytorch和Keras。除了使用Amsgrad = True打開選項外,幾乎沒有什么可做的。

這將上一節中的權重更新代碼更改為以下內容:

avg_grads = beta1 * avg_grads + (1-beta1) * w.grad

avg_squared = beta2 * (avg_squared) +

(1-beta2) * (w.grad ** 2)

max_squared = max(avg_squared,

max_squared)

w = w - lr * avg_grads / sqrt(max_squ

ared)

2.3 Amsgrad實驗的結果:除了很多噪音意外什么也沒有

事實證明,Amsgrad結果令人失望。在我們的實驗中,沒有一個實驗證明它是有點幫助的,即使確實Amsgrad發現的最小值有時略低於(在損失方面)Adam達到的指標(精度,f1得分) …)最終結果總是惡化(參見我們的introduction,或更多的例子:https://fdlm.github.io/post/amsgrad/

Adam optimizer在深度學習中的收斂性證明(proof of convergence)(因為它是針對凸問題的)以及它們在其中發現的錯誤對於與現實生活中的實際問題無關的合成實驗來說是至關重要的。實際測試表明,當avg_squared gradients想要減少時,最好的結果是這樣做。

這表明,即使關注理論可以獲得一些新想法,但它也不能取代實驗(以及很多實驗!)來確保這些想法能真正幫助從業者訓練出更好的模型。

附錄:完整結果

從頭開始訓練CIFAR10(模型是一個比較寬的resnet 22,最終的結果是五個測試集上測平均錯誤率):

在Stanford Cars數據集上,對Resnet50進行微調(前20個epochs不改變學習率,后40個epochs采用不同的學習率學習):

使用github repo中的超參數訓練AWD LSTM (結果顯示驗證/測試集的perplexity,有或沒有緩存指針(cache pointer)):

QRNN相同,不采用LSTM:

對於這項特定任務,我們使用了1cycle policy的修改版本,更快地增加學習速率,然后在再次下降之前具有更長時間的高恆定學習速率。

Adam和其他optimizer之間的比較

https://github.com/sgugger/Adam-experime

nts提供了所有相關超參數的值以及用於得到這些結果的代碼。

往期精彩內容推薦

COLING 2018-最新論文最全分類-整理分享

AI教父-深度學習之父-Geffery Hinton個人簡介

(精品干貨)ACL 2018最新論文歸類(最全最細)分享

朋友,千萬不能錯過!13個自然語言處理的深度學習框架

最前沿的深度學習論文、架構及資源分享

麻省理工學院(MIT)-2018年最新自動駕駛視頻課程分享

精品推薦-2018年Google官方Tensorflow峰會視頻教程完整版分享

模型匯總24 - 深度學習中Attention Mechanism詳細介紹:原理、分類及應用

深度學習中如何選擇一款合適的GPU卡的一些經驗和建議分享

TensorFlow Dev Summit 2018視頻分享

《模型匯總-20》深度學習背后的秘密:初學者指南-深度學習激活函數大全


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM