http://blog.csdn.net/luo123n/article/details/48239963
前言
這里討論的優化問題指的是,給定目標函數f(x),我們需要找到一組參數x,使得f(x)的值最小。
本文以下內容假設讀者已經了解機器學習基本知識,和梯度下降的原理。
SGD
SGD指stochastic gradient descent,即隨機梯度下降。是梯度下降的batch版本。
對於訓練數據集,我們首先將其分成n個batch,每個batch包含m個樣本。我們每次更新都利用一個batch的數據,而非整個訓練集。即:
其中,η為學習率,gt為x在t時刻的梯度。
這么做的好處在於:
- 當訓練數據太多時,利用整個數據集更新往往時間上不顯示。batch的方法可以減少機器的壓力,並且可以更快地收斂。
- 當訓練集有很多冗余時(類似的樣本出現多次),batch方法收斂更快。以一個極端情況為例,若訓練集前一半和后一半梯度相同。那么如果前一半作為一個batch,后一半作為另一個batch,那么在一次遍歷訓練集時,batch的方法向最優解前進兩個step,而整體的方法只前進一個step。
Momentum
SGD方法的一個缺點是,其更新方向完全依賴於當前的batch,因而其更新十分不穩定。解決這一問題的一個簡單的做法便是引入momentum。
momentum即動量,它模擬的是物體運動時的慣性,即更新的時候在一定程度上保留之前更新的方向,同時利用當前batch的梯度微調最終的更新方向。這樣一來,可以在一定程度上增加穩定性,從而學習地更快,並且還有一定擺脫局部最優的能力:
其中,ρ 即momentum,表示要在多大程度上保留原來的更新方向,這個值在0-1之間,在訓練開始時,由於梯度可能會很大,所以初始值一般選為0.5;當梯度不那么大時,改為0.9。η 是學習率,即當前batch的梯度多大程度上影響最終更新方向,跟普通的SGD含義相同。ρ 與 η 之和不一定為1。
Nesterov Momentum
這是對傳統momentum方法的一項改進,由Ilya Sutskever(2012 unpublished)在Nesterov工作的啟發下提出的。
其基本思路如下圖(轉自Hinton的coursera公開課lecture 6a):
首先,按照原來的更新方向更新一步(棕色線),然后在該位置計算梯度值(紅色線),然后用這個梯度值修正最終的更新方向(綠色線)。上圖中描述了兩步的更新示意圖,其中藍色線是標准momentum更新路徑。
公式描述為:
Adagrad
上面提到的方法對於所有參數都使用了同一個更新速率。但是同一個更新速率不一定適合所有參數。比如有的參數可能已經到了僅需要微調的階段,但又有些參數由於對應樣本少等原因,還需要較大幅度的調動。
Adagrad就是針對這一問題提出的,自適應地為各個參數分配不同學習率的算法。其公式如下:
其中gt 同樣是當前的梯度,連加和開根號都是元素級別的運算。eta 是初始學習率,由於之后會自動調整學習率,所以初始值就不像之前的算法那樣重要了。而ϵ是一個比較小的數,用來保證分母非0。
其含義是,對於每個參數,隨着其更新的總距離增多,其學習速率也隨之變慢。
Adadelta
Adagrad算法存在三個問題
- 其學習率是單調遞減的,訓練后期學習率非常小
- 其需要手工設置一個全局的初始學習率
- 更新xt時,左右兩邊的單位不同一
Adadelta針對上述三個問題提出了比較漂亮的解決方案。
首先,針對第一個問題,我們可以只使用adagrad的分母中的累計項離當前時間點比較近的項,如下式:
這里ρ是衰減系數,通過這個衰減系數,我們令每一個時刻的gt隨之時間按照ρ指數衰減,這樣就相當於我們僅使用離當前時刻比較近的gt信息,從而使得還很長時間之后,參數仍然可以得到更新。
針對第三個問題,其實sgd跟momentum系列的方法也有單位不統一的問題。sgd、momentum系列方法中:
類似的,adagrad中,用於更新Δx的單位也不是x的單位,而是1。
而對於牛頓迭代法:
其中H為Hessian矩陣,由於其計算量巨大,因而實際中不常使用。其單位為:
注意,這里f無單位。因而,牛頓迭代法的單位是正確的。
所以,我們可以模擬牛頓迭代法來得到正確的單位。注意到:
這里,在解決學習率單調遞減的問題的方案中,分母已經是∂f∂x的一個近似了。這里我們可以構造Δx的近似,來模擬得到H−1的近似,從而得到近似的牛頓迭代法。具體做法如下:
可以看到,如此一來adagrad中分子部分需要人工設置的初始學習率也消失了,從而順帶解決了上述的第二個問題。
各個方法的比較
Karpathy做了一個這幾個方法在MNIST上性能的比較,其結論是:
adagrad相比於sgd和momentum更加穩定,即不需要怎么調參。而精調的sgd和momentum系列方法無論是收斂速度還是precision都比adagrad要好一些。在精調參數下,一般Nesterov優於momentum優於sgd。而adagrad一方面不用怎么調參,另一方面其性能穩定優於其他方法。
實驗結果圖如下:
Loss vs. Number of examples seen
Testing Accuracy vs. Number of examples seen
Training Accuracy vs. Number of examples seen
其他總結文章
最近看到了一個很棒的總結文章,除了本文的幾個算法,還總結了RMSProp跟ADAM(其中ADAM是目前最好的優化算法,不知道用什么的話用它就對了)