caffe參數配置solver.prototxt 及優化算法選擇

#caffe參數配置solver.prototxt 及優化算法選擇


本文主要包含如下內容:


solver.prototxt介紹及流程


  參考網址
  .proto文件用來定義結構體的參數,.prototxt文件用結構體的初始化數據配置初始化Net
  參數配置文件定義了網絡模型訓練過程中需要設置的參數,如學習率、權重衰減係數、迭代次數、使用GPU還是CPU等。

  在前向過程(forward)中計算loss,在反向傳播中計算梯度gradient。根據誤差度、正則項的梯度以及其他方法的特定項來計算參數更新量。

Solver的流程:

  1. 設計好需要優化的對象,以及用於學習的訓練網絡和用於評估的測試網絡。(通過調用另外一個配置文件prototxt來進行)
  2. 通過forwardbackward迭代的進行優化來跟新參數。
  3. 定期的評價測試網絡。 (可設定多少次訓練後,進行一次測試)
  4. 在優化過程中顯示模型和solver的狀態
# 設置網絡模型,文件的路徑要從caffe的根目錄開始 
net: "examples/mnist/lenet_train_test.prototxt"  

# 與test layer中的batch_size結合起來理解,假設樣本總數爲10000,一次性執行全部數據效率低,因此將測試數據分成幾個批次來執行,每個批次的數量就是batch_size。假設batch_size爲100,則需要迭代100次才能將10000個數據全部執行完,因此test_iter設置爲100.(100*100=10000),合理設置可使得測試遍歷完去不測試樣本
test_iter: 100  

# 訓練網絡之前不進行測試,默認在訓練網絡前先進行一次test
test_initialization:false

# 測試間隔,也就是每訓練test_interval次,才進行一次測試  ,合理設置可使得訓練遍歷完全部訓練樣本
test_interval: 500

# 這個參數乘上train.prototxt中的batch size是你實際使用的batch size。 相當於讀取batchsize * itersize個圖像才做一下gradient decent。 這個參數可以規避由於gpu內存不足而導致的batchsize的限制 因爲你可以用多個iteration做到很大的batch 即使單次batch有限
iter_size: 8

# The base learning rate, momentum and the weight decay of the network.
# base_lr爲基礎學習率
base_lr: 0.01
# 優化算法選擇,此處選擇隨機梯度下降法(默認爲SGD,這一行可以省掉)
type: SGD
# 上一次梯度更新的權重  
momentum: 0.9
# 權重衰減項,防止過擬合的一個參數(正則化項)
weight_decay: 0.0005

# The learning rate policy,學習率變化準則
lr_policy: "inv"
# 學習率變化的比率
gamma: 0.0001
power: 0.75

# 每訓練display次在屏幕上顯示一次  
display: 100

# 最大迭代次數,這個數設置太小,會導致沒有收斂,精確度很低。設置太大,會導致震盪,浪費時間  
max_iter: 10000

# 狀態進行保存,snapshot用於設置訓練多少次後進行保存,默認爲0,不保存。snapshot_prefix 設置保存路徑
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"

# 設置運行模式: CPU or GPU(默認爲GPU)
solver_mode: CPU

lr_policy:學習策略

  lr_policy可以設置爲下面這些值,相應的學習率的計算爲:

    - fixed:        保持base_lr不變.
    - step:         如果設置爲step,則還需要設置一個stepsize,  返回 base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示當前的迭代次數
    - exp:          返回base_lr * gamma ^ iter, iter爲當前迭代次數
    - inv:          如果設置爲inv,還需要設置一個power, 返回base_lr * (1 + gamma * iter) ^ (- power)
    - multistep:    如果設置爲multistep,則還需要設置一個stepvalue。這個參數和step很相似,step是均勻等間隔變化,而multistep則是根據stepvalue值變化
    - poly:         學習率進行多項式誤差, 返回 base_lr (1 - iter/max_iter) ^ (power)
    - sigmoid:      學習率進行sigmod衰減,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))

  相關CPP文件
  其中,求解模型可以在DIGITS可視化
  SGD


solver.prototxt優化算法選擇


批量梯度下降法(BGD)和 隨機梯度下降法(SGD)

  批量梯度下降法(batch gradient descent),是梯度下降法最常用的形式,具體做法也就是在更新參數時使用所有的樣本來進行更新。(訓練集的所有內容)。(容易內存超出,陷入局部最小值)

  隨機梯度下降法(stochastic gradient descent),這裏的隨機梯度下降法其實跟MBGD(minibatch gradient descent)是一個意思,即隨機抽取一批樣本,以此爲根據來更新參數。(增加隨機性,可以跳出局部最小值)

  各自的優缺點都非常突出。對於訓練速度來說,隨機梯度下降法訓練速度很快,而批量梯度下降法在樣本量很大的時候,訓練速度不能讓人滿意。

  對於準確度來說,隨機梯度下降法用於僅僅用mini-batch樣本決定梯度方向,導致解很有可能不是最優,導致迭代方向變化很大,不能很快的收斂到局部最優解。

  同樣的,batch size 設置比較大的時候,效果會比較好(不能設置太小或者太大)。在使用GPU的情況下,並且運用矩陣乘法(並行運算),batch size 等於1或10計算一次梯度的時間是一致的。因此:batch size 設置爲10的時候,運行速度比batch size 設置爲1的時候幾乎快10倍。而且。隨機性更小,震盪更不明顯,加快收斂速度。

SGD:隨機梯度下降法

  SGD,隨機梯度下降法就是每一次迭代計算 mini-batch 的梯度,然後對參數進行更新。利用負梯度和上一次權重的更新值的線性組合(利用傳統的梯度下降法容易收斂到局部最優,且選擇合適的 learing rate 困難)。學習率a是負梯度的權重。動量u是上一次更新值的權重。

  
  

  學習參數需要一定的調整才能達到最好的效果。一般的,將學習速率a初始化爲0.01,然後在訓練中當loss達到穩定時,將a除以一個常數,將這個過程重複多次。對於動量u設置爲0.9。u能使權重的更新更爲平緩(防抖動),使學習過程更爲穩定、快速。
  通過交叉驗證,動量參數通常設爲[0.5,0.9,0.95,0.99]中的一個.有時隨着時間而變化,從0.5到0.99;表示要在多大程度上保留原來的更新方向,這個值在0-1之間,在訓練開始時,由於梯度可能會很大,所以初始值一般選爲0.5;當梯度不那麼大時,改爲0.9。學習率即當前batch的梯度多大程度上影響最終更新方向,跟普通的SGD含義相同。
  特徵:下降初期時,使用了上一次更新參數,如果下降方向一致,乘上較大的u能夠進行很好的加速。下降中後期時,在局部最小值來回震盪的時候,gradient->0,u使得更新幅度增大,從而跳出陷阱。在梯度改變方向的時候,u能夠減少更新。總而言之,momentum項能夠在相關方向加速SGD,抑制振盪,從而加快收斂。

AdaGrad:自適應性梯度下降法

  自適應梯度下降法,對學習率進行了一個約束。即:
  
  
  特徵:前期g_t較小的時候, regularizer較大,能夠放大梯度;後期g_t較大的時候,regularizer較小,能夠約束梯度;合處理稀疏梯度。
  用於平滑的式子eps(一般設爲1e-4到1e-8之間)是防止出現除以0的情況。
  缺點:仍依賴於人工設置一個全局學習率,學習率設置過大的話,會使regularizer過於敏感,對梯度的調節太大,中後期,分母上梯度平方的累加將會越來越大,使gradient->0,使得訓練提前結束。

AdaDelta:AdaGrad的擴展

  Adadelta是對Adagrad的擴展。Adagrad會累加之前所有的梯度平方,而Adadelta只累加固定大小的項,並且也不直接存儲這些項,僅僅是近似計算對應的平均值
  
  
t%5E2)
  特徵:訓練初中期,加速效果不錯,很快;訓練後期,反覆在局部最小值附近抖動

  同時:使用Adadelta算法,我們甚至都無需設置默認的學習率。

E[Δθ2]t=γE[Δθ2]t1+(1γ)Δθt2 E[\Delta \theta^2]_t = \gamma E[\Delta \theta^2]_{t-1} + (1 - \gamma) \Delta \theta^2_t
RMS[Δθ]t=E[Δθ2]t+ϵ RMS[\Delta \theta]_{t} = \sqrt{E[\Delta \theta^2]_t + \epsilon}
Δθt=RMS[Δθ]t1RMS[g]tgt \Delta \theta_t = - \dfrac{RMS[\Delta \theta]_{t-1}}{RMS[g]_{t}} g_{t}

RMASprop:Adadelta的特例

    cache =  decay_rate * cache + (1 - decay_rate) * dx**2
    x += - learning_rate * dx / (np.sqrt(cache) + eps)

  是一個非常高效的適應性學習率方法。這個方法用一種很簡單的方式修改了Adagrad
方法,讓它不那麼激進,單調地降低了學習率。具體說來,就是它使用了一個梯度平方的滑動平均

  代碼中,decay_rate是一個超參數,常用的值是[0.9,0.99,0.999]。RMSProp仍然
是基於梯度的大小來對每個權重的學習率進行修改,這同樣效果不錯。但是和Adagrad不同,其更
新不會讓學習率單調變小,不會發生更新停止的情況。
  特徵:RMSprop依賴於全局學習率,RMSprop算是Adagrad的一種發展,和Adadelta的變
體,效果趨於二者之間,適合處理非平穩目標對於RNN效果很好。

Adam:Adaptive Moment Estimation(目前效果最好的梯度下降算法)

  本質上是帶有動量項的RMSprop,它利用梯度的一階矩估計和二階矩估計動態調整每個
參數的學習率。
  
  
  
  
  

  特徵:結合了Adagrad善於處理稀疏梯度和RMSprop善於處理非平穩目標的優點,對內存需求較小,爲不同的參數計算不同的自適應學習率,也適用於大多非凸優化 - 適用於大數據集和高維空間。
  作者建議u1取默認值爲0.9,v1爲0.999,ϵ爲1e-8

NAG:Nesterov accelerated gradient(加速梯度下降法)

  Nesterov動量的核心思路是,當參數向量位於某個位置x時,觀察上面的動量更新公式可以發現,動量部分會通過mu * v稍微改變參數向量。因此,計算x + mu * v的梯度而不是“舊”位置x的梯度就有意義了。Nesterov項在梯度更新時做一個校正,避免前進太快,同時提高靈敏度。 關鍵:計算梯度的位置不一樣.
  
  
  
  
  Momentum項和Nesterov項都是爲了使梯度更新更加靈活,對不同情況有針對性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章