深度學習優化演算法入門:一、梯度下降
來源:paperspace
編譯:weakish
編者按:DRDO研究人員Ayoosh Kathuria深入淺出地介紹了梯度下降這一概念。
深度學習在很大程度上是在解決大規模的煩人的優化問題。神經網路不過是一個包含數百萬引數的非常複雜的函式。考慮影象分類的例子。AlexNet是一個數學函式,接受表示影象的RGB值的陣列作為輸入,產生一組分類評分作為輸出。
我們所說的訓練神經網路,基本上是指最小化一個損失函式。損失函式的值為我們提供了網路在給定資料集上的表現離完美有多遠的測度。
損失函式
為了簡化問題,假定我們的網路只有兩個引數。在實踐中,網路可能有上億引數,不過在本文中,我們將一直使用兩個引數的網路作為例子,以便視覺化。一個非常好的損失函式的等值曲面看起來可能是這樣。

為什麼我要說非常好的損失函式?因為具備上圖這樣的等值曲面的損失函式就像聖人一樣,基本上是不存在的。不過,它在教學上能起到很好的作用,可以幫助我們理解梯度下降最重要的一些想法。所以,讓我們開始吧!
圖中的x軸和y軸表示兩個權重的值。z軸表示損失函式的值。我們的目標是找到損失值最小的權重值。
剛開始,我們隨機初始化權重,所以神經網路大概就像一個醉漢,將貓的影象識別成人類。也就是下圖中的A點,網路表現很差,損失很高。
我們需要找到一種到達“谷底”B點(損失函式最小值)的方法。我們該怎麼做呢?

梯度下降
初始化權重時,我們在損失曲面的A點。我們首先要做的,是檢查一下,在x-y平面上的所有可能方向中,沿著哪個方向移動能帶來最陡峭的損失值下降。這就是我們需要移動的方向。這一方向恰好是梯度的反方向。梯度,導數的高維表兄弟,為我們提供了最陡峭的上升方向。
下圖可以幫助你理解這一點。在曲面的任一點,可以定義一個正切的平面。在更高維情形下,我們可以定義一個超平面。不過現在還是讓我們保持三維吧。我們在這個平面上有無窮方向,其中正好有一個方向能提供函式最陡峭的上升。這個方向就是梯度的方向。這也正是演算法得名的原因。我們沿著梯度反向下降,所以稱為梯度下降。

現在,有了移動的方向,我們需要決定移動的步幅。這稱為學習率。我們必須仔細選擇學習率,以確保達到最小值。
如果學習率過快,我們可能越過最小值,在谷“脊”不斷反彈,再也到不了最小值。如果學習率過慢,訓練可能過於漫長而不再可行。即便不是這樣,非常低的學習率可能使優化演算法更容易陷入區域性極小值(我們稍後將介紹區域性極小值)。
一旦確定了梯度和學習率,我們開始訓練一步,然後在停留處重新計算梯度,接著重複這一過程。
梯度的方向告訴我們哪個方向有最陡峭的上升,而它的數量則告訴我們最陡峭的上升/下降有多陡。所以,在最小值處,等值曲面幾乎是平的,相應地,梯度幾乎是零。事實上,最小值處的梯度正好是零。


在實踐中,我們也許從未恰好達到最小值,而是在最小值附近的平面區域反覆振盪。在這一區域振盪時,損失幾乎是我們可以達到的最小值,因為我們在實際最小值附近反覆回彈,所以損失值幾乎沒什麼變化。當損失值在預定義的迭代次數(比如,10次或20次)後沒有改善時,我們常常停止迭代。這時我們稱訓練收斂了。
常見誤區
讓我稍稍停頓一下。如果你上網搜尋梯度下降的視覺化影象,你大概會看到從某一點開始,朝向最低點的一條軌跡,就像前面的動畫一樣。然而,這只是一個不精確的示意。實際上,軌跡完全被限制在x-y權重平面上,完全不涉及z軸上的移動。這是因為權重是唯一的自由引數。

x-y平面的每一點表示權重的一種獨特組合,我們想要找到損失值最小的權重組合。
基本等式
描述梯度下降更新規則的基本等式是:

