DeepLearning 代碼解析--隨機梯度下降SGD


1、梯度下降(gradient decent)

  梯度下降方法是我們求最優化的常用方法。常用的有批量梯度下降和隨機梯度下降。

  對於一個目標函數;我們目的min(J(Θ)),

 

 α是learningrate,表示每次向梯度負方向下降的步長,經過一次次迭代,向最優解收斂,如下圖所示。

               

根據數據量的大小,我們可以每次使用一個樣本來優化目標函數,即隨機梯度下降(stochastic gradient descent),我們也可以使用全部的數據,批量梯度下降(batch gradient descent)。在實際中由於數據量過大,我們往往采用小批量梯度下降(mini-batch gradient descent)

sgd解決了梯度下降的兩個問題: 收斂速度慢和陷入局部最優。

 

2、SGD中momentum 沖量的使用

  在sgd的過程中,每次下降步長通過α(alpha)來控制,但是會陷入更新太慢的狀態。

    平坦地區,下降好多步,也走不到頭;

    陡峭的區域,下降過頭,導致,左一步,右一步,收斂也慢

      

   γ∈(0,1)相當於momentum

 思想是,若當前梯度方向與上一次相同,那么,此次的速度V增強,否則,應該相應減弱(相加,同號增強,異號減弱)。

 

下面是mxnet中SGD的代碼

 1 struct sgd_clip {
 2   MSHADOW_XINLINE static real_t Map(real_t x, real_t bound) {
 3     if (x > bound) {
 4       return bound;
 5     } else if (x < -bound) {
 6       return -bound;
 7     } else {
 8       return x;
 9     }
10   }
11 };
12 
13 template<typename xpu>
14 void sgd_mom_update(RunContext ctx, TBlob weight, const TBlob grad, TBlob mom,
15                 float lr, float wd, const SGDParam& param) {
16   using namespace mshadow;
17   using namespace mshadow::expr;
18   Stream<xpu>* s = ctx.get_stream<xpu>();
19   Tensor<xpu, 2> weight2d = weight.FlatTo2D<xpu, real_t>(s);
20   Tensor<xpu, 2> mom2d = mom.FlatTo2D<xpu, real_t>(s);
21   Tensor<xpu, 2> grad2d = grad.FlatTo2D<xpu, real_t>(s);
   //sgd_clip的作用限制梯度的幅值不能過大,
   //rescale 與 wd 的作用不知,字面意思通過對梯度的歸一化和加入上一次權重的影響,使得步長合理
22 if (param.clip_gradient > 0.0f) { 23 mom2d = param.momentum*mom2d - 24 lr*(param.rescale_grad*F<sgd_clip>(grad2d, param.clip_gradient) + wd*weight2d); 25 } else { 26 mom2d = param.momentum*mom2d - lr*(param.rescale_grad*grad2d + wd*weight2d); 27 } 28 weight2d += mom2d; 29 } 30 31 template<typename xpu> 32 void sgd_update(RunContext ctx, TBlob weight, const TBlob grad, 33 float lr, float wd, const SGDParam& param) { 34 using namespace mshadow; 35 using namespace mshadow::expr; 36 Stream<xpu>* s = ctx.get_stream<xpu>(); 37 Tensor<xpu, 2> weight2d = weight.FlatTo2D<xpu, real_t>(s); 38 Tensor<xpu, 2> grad2d = grad.FlatTo2D<xpu, real_t>(s); 39 if (param.clip_gradient >= 0.0f) { 40 weight2d -= lr*(param.rescale_grad*F<sgd_clip>(grad2d, param.clip_gradient) + 41 wd*weight2d); 42 } else { 43 weight2d -= lr*(param.rescale_grad*grad2d + wd*weight2d); 44 } 45 }

 

 

 PS,圖片摘自別人。

新小同學一枚,請前輩多多指教

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM