1. 程式人生 > 其它 >深度學習中的優化問題以及常用優化演算法

深度學習中的優化問題以及常用優化演算法

在深度模型中我們通常需要設計一個模型的代價函式(或損失函式)來約束我們的訓練過程,訓練不是無目的的訓練,而是朝著最小化代價函式的方向去訓練的。本文主要討論的就是這類特定的優化問題:尋找神經網路上一組引數 

 ,它能顯著地降低代價函式 

 ,該代價函式通常包括整個訓練集上的效能評估和額外的正則化項。

在這篇文章裡深度學習的前戲–梯度下降、反向傳播、啟用函式,我們曾探討過梯度下降問題,說明了在深度學習中最小化代價函式的方法就是重複計算代價函式在訓練集上的梯度,從而使得引數 

 往梯度相反的方向更新,以使得代價函式取到最小值。

1、經驗風險和結構風險

設 

 是每個樣本的損失函式, 

 是輸入 x 時所預測的輸出, 

 是資料生成分佈, 

 是目標輸出,於是得到目標函式:

機器學習演算法的目標就是降低上式所示的期望泛化誤差,這個資料量被稱為風險。但是實際中,我們是無法知道資料的真實分佈 

 的,我們只有有限的訓練資料,能得到的也只有訓練資料樣本的分佈,也稱為經驗分佈 

 ,因此在實際優化問題中,我們需要使用經驗分佈來代替真實分佈,於是目標函式為:

因此我們需要最小化經驗風險:

其中 m 表示訓練樣本的數目。基於最小化這種平均訓練誤差的訓練過程被稱為經驗風險最小化(empirical risk minimization)。

但是直接最小化經驗風險很容易導致過擬合,於是我們需要在經驗風險後面加一個正則化項,在這篇文章中我們詳細介紹了幾種常用的正則化方法 

深度學習中的正則化技術–L1&L2-norm,Dropout,Max-norm,像這種加了正則化項的風險函式我們稱為結構風險函式,於是我們的優化目標變為最小化結構風險函式。


2、批量演算法和小批量演算法

我們在計算最小化經驗風險的時候,從它的計算公式可以看出,它需要計算訓練集上每個樣本的損失(或者梯度),然後求和;當訓練樣本非常大時(特別是在深度學習中)這將是非常耗時間的。統計知識告訴我們“整體期望可以用隨機抽取的樣本期望來進行無偏估計”,那麼直覺的可以想到是不是可以在訓練樣本中隨機取樣少量樣本,然後計算這些樣本上的風險平均值來代替整體的風險平均值呢?事實上,m個樣本均值的標準差是 

 ,具體計算公式如下:

其中m表示樣本個數, 

 是樣本的真實標準差,分母 

 表明使用更多樣本來估計梯度的方法的回報是低於線性的。 比較兩個假想的梯度計算,一個基於 100 個樣本,另一個基於 10, 000 個樣本。後者需要的計算量是前者的 100 倍,但卻只降低了 10 倍的均值標準差。如果能夠快速地計算出梯度估計值,而不是緩慢地計算準確值,那麼大多數優化演算法會收斂地更快。

另外由於訓練集存在的冗餘現象,在最壞的情況下,訓練樣本所有的m的樣本都是彼此的相同拷貝,基於取樣的梯度估計可以使用單個樣本計算出正確的梯度,而比原來的做法少花了 m 倍時間。雖然實際中不可能遇到這種最壞的情況,但仍然會存在大量樣本都對梯度做出了非常相似的貢獻。

使用整個訓練集的優化演算法被稱為批量或確定性的梯度演算法(如,梯度下降演算法),這種演算法代價非常高昂。使用訓練集的隨機取樣樣本的優化演算法稱為小批量梯度演算法,在深度模型中我們有充足理由選擇小批量梯度演算法:

  • 更大的批量會計算更精確的梯度估計,但是回報卻是小於線性的。
  • 極小批量通常難以充分利用多核架構。這促使我們使用一些絕對最小批量,低於這個值的小批量處理不會減少計算時間。
  • 如果批量處理中的所有樣本可以並行地處理(通常確是如此),那麼記憶體消耗和批量大小會正比。
  • 在某些硬體上使用特定大小的陣列時,執行時間會更少。尤其是在使用GPU時,通常使用 2 的冪數作為批量大小可以獲得更少的執行時間。一般,2 的冪數的取值範圍是 32 到 256,16 有時在嘗試大模型時使用。
  • 可能是由於小批量在學習過程中加入了噪聲,它們會有一些正則化效果。

使用小批量梯度演算法需要注意的是:1)抽取小批量前對樣本進行隨機打亂順序,有些演算法對取樣誤差比較敏感,一個是它們使用了很難在少量樣本上精確估計的資訊,另一個是它們以放大采樣誤差的方式使用了資訊;2)兩個連續的小批量應該相互獨立:從一組樣本中計算出梯度期望的無偏估計要求這些樣本是獨立的;3)最好多次遍歷資料集:在演算法遍歷資料集更新引數時,只有第一遍滿足泛化誤差梯度的無偏估計(因為第一遍遍歷時,每一批小樣本都是從資料流中抽取出來的。 換言之,學習器好像是一個每次看到新樣本的人,每個樣本 

都來自資料生成分佈 

 ,而不是使用大小固定的訓練集。這種情況下,樣本永遠不會重複;每次更新的樣本是從分佈 

 中取樣獲得的無偏樣本。)額外的遍歷對引數的更新雖然是有偏的估計,但是它會因減小訓練誤差而得到足夠的好處來抵消其帶來的訓練誤差和測試誤差間差距的增加。


