SGD和Adam(轉載)

https://blog.csdn.net/weixin_42398658/article/details/84525917

另在一篇文章中,我們介紹了隨機梯度下降的細節以及如何解決陷入局部最小值或鞍點等問題。在這篇文章中,我們看看另一個困擾神經網絡訓練的問題,即病態曲率。

雖然局部最小值和鞍點可以阻止我們的訓練,但是病態曲率可以使訓練減慢到機器學習從業者可能認爲搜索已經收斂到次優極小值的程度。讓我們深入瞭解病理曲率是什麼。

病態曲率
考慮以下損失輪廓。

                                                                           病態曲率

你看,我們在進入以藍色標記的山溝狀區域之前隨機開始。顏色實際上表示損失函數在特定點處的值有多大,紅色表示最大值,藍色表示最小值。我們想要達到最小值點,爲此但需要我們穿過山溝。這個區域就是所謂的病態曲率。理解要爲什麼它被稱爲病態,讓我們深入研究。下圖是病態曲率放大後的圖像,看起來像..

 

要理解這裏發生的事情並不是很難。梯度下降沿着山溝的山脊反彈,向極小的方向移動較慢。這是因爲脊的表面在W1方向上彎曲得更陡峭。

如下圖,考慮在脊的表面上的一個點梯度。該點的梯度可以分解爲兩個分量,一個沿着方向w1,另一個沿着w2。梯度在w1方向上的分量要大得多,因此梯度的方向更靠近w1,而不是朝向w2(最小值位於其上)。

 

通常情況下,我們使用低學習率來應對這樣的反覆振盪,但在病態曲率區域使用低學習率,可能要花很多時間才能達到最小值處。事實上,有論文報告,防止反覆振盪的足夠小的學習率,也許會導致從業者相信損失完全沒有改善,乾脆放棄訓練。

大概,我們需要找到一種方法,首先緩慢地進入病態曲率的平坦底部,然後加速往最小值方向移動。二階導數可以幫助我們來到來到賴這一點一一。

牛頓法
下降梯度的英文一階優化方法。它只考慮損失函數的一階導數而不是較高的導數。這基本上意味着它沒有關於損失函數曲率的線索。它可以判斷損失是否在下降和速度有多快,但無法區分曲線是平面,向上彎曲還是向下彎曲。

上圖三條曲線,紅點處的梯度都是一樣的,但曲率大不一樣。解決方案?考慮二階導數,或者說梯度改變得有多快。

使用二階導數解決這一問題的一個非常流行的技術是牛頓法(Newton's Method)。爲了避免偏離本文的主題,我不會過多探究牛頓法的數學。相反,我將嘗試構建牛頓法的直覺。

牛頓法可以提供向梯度方向移動的理想步幅。由於我們現在具備了損失曲面的曲率信息,步幅可以據此確定,避免越過病態曲率的底部。

牛頓法通過計算海森矩陣做到這一點.Hessian矩陣是損失函數在所有權重組合上的二階導數的矩陣。

黑森州提供了損失曲面每一點上的曲率估計。正曲率意味着隨着我們的移動,損失曲面變得不那麼陡峭了。負曲率則意味着,損失曲面變得越來越陡峭了。

注意,如果這一步的計算結果是負的,那就意味着我們可以切換回原本的算法。這對應於下面梯度變得越來越陡峭的情形。

然而,如果梯度變得越來越平坦,那麼我們也許正向病態曲率的底部移動。這時牛頓算法提供了一個修正過的學習步幅,和曲率成反比。換句話說,如果損失曲面變得不那麼陡峭,學習步幅就下降。 

爲何我們不常使用牛頓法?
你已經看到公式中的海森矩陣了.Hessian矩陣需要我們計算損失函數在所有權重組合上的梯度。也就是說,需要做的計算的數量級是神經網絡所有權重數量的平方。

現代神經網絡架構的參數量可能是數億,計算數億的平方的梯度在算力上不可行。

雖然高階優化方法在算力上不太可行,但二階優化關於納入梯度自身如何改變的想法是可以借鑑的。雖然我們無法準確計算這一信息,但我們可以基於之前梯度的信息使用啓發式算法引導優化過程。(這個大家可以看看神經網絡與機器學習這本書,那裏有詳細的講解,當然需要你擁有很好的數學基礎和理解能力)

隨機梯度下降( Stochastic Gradient Descent,SGD )
SGD的學習原理很簡單就是選擇一條數據,就訓練一條數據,然後修改權值算法過程如下:

隨機梯度下降法:

給定數據集,數據集標記爲:,學習器爲,學習率

          對於迭代足夠多次

                  {

                             1.隨機選擇數據:

                             2.計算損失梯度:

                             3.修改權值: 

                   }

SGD算法在訓練過程中很有可能選擇被標記錯誤的標記數據,或者與正常數據差異很大的數據進行訓練,那麼使用此數據求得梯度就會有很大的偏差,因此SGD在訓練過程中會出現很強的隨機現象。如何解決呢?

可以多選擇幾個數據在一起求梯度和,然求均值,這樣做的好處是即使有某條數據存在嚴重缺陷,也會因爲多條數據的中和而降低其錯誤程度。在上述的的算法中,率學習通常的英文固定的值,但是在實際中,我們通常希望學習率隨着訓練次數增加而減小,減小的原因上面也說了減少振盪,這裏先給出一種調節學習率的公式:

                                              

上面是線性學習率調整規則,通常ķ的取值和訓練次數有關,如果訓練次數爲上百次,則ķ要大於100,而b的值可以粗略的設置爲百分之一的初始學習率,學習率初始值一般作爲超參數進行設置,一般採取嘗試策略。

學習率最小批量梯度下降算法

初始化:

給定數據集,數據集標記爲:,隨機採樣m條數據,訓練週期k,學習率衰減最低值b,學習器爲,初始學習率

訓練:

對於       

        {

             1.隨機採樣幾條數據:

             2.計算採樣數據平均損失梯度:

             3.計算衰減學習率: 

             4.修改權值:

        }

效果如下圖

動量學習法
和SGD一起使用的非常流行的技術稱爲Momentum。動量也不僅使用當前步驟的梯度來指導搜索,而是累積過去步驟的梯度以確定要去的方向。那麼什麼是動量學習法呢?

在物理學中,動量的英文與物體的質量、速度相關的物理量。一般而言,一個物體的動量指的的是這個物體在它運動方向上保持運動的趨勢。動量是矢量這裏我們可以把梯度理解成力,力是有大小和方向的,而且力可以改變速度的大小和方向,並且速度可以累積。這裏把權值理解成速度,當力(梯度)改變時就會有一段逐漸加速或逐漸減速的過程,我們通過引入動量就可以加速我們的學習過程,可以在鞍點處繼續前行,也可以逃離一些較小的局部最優區域下面類比物理學定義這裏的動量:

       物理學中,用變量v表示速度,表明參數在參數空間移動的方向即速率,而代價函數的負梯度表示參數在參數空間移動的力,根據牛頓定律,動量等於質量乘以速度,而在動量學習算法中,我們假設質量的單位爲1,因此速度v就可以直接當做動量了,我們同時引入超參數,其取值在【0,1】範圍之間,用於調節先前梯度(力)的衰減效果,其更新方式爲:

                                                                                                (1)

                                             

根據上面的隨機梯度下降算法給出動量隨機梯度下降算法;

初始化:

給定數據集,數據集標記爲:,,初始速度,隨機採樣m條數據,訓練週期k,學習率衰減最低值b,學習器爲,初始學習率,初始動量參數爲

訓練:

          對於  

              {

                        1.隨機採樣米條數據:

                         2.計算採樣數據平均損失梯度:

                         3.更新速度:

                         4.更新參數:

              }

 在隨機梯度的學習算法中,每一步的步幅都是固定的,而在動量學習算法中,每一步走多遠不僅依賴於本次的梯度的大小還取決於過去的速度。速度v是累積各輪訓練參的梯度,其中越大,依賴以前的梯度越大。假如每輪訓練的梯度方向都是相同的,和小球從斜坡滾落,由於但衰減因子的存在,小球並不會一直加速,而是達到最大速度後開始勻速行駛,這裏假設每輪獲得的梯度都是相同的,那麼速度最大值爲(按照(1)計算可得):

                                                               

從上式可以看到當= 0.9時,最大速度相當於梯度下降的10倍(帶進上式去算可得),通常可取0.5,0.9,0.99,情況一般的調整沒有調整的那麼重要適當。取值即可。

圖形如下:

好到這裏大家懂了動量的學習機理,我們繼續看看那篇博文:

梯度下降的方程式修改如下。

上面的第一個等式就是動量,動量等式由兩部分組成,第一項是上一次迭代的動量,乘以“動量係數”。

 如果我們將v的初始值設置爲0並選擇我們的係數爲0.9,則後續更新方程式將如下所示。

我們看到,後續的更新保留了之前的梯度,但最近的梯度權重更高。

下面我們來看看動量法如何幫助我們緩解病態曲率的問題。下圖中,梯度大多數發生更新在字形方向上,我們將每次更新分解爲W1和W2方向上的兩個分量。如果我們分別累加這些梯度的兩個分量,那麼W1方向上的分量將互相抵消,而W2方向上的分量得到了加強。 

也就是說,基於動量法的更新,積累了W2方向上的分量,清空了W1方向上的分量,從而幫助我們更快地通往最小值。從這個意義上說,動量法也有助於抑制振盪。

動量法同時提供了加速度,從而加快收斂。但你可能想要搭配模擬退火,以免跳過最小值。當我們使用動量優化算法的時候,可以解決小批量SGD優化算法更新幅度擺動大的問題,同時可以使得網絡的收斂速度更快。

在實踐中,動量係數一般初始化爲0.5,並在多個時期後逐漸退火至0.9。

AdaGrad(自適應梯度算法)
前面的隨機梯度和動量隨機梯度算法都是使用全局的學習率,所有的參數都是統一步伐的進行更新的,上面的例子中我們是在二維權值的情況,如果擴展到高維,大家可想而知,我麼你的優化環境將很複雜,比如你走在崎嶇額深山老林林,到處都是坑坑窪窪,如果只是走一步看一步(梯度下降),或者快速奔跑向前(動量學習),那我們可能會摔的頭破血流,怎麼辦呢如果可以針對每個參數設置學習率可能會更好,讓他根據情況進行調整,這裏就先引出自適應梯度下降?

AdaGrad其實很簡單,就是將每一維各自的歷史梯度的平方疊加起來,然後更新的時候除以該歷史梯度值即可。如針對第我個參數,算法如下。

定義首先一個量用於累加梯度的平方,如下:

                                                   

平方的原因是去除梯度符號的干擾,防止抵消,更新時:

                                                  

        其中= 10 ^ -7,防止數值溢出。

從上式可以看出,AdaGrad使的參數在累積的梯度較小時()就會放大學習率,使網絡訓練更加快速。在梯度的累積量較大時()就會縮小學習率,延緩網絡的訓練,簡單的來說,網絡剛開始時學習率很大,當走完一段距離後小心翼翼,這正是我們需要的。但是這裏存在一個致命的問題就是AdaGrad容易受到過去梯度的影響,陷入“過去“無法自拔,因爲梯度很容易就會累積到一個很大的值,此時學習率就會被降低的很厲害,因此AdaGrad很容易過分的降低學習率率使其提前停止,怎麼解決這個問題呢?RMSProp算法可以很好的解決該問題。

RMSProp(均方根支柱)
同樣,RMSProp可以自動調整學習率。還有,RMSProp爲每個參數選定不同的學習率。

雖然AdaGrad在理論上有些較好的性質,但是在實踐中表現的並不是很好,其根本原因就是隨着訓練週期的增長,學習率降低的很快。而RMSProp算法就在AdaGrad基礎上引入了衰減因子,如下式,RMSProp在梯度累積的時候,會對“過去”與“現在”做一個平衡,通過超參數進行調節衰減量,常用的取值爲0.9或者0.5(這一做法和SGD有異曲同工之處)

                                                          

參數更新階段,和AdaGrad相同,學習率除以歷史梯度總和即可。

                                                           

實踐中,RMSProp更新方式對深度學習網絡十分有效,是深度學習的最有效的更新方式之一。

圖形如下:

下面接着那篇博客看,(這裏還是通過動量過來的,原理是一樣的,因爲都是梯度的累加。這裏大家不用迷惑,當你知道本質的東西以後,就知道通過表面看本質的的意義了)

在第一個等式中,類似之前的動量法,我們計算了梯度平方的指數平均。由於我們爲每個參數單獨計算,這裏的梯度GT表示正更新的參數上的梯度投影。

第二個等式根據指數平均決定步幅大小。我們選定一個初始學習率η,接着除以平均數。在我們上面舉的例子中,W1的梯度指數平均比W2大得多,所以W1的學習步幅比W2小得多。這就幫助我們避免了脊間振盪,更快地向最小值移動。

第三個等式不過是權重更新步驟。

上面的等式中,超參數ρ一般定爲0.9,但你可能需要加以調整。等式2中的ε是爲了確保除數不爲零,一般定爲1E-10。

注意RMSProp隱式地應用了模擬退火。在向最小值移動的過程中,RMSProp會自動降低學習步幅,以免跳過最小值。

Adam(自適應動量優化)
到目前爲止,我們已經看到RMSProp和動量採用對比方法。雖然動量加速了我們對最小值方向的搜索,但RMSProp阻礙了我們在振盪方向上的搜索.Adam通過名字我們就可以看出他是基於動量和RMSProp的微調版本,該方法是目前深度學習中最流行的優化方法,在默認情況儘量使用亞當作爲參數的更新方式

首先計算當前最小批量數據梯度。

                                                      

和動量學習法一樣,計算衰減梯度五:

                                                      

和RMSProp算法類似,計算衰減學習率R:

                                                     

最後更新參數:

                                                     

上面就是RMSProp和動量的有機集合,使他們的優點集於一身,是不是很漂亮,但還是有一個問題就是開始時梯度會很小,R和v經常會接近0,因此我們需要初始給他一個?合適的值,這個值怎麼給才合適呢先看下面的公式:

                                               

其中噸表示訓練次數,剛開始動很大,隨着訓練次數噸的增加VB逐漸趨向於V,R類似下面給出總體的算法結構。

初始化:

 給定數據集,數據集標記爲:,初始速度,隨機採樣m條數據,訓練週期k,學習器爲,初始學習率,初始動量參數爲,學習衰減參數,

訓練:

        用於   :

              {

                       1.隨機採樣米條數據:

                       2.計算當前採樣數據的梯度:

                       3.更新當前速度:

                       4.更新當前學習率:

                       5.更新訓練次數: 

                                              

                       6.更新參數:

               }         

 好,我們繼續看看那篇博客:

這裏,我們計算了梯度的指數平均和梯度平方的指數平均(等式1和等式2)。爲了得出學習步幅,等式3在學習率上乘以梯度的平均(類似動量),除以梯度平方平均的均方根(類似RMSProp)。等式4是權重更新步驟。

超參數β1一般取0.9,β2一般取0.99.ε一般定爲1E-10。

結語
本文介紹了三種應對病態曲率同時加速訓練過程的梯度下降方法。

在這三種方法之中,也許動量法用得更普遍,儘管從論文上看Adam更吸引人。經驗表明這三種算法都能收斂到給定損失曲面的不同的最優局部極小值。然而,動量法看起來要比Adam更容易找到比較平坦的最小值,而自適應方法(自動調整學習率)傾向於迅速地收斂於較尖的最小值。比較平坦的最小值概括性更好。

 儘管這些方法有助於我們訓練深度網絡難以控制的損失平面,隨着網絡日益變深,它們開始變得不夠用了。除了選擇更好的優化方法,有相當多的研究試圖尋找能夠生成更平滑的損失曲面的架構。批量歸一化(Batch Normalization)和殘差連接(Residual Connections)正是這方面的兩個例子。我們會在後續的文章中詳細介紹它們。但這篇文章就到此爲止了。歡迎在評論中提問。
————————————————
版權聲明:本文爲CSDN博主「zsffuture」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42398658/article/details/84525917

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章