深度学习优化方法总结

SGD

SGD一般指小批量梯度下降,每一次迭代计算小批量的梯度,然后对参数进行更新,是最常见的优化方法了即:
gt=θt1f(θt1)g_t = \nabla_{\theta_{t-1}}f(\theta_{t-1})
Δθt=ηgt\Delta\theta_t = -\eta*g_t
其中η\eta是学习率,θ\theta是需要优化的参数。

缺点:

  • 对所有的参数采用了相同的学习率对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了
  • 比较适用于凸函数的优化,对于非凸函数,容易收敛到一些鞍点

Momentum

模拟物理中的动量的概念,在更新梯度的时候,一定程度上保持原来的运动方向:
mt=μmt1+gtm_t = \mu*m_{t-1} + g_t
Δt=ηmt\Delta_t = -\eta*m_t
其中μ\mu是动量因子,就是保持原运动方向的程度。

优缺点:

  • 能够抑制震荡,收敛速度更快
  • 但是仍然是所有的参数使用相同的动量因子和学习率

Nesterov

将Momentum展开:
Δt=ημmtηgt\Delta_t = -\eta*\mu*m_t - \eta*g_t
Momentum没有影响当前梯度的计算,Nesterov在计算梯度时加入了一个修正项,避免梯度前进太快,提高灵敏度:
gt=θt1f(θt1ημmt)g_t = \nabla_{\theta_{t-1}}f(\theta_{t-1} - \eta*\mu*m_t)
mt=μmt1+gtm_t = \mu*m_{t-1} + g_t
Δt=ηmt\Delta_t = -\eta*m_t

Adagrad

以上的三个方法,都是用相同的更新速度更新所有的参数,但是这不适用于所有情况,例如有一些参数前期已经大幅度的更新,进入了只需要微调的阶段,而有些参数前期更新较少,需要较大幅度的更新。

Adagrad就是针对这种情况,缩放每个参数反比于其所有梯度历史平方值总和的平方根。

nt=nt1+gt2n_t = n_{t-1} + g_t^2
Δθt=ηnt+εgt\Delta\theta_t = -\frac{\eta}{\sqrt{n_t + \varepsilon}}*g_t
其中ε\varepsilon是为了防止分母为0,可以看到前期更新幅度大的参数会累积幅度,更新率随着分母的变大而减小。

特点与问题:

  • 不同的参数有不同的梯度,适合稀疏梯度
  • 但是仍然依赖一个人工设置的全局学习率
  • 中后期,分母由于累积效应,不断的增大,会导致学习率过早的减少,可能会未到收敛的位置提前结束。

以上这四个都是手动设置学习率的方法,有点生硬,下面介绍自适应学习率的方法。

RMSProp

针对Adagrad进行优化,Adagrad会积累之前所有梯度的影响,导致训练因学习率过小提前结束,RMSProp采用指数加权的移动平均,抛弃了远历史的影响。

r=ρr+(1ρ)g2r = \rho r+(1-\rho)g^2
Δθ=ηr+εg\Delta\theta = -\frac{\eta}{\sqrt{r+\varepsilon}}*g
其中ε\varepsilon用于防止分母为0

特点:

  • RMSprop依然依赖于全局学习率
  • 可能会在训练初期有一个比较大的偏置
  • 适合处理非平稳目标 ,对于RNN模型的优化效果很好

Adam

Adam融合了Momentum和RMSprop的特点,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

mt=μmt1+(1μ)gtm_t = \mu*m_{t-1} + (1-\mu)*g_t (Momentum)
nt=vnt1+(1v)gt2n_t = v*n_{t-1} +(1-v)*g_t^2 (RMSprop)

RMSprop存在训练初期有一个比较大的偏置的问题,Adam对mtm_t(梯度带权平均和)和ntn_t(带权有偏方差)根据迭代步数进行了校正:

mt^=mt1μt\hat{m_t} = \frac{m_t}{1-\mu^t}
nt^=nt1vt\hat{n_t} = \frac{n_t}{1-v^t}
Δθt=mt^nt^+εη\Delta\theta_t = -\frac{\hat{m_t}}{\sqrt{\hat{n_t}}+\varepsilon}*\eta
论文中建议:μ=0.9,v=0.999,ε=108\mu=0.9, v=0.999, \varepsilon = 10^{-8}

特点:

  • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
  • 对内存需求较小
  • 为不同的参数计算不同的自适应学习率

Adamax

Adamax是Adam的一种变体,采用一种更简单的方式对学习率进行限制:

nt=max(vnt1,gt)n_t = max( v*n_{t-1}, |g_t|)
Δθt=mt^nt+εη\Delta\theta_t = -\frac{\hat{m_t}}{{n_t}+\varepsilon}*\eta

NAdam

NAdam来自论文:《Incorporating Nesterov Momentum into Adam
深度学习优化方法总结
可以看出,Nadam对学习率有了更强的约束,同时对梯度的更新也有更直接的影响。一般而言,在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

一些杂谈

  • 对于稀疏数据,尽量使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值
  • SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠
  • 如果在意更快的收敛,并且需要训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。
  • Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。
  • 在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果

一篇文章《NATURAL LANGUAGE INFERENCE OVER INTERACTION SPACE》发表于ICLR 2018。它采用了组合的优化思路,也值得借鉴:

先用Adam,再用adagrad,最后使用SGD