一文簡述深度學習優化方法——梯度下降

 2018-07-15 20:00:19.0

從很大程度上來說,深度學習實際上是在解決大量煩人的優化問題。神經網絡僅僅是一個非常複雜的函數,包含數百萬個參數,這些參數代表的是一個問題的數學解答。以圖像分類爲例,AlexNet 就是一個數學函數,它以代表圖像 RGB 值的數組爲輸入,生成一組分類得分的輸出。

實質上,通過訓練神經網絡,我們是在最小化一個損失函數。這個損失函數的值衡量了我們網絡的性能在給定數據集上離完美還差多少。

損失函數

簡單起見,假設我們的網絡只有兩個參數。實際上,這個數量是在十億左右,但是我們在這篇文章中會堅持使用兩個參數的例子,以便我們在做一些可視化的嘗試時不會把自己逼瘋。一個很棒的損失函數的輪廓可能是這樣的。

損失函數的輪廓

爲何我說這是一個很棒的損失函數?因爲擁有這種輪廓的損失函數就像聖誕老人一樣,是不存在的。然而,它仍然是一個不錯的教學工具,有助於全面瞭解關於梯度下降的一些最重要的想法。那麼,我們從這裏開始吧。

x 軸和 y 軸分別代表兩個權值,z 軸代表在給定兩個特定權值的情況下損失函數的值。我們的目標就是找到損失最小的特定權值,這個點被稱作損失函數的最小值點。

你一開始就隨機初始化了權值,所以你的神經網絡可能會表現得像喝醉了的你一樣,把貓的圖片歸類爲人。這樣的情況對應的是損失函數輪廓中的 A 點,此處的網絡性能十分差,因此損失也很高。

我們需要尋找一種能夠導航到「谷底」B 點處的方法,這裏的損失函數值最小。那麼我們要怎麼做呢?

梯度下降

初始化權值的時候,我們處於損失函數圖形中的 A 點。首先要做的就是查看 x-y 平面中所有可能的方向,看看哪個方向是損失函數的值下降最陡峭的方向。這個就是我們必須移動的方向,它恰恰與梯度的方向相反。梯度是高維導數的另一種說法,它給出了最陡峭的上升方向。

要想理解這個概念,請看下圖。在曲面的任何一點,我們都能夠定義一個與其相切的平面。在更高維度,我們總能夠定義一個超平面,但在這裏我們還是堅持使用 3 維空間。然後,在這個平面上有無限個方向。其中,準確來說只有一個使函數上升最快的方向,這個方向由梯度給出,與之相反的方向就是下降最快的方向。這就是算法名稱的來源,我們沿着梯度的方向進行下降,所以就叫做梯度下降

現在,既然已經有了前進方向,我們必須決定需要採取步子的大小,而控制下降步幅大小的參數學習率。爲了保證降到最小值,我們必須謹慎地選擇學習率

如果移動得太快,我們可能越過最小值,沿着「山谷」的山脊蹦蹦跳跳,永遠都不可能到達最小值。如果移動太慢,訓練可能花費太長的時間,根本就不可行,此外太慢的學習率也容易讓算法陷入極小值,我們會在本文後面的部分討論。

一旦有了梯度和學習率,我們就開始行動,然後在最終到達的任何位置重新計算梯度,然後重複這個過程。

梯度的方向告訴我們哪個方向上升的最快,它的幅值則表示最陡峭的上升/下降有多陡。所以,在最小值的地方,曲面輪廓幾乎是平坦的,我們期望得到幾乎爲零的梯度。事實上,最小值點的梯度就是 0。

梯度下降過程

使用太大的學習率

在實踐中,我們可能永遠無法精確地達到最小值,但是我們能夠在最小值附近的平坦區域震盪。當我們在這個區域震盪時,損失值幾乎是我們能夠達到的最小值,並且不會有很大的變化,因爲我們是在真實的最小值附近跳動。通常,當損失值在預定的數字內沒有提升的時候我們會停止迭代,例如 10 次或者 20 次迭代。當這種情況發生時,我們就說訓練已經收斂了,或者說收斂已經實現了。

