深度學習中的各種優(yōu)化算法

優(yōu)化算法的目的是為了優(yōu)化損失函數,損失函數衡量的是模型與數據的偏離程度,主要思想是計算損失函數關于參數的導數(多個參數時計算偏導數),然后沿導數的負方向迭代更新參數,一步步最小化損失函數。這類方法就叫做梯度下降法。

一階優(yōu)化算法

一階優(yōu)化算法只計算一階偏導,寫成矩陣就叫 Jacobian 矩陣。

1.隨機梯度下降法SGD

Stochastic gradient descent

這里的隨機梯度下降法特指 minibatch SGD。這里隨機的意思就是每次隨機從訓練數據中選擇一批數據計算梯度來更新參數。具體流程如下:


Require: 學習率 \epsilon?

Require: 初始參數 \theta?

??while 未滿足停止條件 do

???從訓練集中采樣m?個樣本\{x^{(1)}, ...,x^{(m)}\}?的小批量,其中x^{(i)}?對應目標為y^{(i)}?

???計算梯度:g=\frac{1}{m} \nabla_\theta \sum_iL(f(x^{(i)}, \theta), y^{(i)}) 其中\sum_iL(f(x^{(i)}, \theta), y^{(i)})?是當前批樣本的損失(誤差)

???應用更新:\theta=\theta-\epsilon g?

??end while


典型的流程如下(計算當前參數下的梯度,沿負梯度方向更新參數):

sgd

但隨機梯度下降法有個缺點,由于梯度越大更新不長越大,導致在峽谷類型的函數上收斂非常慢,會一直在比較陡的方向來回振蕩。如圖:

sgd

2.使用動量的隨機梯度下降 momentum

隨機梯度下降法固然有用,但有時候導致收斂速度比較慢,想想一下在一個底比較平的碗里,由于碗底的梯度此時已很小,所以每次參數更新的幅度也特別小,導致算法需要很久才能到達極小值處。不過在碗壁處由于梯度大,所以更新幅度也大。所以可以很自然的想,可以保留在碗壁處的運動趨勢,這樣在碗底就有更快的速度即更大的參數更新幅度。這里就很容易聯想到動量,動量是物體質量和速度的乘積,是物體在運動方向上保持運動的趨勢(牛頓第一定律,慣性定律)。

由于有速度的物體都有動量,所以這里我們認為每次更新的參數的位置都有速度,當前時刻的速度會影響之后時刻的速度,當然假設物體是單位質量,運動時間是單位時間,而SGD則可以看做在任何位置都沒有速度或者速度只使用一次便消失,各時刻互不影響。我們先看看物理問題中動量的運用。

假設從山坡上滾下來一個球(光滑無摩擦),受重力的影響,會一直加速直到到達水平面,每一時刻它都有山坡切線方向的速度,也就是有動量,這里我們計算在某一位置S_{t-1}經過單位時間后可以到達的位置S_t,如圖所示:

momentum

由于模型并不嚴謹,所以計算不會太考慮細節(jié)。S_t的計算方式如下:

v_t = v_{t-1} + a\Delta t =v_{t-1}+F\\ S_t = S_{t-1} + \Delta S \\ \begin{aligned} \Delta S &= v_{t-1}\Delta t + \frac{1}{2}a{\Delta t}^2 \\ &\approx v_{t-1}\Delta t + a{\Delta t}^2 \\ &= v_{t-1}+a \\ &= v_{t-1}+F \\ &=v_t \end{aligned} \\
所以:
S_t = S_{t-1} + v_t \\ v_t = v_{t-1} + F
如果把上面的 S 看做 \theta ,把 F 看做 -g 即負梯度,就有:
\theta_t = \theta_{t-1} + v_t \\ v_t = v_{t-1}-g
這就是動量算法的基本思路,也可以從簡單的角度理解,每次更新時都考慮歷史更新值,歷史更新值一直在累加,所以如果遇到每次更新值方向一致(近似)的情況,那即是當前梯度很小,由于歷史累加也會在當前時間有較大的更新幅度,也就是說在碗底運動時使用了碗壁處積攢的動能,收斂速度更快,而且如果遇到峽谷類型的損失函數,也會一定程度上遏制在梯度大的方向上來回擺動,比如當前計算了梯度向左,而上一步計算的梯度是向右,兩個梯度向加就可以減小當前更新的幅度,保持穩(wěn)定,如圖所示:

momentum

在具體實現階段,需要考慮歷史累積梯度和當前梯度的權重,整體流程如下:


Require: 學習率 \epsilon, 動量參數 \alpha

Require: 初始參數 \theta ,初始速度 v

??while 未滿足停止條件 do

???從訓練集中采樣m個樣本\{x^{(1)}, ...,x^{(m)}\}的小批量,其中x^{(i)}對應目標為y^{(i)}。

???計算梯度:g=\frac{1}{m} \nabla_\theta \sum_iL(f(x^{(i)}, \theta), y^{(i)})

???計算速度:v=\alpha v -\epsilon g?

???應用更新:\theta=\theta+v

??end while


具體流程參考下圖:

momentum

由于動量算法考慮了之前的速度,所以它有可能沖過局部極小值,但是也有可能沖過全局最優(yōu)值,在損失函數曲面情況較復雜的情況下,可能會多次沖過極小值又折返回來,使收斂不穩(wěn)定,也會浪費時間。

3.自適應學習率算法Adagrad

前面的 SGD 和 Momentum 算法都是手動設置學習率 \epsilon ,但是學習率往往難以設置卻對訓練過程影響很大,動量算法在一定程度上影響了學習率(\theta =\theta +v 而不是 \theta=\theta-\epsilon g ) 但是卻引入了新的動量參數。以上這些算法在所有參數上都使用了同一個學習率,但直觀上來說,每個參數的學習率應該是獨立的,應該在訓練階段自適應的調整每個參數的學習率。Adagrad就是一種實現方法,基本思想是,如果每個權重方向歷史梯度很大,那么就該在這個方向減小學習率,以免越過極小點,同樣,如果某個權重方向歷史梯度較小,那么就可以在該方向使用大的學習率,加快收斂。Adagrad 使用所有歷史梯度的平方和的平方根,所以在設定初始學習率的情況下,梯度較大的參數方向的學習率減小的很快,反之梯度較小的參數方向的學習率減小的比較慢,具體算法如下:


Require: 全局學習率 \epsilon

Require: 初始參數 \theta

Require: 小常數 \delta ,為了數值穩(wěn)定使用,大約設為10^{-7}

??初始化梯度累積變量 r=0

??while 未滿足停止條件 do

???從訓練集中采樣m個樣本\{x^{(1)}, ...,x^{(m)}\}的小批量,其中x^{(i)}對應目標為y^{(i)}。

???計算梯度:g=\frac{1}{m} \nabla_\theta \sum_iL(f(x^{(i)}, \theta), y^{(i)})

???累積平方梯度:r=r+g\bigodot g? (對應元素相乘)

???計算更新:\Delta \theta = \frac{\epsilon}{\delta+\sqrt{r}} \bigodot g ,只看其中一個參數更新就是:\Delta \theta^i=\frac{\epsilon}{\delta+\sqrt{\sum^t_{t=0}(g^i_t)^2}}g^i

???應用更新:\theta=\theta+\Delta \theta

??end while


Adagrad算法還可以從二階梯度分析,待續(xù),主要參考李宏毅的Gradient Descent

雖然Adagrad效果不錯,但是從一開始就累積梯度平方會導致有效學習率過早和過量的減小。

4.自適應學習率算法RMSProp

RMSProp是Adagrad的修改版,由于Adagrad使用了歷史所有的梯度,所以很容易被歷史梯度影響難以做出快速調整,這點與Momentum比較像,但是Momentum有動量參數參數來控制歷史梯度的權重而Adagrad沒有這個機制,增加了這個機制就是RMSProp了,控制歷史梯度的權重可以更快的對梯度變化做出調整。

具體算法如下:


