比Momentum更快:揭開Nesterov Accelerated Gradient的真面目
轉自:https://zhuanlan.zhihu.com/p/22810533
作為一個調參狗,每天用着深度學習框架提供的各種優化算法如Momentum、AdaDelta、Adam等,卻對其中的原理不甚清楚,這樣和一條咸魚有什么分別!(誤)
但是我又懶得花太多時間去看每個優化算法的原始論文,幸運的是,網上的大神早就已經幫人總結好了:《An overview of gradient descent optimization algorithms》,
看完了這篇文章,總算可以說對自己平時用的工具有一個大概的了解啦!
文章的內容包括了Momentum、Nesterov Accelerated Gradient、AdaGrad、AdaDelta和Adam,在這么多個優化算法里面,一個妖艷的賤貨(划去)成功地引起了我的注意——Nesterov Accelerated
Gradient,簡稱NAG。原因不僅僅是它名字比別人長,而且還帶了個逼格很高、一聽就像是個數學家的人名,還因為,它僅僅是在Momentum算法的基礎上做了一點微小的工作,
形式上發生了一點看似無關痛癢的改變,卻能夠顯著地提高優化效果。為此我折騰了一個晚上,終於扒開了它神秘的面紗……(主要是我推導公式太慢了……)
話不多說,進入正題,首先簡要介紹一下Momentum和NAG,但是本文無恥地假設你已經懂了Momentum算法,如果不懂的話,強烈推薦這篇專欄:
《路遙知馬力——Momentum - 無痛的機器學習 - 知乎專欄》,本文的實驗代碼也是在這篇專欄的基礎上改的。
Momentum改進自SGD算法,讓每一次的參數更新方向不僅僅取決於當前位置的梯度,還受到上一次參數更新方向的影響:
其中,和
分別是這一次和上一次的更新方向,
表示目標函數在
處的梯度,超參數
是對上一次更新方向的衰減權重,所以一般是0到1之間,
是學習率。
總的來說,在一次迭代中總的參數更新量包含兩個部分,第一個是由上次的更新量得到的,第二個則是由本次梯度得到的
。
所以Momentum的想法很簡單,就是多更新一部分上一次迭代的更新量,來平滑這一次迭代的梯度。從物理的角度上解釋,就像是一個小球滾落的時候會受到自身歷史動量的影響,
所以才叫動量(Momentum)算法。這樣做直接的效果就是使得梯度下降的的時候轉彎掉頭的幅度不那么大了,於是就能夠更加平穩、快速地沖向局部最小點:
圖片引自《 An overview of gradient descent optimization algorithms》
然后NAG就對Momentum說:“既然我都知道我這一次一定會走的量,那么我何必還用現在這個位置的梯度呢?我直接先走到
之后的地方,
然后再根據那里的梯度再前進一下,豈不美哉?”所以就有了下面的公式:
公式2,NAG的原始形式
跟上面Momentum公式的唯一區別在於,梯度不是根據當前參數位置,而是根據先走了本來計划要走的一步后,達到的參數位置
計算出來的。
對於這個改動,很多文章給出的解釋是,能夠讓算法提前看到前方的地形梯度,如果前面的梯度比當前位置的梯度大,那我就可以把步子邁得比原來大一些,
如果前面的梯度比現在的梯度小,那我就可以把步子邁得小一些。這個大一些、小一些,都是相對於原來不看前方梯度、只看當前位置梯度的情況來說的。
但是我個人對這個解釋不甚滿意。你說你可以提前看到,但是我下次到了那里之后不也照樣看到了嗎?最多比你落后一次迭代的時間,真的會造成非常大的差別?
可是實驗結果就是表明,NAG收斂的速度比Momentum要快:
圖片引自《 路遙知馬力——Momentum - 無痛的機器學習 - 知乎專欄》,上圖是Momentum的優化軌跡,下圖是NAG的優化軌跡
為了從另一個角度更加深入地理解這個算法,我們可以對NAG原來的更新公式進行變換,得到這樣的等效形式(具體推導過程放在最后啦):
公式3,NAG的等效形式
這個NAG的等效形式與Momentum的區別在於,本次更新方向多加了一個,它的直觀含義就很明顯了:如果這次的梯度比上次的梯度變大了,
那么有理由相信它會繼續變大下去,那我就把預計要增大的部分提前加進來;如果相比上次變小了,也是類似的情況。這樣的解釋聽起來好像和原本的解釋一樣玄,
但是讀者可能已經發現了,這個多加上去的項不就是在近似目標函數的二階導嘛!所以NAG本質上是多考慮了目標函數的二階導信息,怪不得可以加速收斂了!
其實所謂“往前看”的說法,在牛頓法這樣的二階方法中也是經常提到的,比喻起來是說“往前看”,數學本質上則是利用了目標函數的二階導信息。
那么,變換后的形式真的與NAG的原始形式等效么?在給出數學推導之前,先讓我用實驗來說明吧:
上圖是公式3給出的優化軌跡,下圖是公式2給出的優化軌跡——完全一樣
實驗代碼放在Github,修改自《路遙知馬力——Momentum - 無痛的機器學習 - 知乎專欄》的實驗代碼。有興趣的讀者可以多跑幾個起始點+學習率+衰減率的超參數組合,
無論如何兩個算法給出的軌跡都會是一樣的。
最后給出NAG的原始形式到等效形式的推導。由
可得
記
上式代入上上式,就得到了NAG等效形式的第二個式子:
對展開可得
於是我們可以寫出的形式,然后用
減去
消去后面的無窮多項,就得到了NAG等效形式的第一個式子:
最終我們就得到了NAG的等效形式:
結論:在原始形式中,Nesterov Accelerated Gradient(NAG)算法相對於Momentum的改進在於,以“向前看”看到的梯度而不是當前位置梯度去更新。
經過變換之后的等效形式中,NAG算法相對於Momentum多了一個本次梯度相對上次梯度的變化量,這個變化量本質上是對目標函數二階導的近似。
由於利用了二階導的信息,NAG算法才會比Momentum具有更快的收斂速度。
本文實驗代碼放在Github