常見的錯誤

讓我稍微偏離主題一會。如果搜索梯度下降的可視化圖,你很可能會看到一個起於一個點、終於最小值點的軌跡,就像前文動畫所展示的一樣。然而,這個關於梯度下降的描述並不準確。我們得到的軌跡完全侷限在 x-y 平面內,這個平面包含權重

正如上面的動畫所描述的,梯度下降並不涉及在 z 軸方向上的移動。因爲僅由 x 軸和 y 軸方向描述的權重是自由參數。實際得到的軌跡是定義在 x-y 平面中的,如下圖所示:

實際的梯度下降軌跡

x-y 平面中的每一個點代表着一個唯一的權重組合,而我們希望有一組由最小值描述的權重

基本方程

描述梯度下降更新規則的基本方程是:

每一次迭代中都執行更新。此處,w 是權重向量,它位於 x-y 平面。我們從這個向量中減去學習率α乘上損失函數相對於權重的梯度。梯度是一個向量,它給出了損失函數上升最快的方向。下降最快的方向恰好和梯度方向相反,這就是爲什麼要從權重向量中減去梯度向量的原因。

如果想象向量對你來說有一些難度,那麼,幾乎同樣的更新規則同時適用於網絡的每一個權重。唯一的變化是,我們現在對每個權重單獨執行更新,上述方程中的梯度被替換爲梯度向量沿着特定權重方向的投影。

對所有的權重同時執行更新。

在做減法之前,我們用學習率與梯度向量相乘。這是我們之前討論過的步驟。要知道,即使我們保持學習率不變,步長也會因爲梯度大小,即損失函數輪廓的陡峭性變化而變化。隨着我們接近最小值點,梯度會接近於 0,我們會以越來越小的步長接近最小值點。

理論上而言,這樣很好,因爲我們希望當接近一個最小值的時候算法能夠採取更小的步長。步長太大有可能導致跳過最小值,並且在最小值脊樑之間來回跳動。

梯度下降中常用的一個技術是採用可變的學習率,而不是固定的學習率。初始時,我們可以使用較大的學習率。但是到了後來,隨着接近最小值點,我們需要慢下來。實現這種策略的一種方法就是模擬退火,也就是衰減的學習率。在這種情況下,學習率在股東能夠數量的迭代次數中逐漸減小。

梯度下降挑戰之一:局部極小值

到目前爲止,梯度下降的故事聽起來真的很美好。現在,我來揭開它的面紗。還記得我之前說過有種損失函數很好,而這種損失函數是不存在的這句話嗎?它們確實是不存在的。

首先,神經網絡是複雜的函數,我們在假設的函數中引入了大量的非線性變換。得到的損失函數看起來並不太好,同樣只有一個我們可以收斂到的最小值點。事實上,這種理想的損失函數被稱作「凸函數」(總是向上彎曲的函數),而深度網絡的損失函數很難是凸的。實際上,它們很可能是這樣的:

在上圖中,存在梯度爲 0 的局部極小值點。然而,我們想要達到的全局最小值點,卻是無法實現的。現在,如果你將權值初始化在 A 點,那麼你將會收斂到局部極小值點,而且,一旦你收斂到這個極小值點,梯度下降將沒法使你離開這裏。

梯度下降是由梯度驅動的,它在任何一個極小值點都會爲 0。局部極小值之所以被稱作局部極小值,是因爲損失函數在該點的值在局部區域是最小的。而全局最小值被稱作全局最小值,是因爲在損失函數在該點的值在整個區域最小。

更糟糕的是,由於我們考慮的那個 3 維損失函數輪廓在實際中是從沒有發生過的,損失函數的輪廓可能更加複雜。在實踐中,我們的神經網絡大約會有 10 億個權重,給我們一個大約(10 億+1)維的函數。