3、神經網路優化中的挑戰

優化是一個很困難的任務,在傳統機器學習中一般會很小心的設計目標函式和約束,以使得優化問題是凸的;然而在訓練神經網路時,我們遇到的問題大多是非凸,這就給優化帶來更大的挑戰。

3.1 區域性極小值

凸優化問題通常可以簡化為尋找一個區域性極小值點的問題,在凸函式中,任何一個區域性極小點都是全域性最小點;有些凸函式的底部是一個平坦區域,在這個平坦區域的任一點都是一個可以接受的解。如下圖所示:

但是在非凸函式中,梯度經常卡在區域性極小值點出不來,所以得不到全域性最優解,如下圖所示:

3.2 高原、鞍點和其他平坦區域

低維空間中,區域性極小值很普遍。在更高維空間中,區域性極小值很罕見,而鞍點則很常見。鞍點處的極值也為0,在鞍點處,Hessian 矩陣同時具有正負特徵值。位於正特徵值對應的特徵 向量方向的點比鞍點有更大的代價,反之,位於負特徵值對應的特徵向量方向的點有更小的代價,從而神經網路也不能優化到一個極小值。我們可以將鞍點視為代價函式某個橫截面上的區域性極小點,同時也可以視為代價函式某個橫截面上的區域性極大點,如下圖紅色小點所示:

另外如果在高原處,梯度是平坦的,那麼優化演算法很難知道從高原的哪個方向去優化來減小梯度,因為平坦的高原處每個方向的梯度都是0。高維空間的這種情形為優化問題帶來很大的挑戰。

3.3 懸崖和梯度爆炸

多層神經網路通常存在像懸崖一樣的斜率較大區域,如下圖所示。這是由於幾個較大的權重相乘導致的。遇到斜率極大的懸崖結構時,梯度更新會很大程度地改變引數值,通常會完全跳過這類懸崖結構。

高度非線性的深度神經網路或迴圈神經網路的目標函式通常包含由幾個引數連乘而導致的引數空間中尖銳非線性。這些非線性在某些區域會產生非常大的導數。當引數接近這樣的懸崖區域時,梯度下降更新可以使引數彈射得非常遠,可能會使大量已完成的優化工作成為無用功。

3.4 長期依賴

當計算圖變得極深時,神經網路優化演算法會面臨的另外一個難題就是長期依賴問題——由於變深的結構使模型喪失了學習到先前資訊的能力,讓優化變得極其困難。深層的計算圖不僅存在於前饋網路,還存在於迴圈網路中。因為迴圈網路要在很長時間序列的各個時刻重複應用相同操作來構建非常深的計算圖,並且模型引數共享,這使問題更加凸顯。

例如,假設某個計算圖中包含一條反覆與矩陣 

 相乘的路徑。那麼 t 步後,相當於乘以 

 。假設 

 有特徵值分解 

 。在這種簡單的情況下,很容易看出

當特徵值 λi 不在 1 附近時,若在量級上大於 1 則會爆炸;若小於 1 時則會消失。梯度消失與爆炸問題(vanishing and exploding gradient problem)是指該計算圖上的 梯度也會因為 

 大幅度變化。梯度消失使得我們難以知道引數朝哪個方向移動能夠改進代價函式,而梯度爆炸會使得學習不穩定。之前描述的促使我們使用梯度截斷的懸崖結構便是梯度爆炸現象的一個例子。

3.5 其他問題

比如非精確梯度,區域性和全域性結構間的弱對應,優化的理論限制等。


4、基本的優化演算法

訓練深度神經網路經常需要花費很多時間,在本文開頭介紹了之前寫的兩篇文章,我們可以知道一般加快神經網路訓練速度的方法有:合適的初始化策略,使用合適的啟用函式;還可以使用批量歸一化處理每層的輸出資料,也可以使用預訓練好的模型做遷移學習。這裡我們介紹一些常用的優化演算法,這能非常有效的縮短梯度下降所需要的時間,這些優化演算法包括:SGD, Momentum optimization, Nesterov Accelerated Gradient, AdaGrad, RMSProp, and Adam optimization。

4.1 隨機梯度下降

我們已經很熟悉梯度下降演算法了,隨機梯度下降(SGD)其實就是通過資料生成分佈隨機抽取m個小批量樣本,在這些小批量樣本上應用梯度下降演算法通過計算它們的梯度均值來得到梯度的無偏估計。

隨機梯度下降在第k個迭代更新

4.2 動量(Momentun)

動量可以加速學習,特別是處理高曲率、小但一致的梯度,或是帶噪聲的梯度。動量演算法積累了之前梯度指數級衰減的移動平均,並且繼續沿該方向移動。動量的效果如下圖所示

有動量的梯度下降行為

橫跨輪廓的紅色路徑表示動量學習規則所遵循的路徑,它使該函式最小化。我們在該路徑的每個步驟畫一個箭頭,表示梯度下降將在該點採取的步驟。我們可以看到,一個病態條件的二次目標函式看起來像一個長而窄的山谷或具有陡峭邊的峽谷。動量正確地縱向穿過峽谷,而普通的梯度步驟則會浪費時間在峽谷的窄軸上來回移動。比較下圖,它也顯示了沒有動量的梯度下降的行為。

沒有動量的梯度下降行為

動量演算法引入了變數 v 充當速度角色,它的作用是如果當前梯度越大,那麼此時引數更新幅度越大,更新規則如下:

具體演算法如下圖所示:

在梯度下降演算法中,步長等於梯度範數乘以學習率,而現在步長取決於梯度序列的大小和排列。當許多連續的梯度指向相同的方向時,步長最大。如果動量演算法總是能觀測到梯度 g ,那麼它會在方向 -g 上不停加速,知道達到最終速度,其中步長大小為: 

 ,如果動量超引數設定為 

 ,則對應著最大速度10倍於梯度下降演算法。

optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate,
                                            momentum=0.9)

4.3 Nesterov 動量

Nesterov 動量和標準動量之間的區別體現在梯度計算上。Nesterov 動量中,梯度計算在施加當前速度之後。因此,Nesterov 動量可以解釋為往標準動量方法中添加了一個校正因子。完整的 Nesterov 動量演算法如下所示。

引數更新規則為:

optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate,
                                           momentum=0.9, use_nesterov=True)

4.4 AdaGrad

由於學習率對模型的效能有顯著影響,又比較難以設定,於是有了自適應學習率演算法。 AdaGrad演算法,如下圖所示,獨立地適應所有模型引數的學習率,縮放每個引數反比於其所有梯度歷史平方值總和的平方根。具有損失最大偏導的引數相應地有一個快速下降的學習率,而具有小偏導的引數在學習率上有相對較小的下降。淨效果是在引數空間中更為平緩的傾斜方向會取得更大的進步。 然而,經驗上已經發現,對於訓練深度神經網路模型而言,從訓練開始時積累梯度平方會導致有效學習率過早和過量的減小。AdaGrad 在某些深度學習模型上效果不錯,但不是全部。

4.5 RMSProp

RMSProp 演算法修改 AdaGrad 以在非凸設定下效果更好,改變梯度積累為指數加權的移動平均。AdaGrad 旨在應用於凸問題時快速收斂。當應用於非凸函式訓練神經網路時,學習軌跡可能穿過了很多不同的結構,最終到達一個區域性是凸碗的區域。AdaGrad 根據平方梯度的整個歷史收縮學習率,可能使得學習率在達到這樣的凸結構前就變得太小了。RMSProp 使用指數衰減平均以丟棄遙遠過去的歷史,使其能夠在找到凸碗狀結構後快速收斂,它就像一個初始化於該碗狀結構的 AdaGrad 演算法例項。

RMSProp 的標準形式如演算法 8.5 所示,結合 Nesterov 動量的形式如演算法 8.6 所 示。相比於 AdaGrad,使用移動平均引入了一個新的超引數ρ,用來控制移動平均的 長度範圍。

經驗上,RMSProp 已被證明是一種有效且實用的深度神經網路優化演算法。目前 它是深度學習從業者經常採用的優化方法之一。

optimizer = tf.train.RMSPropOptimizer(learning_rate=learning_rate,
                                      momentum=0.9, decay=0.9, epsilon=1e-10)

4.6 Adam

Adam 是另一種學習率自適應的優化演算法,如演算法 8.7 所示。“Adam’’ 這個名字派生自短語 “adaptive moments’’。

首先,在 Adam 中,動量直接併入了梯度一階矩(指數加權)的估計。將動量加入 RMSProp 最直觀的方法是將動量應用於縮放後的梯度。結合縮放的動量使用沒有明確的理論動機。其次,Adam 包括偏置修正,修正從原點初始化的一階矩(動量項)和(非中心的)二階矩的估計(演算法 8.7 )。RMSProp 也採用了(非中心的)二階矩估計,然而缺失了修正因子。因此,不像 Adam,RMSProp 二階矩估計可能在訓練初期有很高的偏置。Adam 通常被認為對超引數的選擇相當魯棒,儘管學習率有時需要從建議的預設修改。

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)

在訓練深度神經網路模型時,Adam 優化演算法可以被優先選擇,它通常比其他優化演算法快並且效果好;Adam 演算法有三個引數,一般使用預設的引數就可以了,但是如果需要調整的話,建議熟悉一下它的理論,然後根據實際情況設定引數。

5、《deep learning》是一本好書,但是不建議入門一開始就看。


6、參考資料

1、Aurélien Géron,《 Hands-On Machine Learning with Scikit-Learn and TensoFlow》 2、 Ian Goodfellow et. al,《Deep Learning》

轉至:https://zhuanlan.zhihu.com/p/33175839