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,圖片摘自別人。
新小同學一枚,請前輩多多指教