事實上,很難想象一個如此多維度的函數是什麼樣子的。然而,深度學習領域如今人才濟濟,人們已經想出了以 3D 的形式可視化損失函數輪廓的方法。最近的一篇論文提出了一種名爲「Filter Normalization」的技術,該項技術解釋了超出本文範圍的內容。然而,它確實讓我們看到了我們所處理的損失函數的潛在複雜性。例如,下圖是 VGG-56 在 CIFAR-10 數據集上構建的損失函數的 3D 架構。

一個複雜的損失函數圖像(圖源:https://www.cs.umd.edu/~tomg/projects/landscapes/)

正如你所看到的,到處都是局部極小值點。

梯度下降挑戰之二:鞍點

關於梯度下降的侷限性,我們得到的基本教訓是:一旦到達梯度爲 0 的區域,不管極小值點的質量如何,它都幾乎無法逃離。我們面臨的另一種問題是鞍點,它們的形狀如下:

鞍點

你也可以在之前的圖片中看到兩座山峯相遇時候的鞍點。

鞍點得名於它的形狀類似於馬鞍。儘管它在 x 方向上是一個最小值點,但是它在另一個方向上是局部最大值點,並且,如果它沿着 x 方向變得更平坦的話,梯度下降會在 x 軸振盪並且不能繼續根據 y 軸下降,這就會給我們一種已經收斂到最小值點的錯覺。

隨機性的解救

那麼,我們如何在嘗試收斂到全局最優值的同時擺脫局部極小值和鞍點呢?答案是使用隨機梯度下降

到目前爲止,我們一直使用通過對訓練集上的所有可能樣本的損失值求和得到的損失函數進行梯度下降。如果我們進入局部極小值或者鞍點,我們就會被困住。幫助梯度下降擺脫這些困境的一種方法就是隨機梯度下降

在隨機梯度下降中,我們不是通過對所有損失函數求和來計算損失函數的梯度,而是通過計算僅僅一個隨機抽樣(不替換)例子的損失梯度來採取步驟。隨機梯度下降中的每個樣本都是隨機選擇的,相比之下,早期方法在一個批量中處理所有的樣本,因此稱爲批量梯度下降

更新規則也做了相應的改變。


這意味着,我們每一步採用的損失函數都不同於實際的損失函數(它是每一個樣本的損失函數的和)。這種「一個樣本損失函數」在某一特定點的梯度實際上可能指向與「所有樣本損失函數」的梯度略有不同的方向。

也就是說,儘管「所有樣本損失函數」的梯度可能把我們推向一個局部極小值,或者使我們困在一個鞍點,但是這種「一個樣本損失函數」的梯度可能指向一個不同的方向,並有可能幫助我們避開這些情況。

「所有樣本損失函數」的一個局部最小值點也應該考慮在內。如果我們採用批量梯度下降,那麼我們會被困在這裏,因爲這裏的梯度始終會指向局部最小值點。但是,如果我們使用隨機梯度下降,這個點可能不在「一個樣本損失函數」輪廓的局部最小值周圍,這使得我們遠離局部最小值點。

即使我們陷在「一個樣本損失函數」的局部最小值點,下一個隨機採樣點的「一個樣本損失函數」的損失情況也可能不同,從而使我們能夠繼續移動。

當它收斂的時候,它會收斂到幾乎所有「一個樣本損失函數」的最小值。也有經驗顯示,鞍點是極不穩定的,輕輕一推就可以擺脫。

所以,這是否意味着在實踐中應該使用這種一個樣本的隨機梯度下降呢?

批大小

答案是否定的。儘管從理論上而言,隨機梯度下降可能給我們帶來最好的結果,但是從計算角度而言,它並不是一個非常可行的選擇。當我們使用由所有單個損失函數相加得到的函數進行梯度下降時,所有單個損失函數的梯度可以並行計算,而使用隨機梯度下降的時候,梯度的計算必須一個一個的順序進行。

因此,我們所做的是一個平衡的行爲。我們使用固定數量(例如 16、32 或者 128 個)的樣本形成一個 mini-batch 來構建損失函數,而不是使用整個數據集或者單個樣本。這個詞與一次處理所有樣本形成了對比,它通常被稱作批梯度下降。選擇 mini-batch 的大小是爲了保證我們有足夠的隨機性擺脫局部最小值,同時可以利用足夠的並行計算力。

重新審視局部極小值:它們並沒有你想象的那麼糟糕

不要急着反對局部極小值,最近的研究表明局部最小值並不一定就是壞的。在神經網絡的損失情況下,最小值實在太多了,好的局部極小值可能和全局最小值一樣好。

我爲什麼說好?是因爲你仍可能陷入由不穩定的訓練樣本導致的局部極小值中。好的局部極小值,或者文獻中提到的最優局部極小值,在給定神經網絡的高維損失函數中也可能是大量存在的。

你可能還會注意到,很多神經網絡都在執行分類任務。如果一個局部極小值對應着 0.7—0.8 的正確標籤分數,而全局最小值能夠產生 0.95-0.98 的正確標籤分數,那麼兩者輸出的預測標籤結果將是相同的。

最小值的一個理想屬性是它應該在平坦的一面。爲什麼?因爲平坦的最小值很容易收斂到,而且越過最小值或者在最小值的脊樑之間跳躍的可能性更小。

更重要的是,我們期望測試集的損失曲面與我們訓練的訓練集的損失曲面略有不同。對處於平坦又較寬處的極小值,由於這種變化,損失不會有太大變化,但處於相對較窄處的極小值不是這樣。我們要指出的一點是,更平坦處的最小值能夠更好地泛化,因此是可取的。

重新審視學習率

近來,針對損失函數中的次優最小值,關於學習率調度的研究激增。即使學習率下降,也有可能陷入局部極小值。傳統上,要麼在固定次數的迭代之後訓練完成,要麼在損失值沒有改善的情況下,固定次數的迭代(比如 10 次)之後訓練停止。這種情況在文獻中被稱爲早停。

使用較快的學習率也有助於我們在訓練中更早地跳過一些局部極小值。

人們也把早停和學習率衰減結合起來,在迭代 10 次後損失函數沒有改善的情況下學習率開始衰減,最終在學習率低於某個確定的閾值時停止。

近年來,循環學習率變得流行起來,在循環學習率中,學習率是緩慢增加的,然後緩慢減小,以一種循環的形式持續着。

Leslie N. Smith 提出的 Triangular 和 Triangular2 循環學習率方法。左側的最大學習率和最小學習率保持不變。右側的區別在於每個週期之後學習率減半。圖源:Hafidz Zulkifl

所謂暖重啓的隨機梯度下降,基本上是將學習率退火到一個下限,然後將學習率恢復到初始值。

對於學習率如何下降,我們也有不同的計劃,例如,從指數衰減到餘弦衰減。

餘弦退火與重啓相結合

最近的一篇論文介紹了一種叫做「隨機加權平均」的技術。作者提出了一種方法,首先收斂到最小值,緩存權重,然後將學習率恢復到更高的值。然後,這種更高的學習率將算法從最小值推到損失面中的隨機點。然後使算法再次收斂到另一個最小值。重複幾次,最後,他們對所有緩存權重集的預測進行平均,以產生最終預測。

隨機加權平均技術

結論

所以,這是梯度下降的介紹性文章,這是深度學習優化工作的驅動力,因爲關於反向訓練的開創性論文顯示,可以通過計算梯度來訓練神經網絡。然而,關於梯度下降還有一個我們在這篇文章中沒有談到的缺失部分,那就是解決 pathological curvature 的問題。對經典隨機梯度下降的擴展,如動量、RMSProp 和 Adam,被用來克服這個關鍵問題。

然而,我覺得我們所做的一切,對一篇文章來說已經足夠了,其餘的將會由另一篇文章解決。


原文鏈接:https://blog.paperspace.com/intro-to-optimization-in-deep-learning-gradient-descent/

文章來源:機器之心