深度学习中的优化算法介绍

版权声明:我的博客站点:www.zgcr1991.com https://blog.csdn.net/zgcr654321/article/details/88178529

BGD/MBGD/SGD

梯度下降的公式为:
θ i + 1 = θ i η θ i L ( θ i ) \theta_{i+1}=\theta_{i}-\eta \frac{\partial}{\partial \theta_{i}} L(\theta_{i})
对某个参数w的梯度下降公式就是上一步的该参数w的值减去学习率乘以损失函数对w的梯度值。损失函数对w的偏导数值就是梯度。需要注意的是梯度下降总是减去梯度。
BGD/MBGD/SGD的区别主要在于损失函数的计算:
J ( θ ) = 1 2 m i = 1 m ( h θ ( x ( i ) ) y ( i ) ) 2 J(\theta)=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2}
BGD中,用于计算损失函数的是全体样本epoch;MBGD中,用于计算损失函数的是一个小批量样本batch_size;SGD中,用于计算损失函数的是单个样本。

Momentum

v t = γ v t 1 + η θ J ( θ ) v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J(\theta)
θ = θ v t \theta=\theta-v_{t}
θ为权重参数,衰减值γ通常设定为0.9,或相近的某个值。
可以看到参数更新时不是直接减去学习率乘以上一步梯度,而是减去动量vt。vt由上一步的动量vt-1乘以衰减值γ,再加上上一步的学习率乘以梯度。
这样做的好处是,如果当前步的梯度与上一步梯度方向相同,那么这种计算会增大动量vt;如果当前步的梯度与上一步梯度方向相反,则会减小动量vt。
这样如果我们再局部最优点附件震荡收敛时,当前步的梯度与震荡的前一步的梯度方向相反。因此原本在局部最优点要大幅震荡徘徊的梯度,主要受到前一时刻的影响,而导致在当前时刻的梯度幅度减小。 这使得Momentum算法收敛速度比普通的梯度下降法更快。

NAG

v t = γ v t 1 + η θ J ( θ γ v t 1 ) v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J\left(\theta-\gamma v_{t-1}\right)
θ = θ v t \theta=\theta-v_{t}
θ为权重参数,衰减值γ通常设定为0.9。
NAG算法全称是Nesterov accelerated gradient,是对Momentum的改进。计算vt时求梯度时,损失函数中的参数θ会减去上一步的动量vt-1与衰减值γ的乘积,然后再对这个损失函数求梯度。
这使得我们能预测参数θ下一位置的近似值。这样我们就可以通过计算参数未来位置的近似值上的梯度"预见未来"。
NAG可以使RNN神经网络在很多任务上有更好的表现。

Adagrad

η t = η t 1 + g t 2 \eta_{t}=\eta_{t-1}+g_{t}^{2}
θ t + 1 = θ t η n t + ϵ g t \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{n_{t}+\epsilon}} * g_{t}
θ为权重参数。t代表每一次迭代。g代表第t次迭代时对θ得梯度。ϵ为平滑因子,避免除数为零。
可以看到学习率是初始学习率η除以过去每次迭代的梯度的平方之和。所以学习率会逐渐变小。对于变化不剧烈的参数,它们的梯度一直比较小,因此学习率就可以保持在比较大的水平;而对于变化剧烈的参数,它们的梯度值比较大,学习率相对就小一些。
基于上面这个特性,Adagrad方法对稀疏参数进行大幅更新和对频繁参数进行小幅更新。因此,Adagrad方法非常适合处理稀疏数据。

AdaDelta/RMSProp

论文:ADADELTA: an adaptive learning rate method
论文地址:https://arxiv.org/pdf/1212.5701v1.pdf
E ( g t 2 ) = E ( g t 1 2 ) + ( 1 γ ) g t 2 E(g_{t}^{2})=E(g_{t-1}^{2})+(1-\gamma) g_{t}^{2}
θ t = η E ( g t 2 ) + ϵ g t \triangle \theta_{t}=-\frac{\eta}{\sqrt{E(g_{t}^{2})+\epsilon}} \cdot g_{t}
θ t = η R M S ( g t ) g t \triangle \theta_{t}=-\frac{\eta}{RMS(g_{t})} g_{t}
θ t = R M S ( θ t 1 ) R M S ( g t ) g t \triangle \theta_{t}=-\frac{RMS(\triangle \theta_{t-1})}{RMS(g_{t})} g_{t}
θ t + 1 = θ t + θ t \theta_{t+1}=\theta_{t}+\triangle \theta_{t}
衰减值γ通常设定为0.9。
AdaDelta是对Adagrad方法的改进。AdaDelta的梯度和递归地定义成历史梯度平方的衰减平均值。动态平均值E仅仅取决于当前的梯度值与上一时刻的平均值。将分母简记为RMS,表示梯度的均方根误差。此外,还将学习率η换成了 RMS[Δθ],这样我们不需要设置基础学习率η。
从多个数据集情况来看,AdaDelta在训练初期和中期,具有非常不错的加速效果。但是到训练后期,进入局部最小值雷区之后,AdaDelta就会反复在局部最小值附近抖动。主要体现在验证集错误率上,脱离不了局部最小值吸引盆。这时,切换成动量SGD,如果把学习率降低一个量级,就会发现验证集正确率有2%~5%的提升。
个人猜测使用SGD时,因为人工学习率的量级降低,给训练造成一个巨大的抖动,从一个局部最小值,抖动到了另一个局部最小值,而AdaDelta的二阶近似计算,或者说所有二阶方法,则不会产生这么大的抖动,所以很难从某个局部最小值中抖出来。
RMSProp和AdaDelta基本一样。

Adam

论文:ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION
论文地址:https://arxiv.org/pdf/1412.6980.pdf
g t = θ J ( θ t 1 ) g_{t}=\nabla_{\theta} J\left(\theta_{\mathrm{t}-1}\right)
m t = β 1 m t 1 + ( 1 β 1 ) g t m_{t}=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t}
v t = β 2 v t 1 + ( 1 β 2 ) g t 2 v_{t}=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2}
m s = m t 1 ( β 1 t ) m_{s}=\frac{m_{t}}{1-(\beta_{1}^{t})}
v s = v t 1 ( β 2 t ) v_{s}=\frac{v_{t}}{1-(\beta_{2}^{t})}
θ t + 1 = θ t η v s + ϵ m s \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{v_{s}}+\epsilon} m_{s}
Adam算法的全称是adaptive moment estimation,它吸收了RMSProp和Momentum算法的优点。其计算过程如下:

  • 计算第t次迭代的梯度;
  • 计算梯度的指数移动平均数,m0初始化为0。类似于Momentum算法,综合考虑之前时间步的梯度动量。β1系数为指数衰减率,控制动量与当前梯度的权重分配,默认为0.9;
  • 其次,计算梯度平方的指数移动平均数,v0初始化为0。β2系数为指数衰减率,控制前面的的梯度平方的影响情况,默认为0.999;
  • 由于m0初始化为0,会导致mt偏向于0,尤其在训练初期阶段。因此需要对梯度均值mt进行偏差纠正,降低偏差对训练初期的影响;
  • v0初始化为0导致训练初始阶段vt偏向0,对其进行纠正;
  • 更新权重参数θ,初始的学习率α乘以梯度均值与梯度方差的平方根之比。其中默认学习率α=0.001,ε=10^-8,避免除数变为0。

猜你喜欢

转载自blog.csdn.net/zgcr654321/article/details/88178529
今日推荐