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,图片摘自别人。
新小同学一枚,请前辈多多指教