理解梯度下降(二)(理論篇)|機器學習你會遇到的「坑」


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


數學準備

  • Hadamard product:矩陣的各個元素對應相乘



理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



一個好的優化算法,一方面要快,即迭代更新的次數越少越好,另一方面計算的代價要小,即利用的信息越少越好。現在我們已經知道這兩者是無法兼得的,梯度下降只需要計算梯度,但在每一步下降只侷限於大小為

理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”

的局部方向,迭代更新的次數較多,而牛頓法這樣的二階優化,利用了Hessian矩陣的信息,預設了梯度為零,使得一般情況下的迭代更新次數更少,但是每次迭代時需要計算樣本的Hessian的逆。

如果我們想在牛頓法的基礎上進一步的減小信息量,就可以考慮BFGS(Broyden-Fletcher-Goldfalb-Shanno)這種著名的擬牛頓法,它並沒有直接計算Hessian的逆,而是採取向量的乘積和矩陣的加法來代替了Hessian,使得計算量進一步下降。但即便這樣我們在深度學習中仍然很少採用它,主要的因素還是模型參數和數據的龐大,空間複雜度太大,內存消耗嚴重。

所以,梯度下降似乎是看起來更好的選擇, 但仍有提升空間。首先,我們在計算梯度時,用了所有的樣本,因為這樣的梯度估計才更準確,但是很多樣本太相似了,比如其他條件均一樣,一個身高為172、體重63kg,另一個身高172.5、體重63.4,這樣的樣本對Loss function的貢獻是相似的,產生的梯度估計也是相似的,我們完全可以採用少且有效的信息去替代冗餘的信息;其次,在實踐中,小批量的梯度下降即便增加了迭代次數,但計算的代價少了,總體的效率仍然很高;最後,隨機的挑選小批量的樣本一定程度上增加了梯度估計的方差(噪聲項),反而使得梯度下降有機會跳出局部最小值,在保證與全樣本梯度下降結果差不多的前提下,有表現更為優異的可能性。

這樣的方法我們叫做隨機梯度下降(Stochastic Gradient Descent),有的人會按照每次梯度更新使用的樣本量,進一步的分為小批量,在線等等,這樣的分類是不必要的,現在通常說隨機,一般就指小批量梯度下降。因為使用單個樣本更新梯度,梯度估計效果會很差,同時無法有效利用多線程操作,我們在此不予討論。

隨機梯度下降參數更新公式就由原來的:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



變為了:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



當使用隨機梯度下降時,原本梯度為零的點一般不會為零,但也會變得很小,所以我們會看到隨機梯度下降並不會停留在極小值(如果存在極小值的話),而是在其附近微小震盪。另外實驗表明,隨機梯度下降會在迭代初期性能遠遠超越全部樣本的梯度下降。

那麼梯度下降能不能更快呢?因為我們可以設想,如果參數的初始值越靠近目標點,那麼優化過程肯定越快,每一步的梯度都積累在同一個方向上,那麼還可以減少很多無謂的迭代,畢竟梯度下降本質上是貪心的。


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


如圖,a和b的參數初始值並不一樣,結果a的梯度下降比b的更快,雖然b的每一步的梯度下降都是此時此刻的最佳的方向,但在整體看來,b把步驟浪費在了等高線附近的來回移動。

但是,一般而言,我們並不知道Loss function的性質,我們無法確定出完美的初始值(實際中,一般都是假設一個正態分佈,或者隨機初始化),換而言之,我們要想方設法將處理更為普遍的情況,儘可能減少在contour附近的來回移動。

動量算法可以緩解這個問題,它引入了一個量叫做速度,用來積累以前的梯度信息:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



這種做法是出於物理上的考慮,Loss function的負梯度就是物理上的勢的負梯度,我們把它叫做力,根據矢量加法,或者做正交分解,就可以直觀的看出,累加的結果就是把每一次力的相同方向加大,而相反的方向相互抵消,使得速度在每次力的相同方向都越來越大,本質上就是對梯度的方向做了歸一化,然後我們選擇利用速度去更新參數:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



讓我們來考慮極端的情況,如果每次的梯度的方向一致,那麼v就會沿著一個方向越來越大,參數a用來調節過去積累梯度與現在梯度的比重,a越大,那麼過去的信息佔得比重越大。同時我們也可以在梯度計算之前就在參數中添加速度項:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



就得到了Nesterov動量算法,簡單來看,並沒有異樣,只是添加的步驟不同,而且在循環中,標準的動量算法遲早都會執行參數更新後的梯度。實際上,如果我們做一個簡單的矢量加法:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


如圖,左圖為普通的動量算法,遵循著矢量加法,其中梯度步驟gradient step並未利用當前的速度,而在Nesterov卻在梯度步驟就利用了速度信息,最終使實際的步驟發生了偏移。

動量算法一定程度上加速了梯度下降,但是卻引入了另一個超參數a,更重要的是,實踐發現,同樣作為超參數,a遠遠沒有學習率

理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”

重要,我們希望不引入額外參數的情況下加速優化,就不得不考慮學習率。我們希望達到的效果是,學習率在梯度很大的時候,變得小一些,不至於錯過極小值,在梯度很小的時候變得大一點,使得在Loss 平坦的地方走的更快。這就是所謂的自適應學習率算法。

梯度越大學習率要越小,一個自然的想法就是用一個量來累計所有的梯度:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



然後在學習率上乘以梯度的倒數,其中

理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”

是非常小的常數,避免分母為零:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



此算法就叫做AdaGrad,簡單實現了梯度越大的地方,學習率越小的目標。但它積累了全部的梯度,使得學習率過早的下降,所以我們還可以給不同時期的梯度賦予權重因子,使得較早的梯度不重要,而較近的梯度更重要:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


這樣就得到了RMSProp算法,在此基礎上,我們希望在梯度項中也加入一些修正,使得當前所使用的梯度還會受到歷史梯度的影響,與動量算法類似:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


最後更新公式也變為:


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”



這就得到了Adam算法的基本形式,裡面包含著兩個超參數,這也是深度學習中最被經常使用的算法。

理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


讀芯君開扒

課堂TIPS

• 隨著數據的增多,有些情況下我們也不得不用單樣本的隨機梯度下降,因為照目前的發展來看,數據規模的增長速度已經超越了計算能力的增速,此外,對訓練集進行分批訓練也變得越來常見。

• 動量算法本質上也在將學習率調節為

理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”

,a越大,速度也就越快,但動量算法有一個明顯的缺點,那就是當速度太快時,無法在極小值附近停下來,這也是制約其發展的因素之一,一般的都是動量算法與其他的自適應算法相結合,可以發揮出最大的效果。

• Adam算法也被人認為是對一階矩和二階矩的偏差修正,但對於初學者來說,更好的理解方式是RMSprop+動量算法,需要注意的是,初期的積累梯度和積累動量趨於零,一般的,我們會對其先進行修正,比如:

理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”


理解梯度下降(二)(理論篇)|機器學習你會遇到的“坑”




分享到:


相關文章: