Caffe現在提供了六種優化算法:
- Stochastic Gradient Descent (type: SGD)
- AdaDelta (type: AdaDelta)
- Adaptive Gradient (type: AdaGrad)
- Adam (type: Adam)
- Nesterov's Accelerated Gradient (type: Nesterov)
- RMSprop (type: RMSPorp)
假設一個數據集,其數據總量爲D, 那麼這整個數據集的loss的平均值是:
其中, 前面第一部分就是求所有數據損失值的平均值, 第二部分是正則項, lamda是正則項係數, 用於防止過擬合.
如果數據量很小的話,用上面的公式還可以計算. 但是如果數據量D非常大, 那麼計算一次Loss將耗費很長的時間.
所以這時候提出了 batch(批) 這個概念, 將所有數據集D分割成很多個小的batch, 記爲N.
在一次前向計算和後向計算中, 我們只提取一個batch數量的數據, 然後只更新這一batch數據的loss,
然後我們可以重複的, 多次的提取一個batch數據來進行計算.
在caffe中, 默認的優化算法是SGD, 也就是隨機梯度下降算法.
一. Stochastic Gradient Descent (SGD)
隨機梯度下降算法是在梯度下降算法的基礎上發展起來的, 梯度下降算法也叫最速下降算法.
簡要一句話說明SGD的原理就是當前參數W(t+1) 等於 上一次更新後的參數Wt 和 當前權重更新值 的線性組合.
而我們實際在caffe中使用的時候都是加上衝量法的.
其中, α 是學習率(base_lr), μ 是上一次梯度值的權重, 就是衝量(momentum).
學習率是要不斷下降才能讓模型不斷優化的. 學習率可以理解爲步長, 優化模型就是翻山越嶺的從最陡方向出發找最低谷. 如果步子太大了,容易跨過最低谷, 如果步子太小, 找的太慢, 而且容易陷入其他非最低谷出不來了. 在solver文件中, 學習率下降策略lr_policy有很多, 以後我會詳細講的, 知道有這麼回事就好.
上面說的最陡方向, 其實就是負的梯度方向.
衝量就是在保證loss穩定的情況下,儘量加速其下降. 對於SGD, 這個一般默認設置爲0.9, 在某些特殊情況, 當學習率下降到很小的時候, 可以將衝量設置爲 0.99, 提高訓練效果.
二. AdaDelta
Paper地址: https://arxiv.org/pdf/1212.5701.pdf
AdaDelta是一種具有適應性的學習率方法, 也是基於梯度下降發展出來的. 這個算法不需要手動調優學習率, 並且對噪音有很好的魯棒性.
下面是幾點這個方法的優點:
1. 不用手動設置學習率.
2. 對超參數初始化不敏感.
3. 對於每一維度, 分別有一個動態的學習率.
4. 對大梯度, 噪音, 和結構選擇有很好的魯棒性.
5. 對本地和分佈式環境的適應性都很好.
原作者一開始想對梯度下降法做很多改動, 最大的想法就是應用牛頓法, 使用二階導的代價函數,即Hessian海森矩陣:
其中Δxt 是參數變化量, Ht是Hessian海森矩陣, 相當於學習率, 即步長. gt就是梯度, 決定下降方向. 這時候學習率是由海森矩陣決定的, 所以我們就不用手動的設置學習率了.
但是, 海森矩陣在計算上是非常複雜和麻煩的, 所以作者藉着海森矩陣這個思路, 想到加強對一階導數使用或者用估算海森矩陣結果的方法.
最終是選擇了加強一階導數使用的方法, 近似模擬二階牛頓法
基本思路還是跟SGD一樣, 實際的變化量是 衝量和上一次變化量的乘積減去基礎學習率乘以當前梯度值(這裏基礎學習率是1.0, 而且保持不變.)
AdaDelta衝量一般設置成0.95
solver中delta一般設置成1e-6
base_lr必須設置爲1.0
lr_policy必須設置爲fixed.
-------------------------下面是具體算法實現步驟--------------------------------------------------------------------------------------------------------------
paper中作者跟AdaGrad方法做了大量的對比, 作者提出AdaDelta方法主要解決了AdaGrad的兩個缺點. 一是解決了隨着訓練的進行, 學習率會持續衰減的問題. 我認爲作者想表達的意思就是隨着訓練的進行, 如果學習率持續降低, 到後期對優化的影響會降到很低導致優化不完全. 二就是解決的需要手動設置初始學習率的問題.
2012年 Schaul&S. Zhang&LeCun 提出了AdaGrad-like 算法, 我這裏提到這個算法是因爲和AdaDelta算法有相似的地方.
其中, diag(Ht) 是海森矩陣的對角矩陣, E[gt-w:t]是從當前t算起前w次迭代梯度的期望值, 分母就是從當前t算起前w次迭代梯度平方的期望值
這樣取前w次梯度的好處是不會讓梯度消失
好了回到AdaDelta, 這個方法沒有隻是取前w次迭代梯度, 而是取所有迭代的梯度.
其中, ρ是衰減常量, 在caffe中通過設置momentum來設置這個參數. 通過這個公式, 我們算出當前iteration 所有梯度平方的期望值.
我們需要上面結果的平方跟用於參數更新, 這裏用RMS(root mean square 均方根)表示:
其中, RMS[g]t表示當前iteration下, 梯度g 的均方根值, ε是一個常數(就是solver中參數delta), 平滑項, 爲了保證輸出結果不爲零, 因爲後面這個結果是要做分母的.
最後參數的變化量公式:
上面的方法就是Tieleman&Hinton的RMSProp.
後來的Zeiler考慮到units的問題, Δx是用來更新參數x的, 所以他們的units必須要一致.
說說我的理解, 上面的公式中, gt的units應該是跟x正相關的. RMS[g]t的units也是跟x正相關的.
但是一相除, 就變成了unitless 這種情況了.
所以在看下面公式, 在分子上加上了上一次迭代的參數變化量的RMS, 將units又找了回來.
這個units到底怎麼理解我還有困惑, 我覺得應該可以理解爲 "單位"
並且加入上一次迭代, 會增加最終結果的魯棒性, 不會發生突變.
分子分母RMS中的ε取相同的值
實際步長, 也可以認爲是學習率, 跟當前梯度和上一次參數變化量相關
所以不同層, 不同維度的參數的學習率也是不同的. 可以用"因人而異"來形容.
而不是SGD那樣所有參數的學習率是相同的.
AdaDelta在訓練初期和中期, 速度很快. 但是到後期容易陷入局部最優.這一點沒有SGD效果好.
-------------------------------------------------------------------------------------------------------------------------------------------------------------
三. AdaGrad
Adaptive Gradient 自適應梯度算法, 借鑑了L2 Regularizer
其中, 分母是從1開始到t的所有梯度和的平方根, η是基礎學習率.
權值初始化對AdaGrad影響敏感, 如果權值初始化過大, 梯度很大, 調節幅度會很小.
訓練中後期, 梯度很容易逼近0 ,提前結束訓練.
適合處理稀疏梯度
實際使用公式是:
solver中 base_lr 一般設置不大, 可參考使用0.01
lr_policy 必須設置爲"fixed"
momentum 對應公式中ε
四. Adam
Adaptive Moment Estimation
同樣也是基於梯度的優化方法.
只需要一階梯度信息, 並且佔用很少的內存.
通過估計梯度的一階矩 和 二階矩 去動態的調整每個參數的學習率.
其中, mt是對梯度的一階矩估計, nt是對梯度的二階矩估計. 上面帶拐的是對其自身的校正.
u一般取0.9
v一般取0.999
ε一般取1e-8.
五. NAG
Nesterov's Accelerated Gradient
Nesterov的改進是讓之前的動量直接影響到當前的動量
其中, η是基礎學習率, μ是動量(衝量)
momentum首先計算一個梯度, 短的藍色向量. 然後在加速更新梯度的方向進行一個大的跳躍, 長的藍色向量.
nesterov項先在以前的加速梯度方向進行一個大的跳躍, 棕色向量
最後計算梯度, 進行校正, 綠色向量.
solver中base_lr一般爲0.01, gamma爲0.1
lr_policy一般爲"step", stepsize視情況而定.
momentum一般爲0.95
六. RMSprop
這個算法公式在上面AdaDelta中已經寫出來了, RMSprop是AdaDelta的中間形式.
solver中base_lr看情況爲1.0或者0.001
lr_policy一般爲"fixed"
rms_decay一般爲0.98
momentum一般爲0.95
七. 選擇優化方法和優化策略
1. RMSprop解決了AdaGrad訓練中後期梯度消失的問題.
2. AdaDelta中參數的學習率與初始學習率無關. 而RMSprop中參數學習率與初始學習率有關.
3. Adam比RMSprop增加了偏差校正和動量(注意RMSprop中參數momentum的數值是作用在求期望的過程中,不算動量.)
4. 如果輸入數據是 稀疏的, 最好使用自適應學習速率的優化方法(AdaGrad, AdaDelta, RMSprop和Adam).因爲在優化過程中它們會自動調整學習率.
5. 如果關心優化速度, 那麼自適應學習速率方法會比較快. Adam可能是當前最好的優化方法. 但很多大牛還是使用原始的SGD並且不用動量項.
6. Shuffle: 每次迭代時隨機打亂數據樣本順序
7. Curriculum Learn: 把訓練樣本按某種有意義的方式排序, 對逐步解決困難問題有幫助.
8. 歸一化參數初始值.
9. Early Stopping, 這個結合可視化技術來看. 取過擬合前的模型來用.
10. 在損失函數中添加正則化項.
11. Dropout, 測試階段不要用Dropout
12. 並行與分佈式優化方法: Hogwild, Downpour SGD, Delay-tolerant Algorithms for SGD, Elastic Averaging SGD, 工具使用Tensor Flow.