Require: 全局學習率 \epsilon ,衰減速率 \rho

Require: 初始參數 \theta

Require: 小常數 \delta? ,為了數值穩(wěn)定使用,通常設為10^{-6}?

??初始化梯度累積變量 r=0?

??while 未滿足停止條件 do

???從訓練集中采樣m個樣本\{x^{(1)}, ...,x^{(m)}\}的小批量,其中x^{(i)}對應目標為y^{(i)}。

???計算梯度:g=\frac{1}{m} \nabla_\theta \sum_iL(f(x^{(i)}, \theta), y^{(i)})

???累積平方梯度:r=\rho r+(1-\rho)g\bigodot g? (對應元素相乘)

???計算更新:\Delta \theta = \frac{\epsilon}{\delta+\sqrt{r}} \bigodot g ,只看其中一個參數更新就是:\Delta \theta^i=\frac{\epsilon}{\delta+\sqrt{\sum^t_{t=0}(g^i_t)^2}}g^i

???應用更新:\theta=\theta+\Delta \theta

??end while


5.自適應學習率算法Adam

Adam 結合了RMSProp和Momentum , 可以參考Adam的論文

具體算法如下:


Require: 全局學習率 \epsilon (建議默認為0.001)

Require: 矩估計的指數衰減速率,\rho_1\rho_2 在區(qū)間 [0,1) 內(建議默認分別為0.9和0.999)

Require: 初始參數 \theta?

Require: 小常數 \delta ,為了數值穩(wěn)定使用,通常設為10^{-6}

??初始化一階和二階矩變量 s=0r=0

??初始化時間步 t=0

??while 未滿足停止條件 do

???從訓練集中采樣m?個樣本\{x^{(1)}, ...,x^{(m)}\}?的小批量,其中x^{(i)}?對應目標為y^{(i)}?。

???計算梯度:g=\frac{1}{m} \nabla_\theta \sum_iL(f(x^{(i)}, \theta), y^{(i)})

???t = t+1

???更新有偏一階矩估計(速度):s=\rho_1s+(1-\rho_1)g?

???更新有偏二階矩估計(累積平方梯度):r=\rho_2 r+(1-\rho_2)g\bigodot g (對應元素相乘)

???修正一階矩的偏差:\hat{s}=\frac{s}{1-\rho_1^t}?

???修正二階矩的偏差:\hat{r}=\frac{r}{1-\rho_2^t}?

???計算更新:\Delta \theta =- \epsilon \frac{\hat{s}}{\delta+\sqrt{\hat{r}}}? (逐元素應用操作)

???應用更新:\theta=\theta+\Delta \theta?

??end while


Adam論文中給出的與其他優(yōu)化算法的比較:

adam

6.各算法比較

optimization- imgur

image

optimizer2

二階優(yōu)化算法

二階優(yōu)化算法只計算二階偏導,寫成矩陣就叫 Hessian 矩陣。

最簡單的二階優(yōu)化算法 牛頓法 ,尋找函數的臨界點,臨界點有可能是極大極小點,也可能是鞍點,但是鞍點是不可取的,只有是極小點也就是Hessian矩陣正定時牛頓法才是適用的,不然牛頓法很可能找到鞍點而停止。

由于牛頓法這種尋找梯度為零(臨界點)的點的性質,導致無法成功運用在神經網絡的訓練中。因為高維空間中有更多的鞍點。而低維空間的局部極小值更普遍。直觀上來理解:假設某個點每個二階偏導都大于零說明這個點事極小點,假設由拋硬幣決定二階導數的正負,那在二維空間中某個點是極小點的概率就是1/2*1/2=1/4? 那在高維如五維空間中這個點是極小點的條件就是各個偏導都大于零,概率是1/2*1/2*1/2*1/2*1/2=1/32? 而只有其中一個偏導大于零的情況就比較常見。

高維空間中鞍點的激增或許就解釋了在神經網絡訓練中為什么二階方法無法成功取代梯度下降法。(《深度學習》8.2)

參考資料

  1. 《深度學習》
  2. 李宏毅的在線課程
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容