1. 程式人生 > >入門 | 一文簡述深度學習優化方法——梯度下降

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

http://www.sohu.com/a/241298990_129720

本文是一篇關於深度學習優化方法——梯度下降的介紹性文章。作者通過長長的博文,簡單介紹了梯度下降的概念、優勢以及兩大挑戰。文中還配有大量生動形象的三維影象,有興趣的親瞭解一下?

從很大程度上來說,深度學習實際上是在解決大量煩人的優化問題。神經網路僅僅是一個非常複雜的函式,包含數百萬個引數,這些引數代表的是一個問題的數學解答。以影象分類為例,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 Zulkifli

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

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

餘弦退火與重啟相結合

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

隨機加權平均技術

結論

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

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

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