每次迭代均進行這樣的更新。上式中,w是位於x-y平面的權重向量。我們從這個向量減去損失函式在權重上的梯度乘以alpha,學習率。梯度也是一個向量,提供損失函式上升最陡峭的方向。最陡峭下降的方向正好是梯度的反方向,所以我們從權重向量中減去梯度向量。
如果想象向量對你來說有點難,你可以想像梯度下降同時應用於網路的所有權重,按照幾乎一樣的更新規則。唯一的不同是,由於我們現在為每個權重分別應用更新,上式中的梯度替換為梯度向量在表示具體權重的方向上的投影。

我們乘上了學習率,對應我們之前提到的步幅。注意,即使學習率是常數,由於梯度數量(損失曲面的陡峭程度)的變動,步幅仍然會改變。當我們逼近最小值時,梯度逼近零,我們以越來越小的步子邁向最小值。
理論上這很好,因為我們希望演算法在逼近最小值時採用較小的步幅,以免過大的步幅導致越過極小值,並在極小值周圍的谷脊間反覆回彈。
梯度下降中廣泛採用的一項技術是使用可變學習率,而不是固定學習率。剛開始,我們可以接受較大的學習率。之後,隨著訓練進行,我們漸漸接近最小值,這時我們想要放慢學習率。實現這一策略的一種方法是模擬退火,又稱學習率衰減。在這種方法中,學習率在固定數目的迭代之後衰減。
梯度下降的挑戰之一:區域性極小值
好吧,目前為止,梯度下降看起來是一個非常美好的童話。不過我要開始潑涼水了。還記得我之前說過,我們的損失函式是一個非常好的函式,這樣的損失函式並不真的存在?
首先,神經網路是複雜函式,具有大量非線性變換。由此得到的損失函式看起來不像一個很好的碗,只有一處最小值可以收斂。實際上,這種聖人般的損失函式稱為凸函式,而深度網路的損失函式幾乎總是非凸的。事實上,損失函式可能是這樣的:

上圖中有一個梯度為零的區域性極小值。然而,我們知道那不是我們能達到的最低損失(全域性最小值)。如果初始權重位於點A,那麼我們將收斂於區域性極小值,一旦收斂於區域性極小值,梯度下降無法逃離這一陷阱。
梯度下降是由梯度驅動的,而梯度在任何極小值處都是零。區域性極小值,顧名思義,是損失函式在區域性達到最小值的點。而全域性最小值,是損失函式整個定義域上可以達到的最小值。
讓事情更糟的是,損失等值曲面可能更加複雜,實踐中可沒有我們考慮的三維等值曲面。實踐中的神經網路可能有上億權重,相應地,損失函式有上億維度。在那樣的影象上梯度為零的點不知道有多少。
事實上,視覺化這樣的高維函式很難。然而,因為現在有很多極具天賦的人從事深度學習研究,人們找到了以3D形式視覺化損失函式的等值曲面的方法。最近的一篇論文提出了過濾器歸一化(Filter Normalization)技術,本文就不解釋它的具體做法了。我們只要知道,它能夠為我們提供呈現損失函式複雜性的檢視。例如,下圖表示VGG-56深度網路在CIFAR-10資料集上的損失函式:

如你所見,上面遍佈區域性極小值。
梯度下降的挑戰之二:鞍點
我們碰到的另一種問題是鞍點,看起來是這樣的:

之前的圖片中,雙“峰”交匯處也有一個鞍點。
鞍點因形狀像馬鞍而得名。鞍點處,梯度在一個方向(x)上是極小值,在另一個方向上則是極大值。如果沿著x方向的等值曲面比較平,那麼梯度下降會沿著y方向來回振盪,造成收斂於最小值的錯覺。
隨機性是救星!
所以,我們該如何逃離區域性極小值和鞍點,努力收斂於全域性最小值呢?答案是隨機性。
目前為止,我們進行梯度下降時計算的損失函式累加了訓練集中所有可能樣本上的損失。如果我們碰到區域性極小值或鞍點,我們便陷入其中。幫助梯度下降擺脫這些的一種方法是使用隨機梯度下降。
隨機梯度下降並不通過累加所有損失函式計算損失,而是計算隨機取樣(無放回)的樣本的損失。和隨機選取一個樣本的隨機梯度下降不同,我們之前的方法在一個batch內處理所有樣本,因此稱為批量梯度下降。
相應地,隨機梯度下降的更新規則為:

基於“單樣本損失”計算出的梯度,方向和基於“全樣本損失”計算出的梯度可能略有不同。因此,當“全樣本損失”可能將我們推入區域性極小值,或讓我們陷於鞍點時,“單樣本損失”梯度可能指向不同的方向,也許能幫助我們避開區域性極小值和鞍點。
即使我們陷入了“單樣本損失”的區域性極小值,下一個隨機取樣的資料點的“單樣本損失”可能不一樣,讓我們得以繼續移動。
當它真的收斂時,它收斂於根據幾乎所有“單樣本損失”計算得出的最小值。同時,經驗表明,鞍點極為不穩定,小小的輕推可能就足以逃離鞍點。
所以,這是否意味著,在實踐中,我們應該總是進行這樣的單樣本隨機梯度下降?
batch大小
答案是否。儘管理論上,隨機梯度下降也許能為我們提供最好的結果,從算力上看,它是一個不太可行的選項。隨機梯度下降時,我們需要一步一步地計算損失,而在批量梯度下降時,單獨損失的梯度可以平行計算。
因此,我們在這兩種方法之間尋找一個平衡。我們既不使用整個資料集,也不僅僅基於單個樣本構造損失函式,我們使用固定數量的樣本,比如,16、32、128,這稱為mini-batch。之所以稱為mini-batch,是為了區別批量(batch)梯度下降。選擇合適的mini-batch大小,可以確保我們既能有足夠的隨機性以擺脫區域性極小值,又能充分利用並行處理的算力優勢。
重新審視區域性極小值:它們並沒有你想像的那麼糟糕
在你仇視區域性極小值之前,先看下最近的研究吧。最近的研究表明,區域性極小值並不一定不好。在神經網路的損失曲面上,有太多的極小值了。“良好”的區域性極小值表現可能和全域性最小值一樣好。
為什麼我說“良好”?因為我們仍然可能陷入難以預測的訓練樣本導致的“糟糕”的區域性極小值。“良好”的區域性極小值,文獻中常稱為最優區域性極小值,在神經網路的高維損失函式中,可以有相當多個。
另外,許多神經網路進行的是分類任務。如果區域性極小值對應的正確標籤的分值在0.7-0.8之間,而同一樣本全域性最小值對應的正確標籤的分值在0.95-0.98之間,最終得到的輸出分類預測是一樣的。
我們希望極小值具有的性質是它位於較平坦的一邊。為什麼?因為平坦極小值更容易收斂,跳過極小值、在極小值周圍的“谷脊”反覆回彈的概率更低。
更重要的是,預測集的損失曲面一般和訓練集的略有不同。平坦寬闊的極小值,從訓練集到預測集的切換不會改變太多損失,而狹窄的極小值則不然。更平坦的極小值推廣性更好。
重新審視學習率
最近湧現了一堆學習率規劃的研究,以避免收斂於損失曲面的次優極小值。即使使用學習率衰減,仍有可能陷入區域性極小值。傳統上,訓練或者在固定數目的迭代之後結束,或者在損失沒有改善的10個(比方說)迭代後結束(文獻中稱為及早停止)。
更高的學習率也有助於幫助我們在訓練早期逃離區域性極小值。
也有人組合了及早停止和學習率衰減,每次遇到10個損失沒有改善的迭代,就降低學習率,並在學習率低於某個預訂的閾值時停止訓練。
近年來也曾流行週期學習率,緩慢增加學習率,然後降低學習率,迴圈往復。

還有稱為熱重啟隨機梯度下降的技術,基本上就是學習率退火至下界後,還原學習率為原值。
還有不同的學習率衰減的規劃方案,從指數衰減到餘弦衰減。

最近的一篇論文又引入了隨機權重平均的技術。作者研發了一種新方法,首先收斂於一個極小值,快取權重,然後還原到較高的學習率。這一較高的學習率將演算法推離極小值,到損失曲面上的一個隨機點。接著演算法收斂於另一個極小值。重複幾次後,對所有快取的權重取平均,基於平均權重作出預測。

結語
梯度下降就介紹到這裡了。不過我們還漏了一點沒講,如何應對病態曲率。隨機梯度下降的一些擴充套件,如動量、RMSProp、Adam可以用來克服這一問題。
不過我覺得我們介紹的內容對一篇部落格文章來說已經夠多了,剩餘的內容將在另一篇文章中介紹。