AdamW随机梯度下降优化解读(备用)

基于随机梯度下降(SGD)的优化算法,在深度学习特别是NLP领域是非常重要的,很多NLP任务都可以转化为对其核心函数进行最小化的数学问题。AdamW随机梯度下降优化算法,相比经典SGD优化算法,采用自适应机制自动调整梯度下降的学习率,模型训练过程基本不需要干预,目前广泛应用于BERT等NLP模型的预训练中。

为什么要用AdamW

经典的随机梯度下降(SGD)优化算法在深度学习取得不错的成绩,但由于相同的学习率被应用于各个参数,使得难以选择恰当的学习率,学习率调整策略受限于预先指定的规则,需要花费较多的时间调整参数,避免在误差函数的优化过程中陷入局部次优解或鞍点。

AdaGrad和RMSProb针对SGD以及Momentum优化存在的问题,采用自适应梯度的方法,能对每个不同的参数调整不同的学习率,对频繁变化的参数以更小的步长进行更新,而对稀疏的参数以更大的步长进行更新。

AdaGrad相比SGD增加了分母,梯度平法累积的平方跟,对更新步长进行更新,但随之时间步的增加,分母项越来越大,最终导致学习率收缩到太小无法进行有效更新。

RMSProp采用梯度平法的指数移动平均数来调节学习率的变化,能够在不稳定的目标函数下进行很好的收敛。RMSProp克服了AdaGrad梯度急剧减小的问题,在很多应用中都展示出优秀的学习率自适应能力。

Adam[1]结合AdaGrad和RMSProp两种算法的优点,对梯度的一阶矩估计和二阶矩估计进行综合考虑,计算出更新步长,实现简单,计算高效,对内存需求小,参数的更新不受梯度的伸缩的影响,超参数通常无需调整或仅需很少的调整,更新步长能被限定在大致的范围内,能自动调整学习率,适应于大规模数据以及参数的场景,比如Bert预训练(110M参数,几十G的wiki数据集,AdamW),适应于NLP等目标函数不稳定以及梯度稀疏或梯度存在很大噪声的问题,超参数可解释性良好,几乎不需要调参。

AdamW计算公式解读

AdamW是目前大量应用的随机梯度下降的优化算法,计算过程如下:

首先是计算梯度的指数移动平均数

m 初始化为0,dx是t时刻的梯度。

m是综合考虑之前时间步的梯度动量,beta1系数是指数衰减率,控制权重的分配,通常取值接近于1,比如0.99。

m = beta1*m + (1 - beta1) * dx

其次是计算梯度平方的指数移动平均数

v的初始值是0,beta2是指数衰减系数,控制之前梯度的影响,类似于RMSProp,对梯度平法进行加权均值,beta2经常采用0.999,由于NLP领域或视频领域的梯度稀疏,所以采用了更接近于1的beta2参数。(参考BERT源码,未对beta1和beta2进行初始化矫正类型的计算。)

v = (beta2) *v + (1 - beta2) * dx**2,   

最后是更新参数

初始的学习率lr乘以梯度均值与梯度方差的平方根之比,其中lr默认学习率α=0.001;ε=10^-8,避免除数变为0;wd为权重衰减系数,经常为0.01,修正L2 Norm和Weight Delay在Adam中不等价导致导致Adam优化带L2正则的损失并不有效的问题。

从表达式可以看出来,对更新步长的计算,是从梯度均值及梯度平法两个切入点进行自适应调节,而不是由当前梯度决定。

p(t+1) = pt  - lr(m/(sqrt(v) + eps) + wd*p(t) )

Keras版本的AdamW  https://github.com/zhouyonglong/keras-adamw

AdamW批处理优化实现-LAMP

对于BERT模型训练,在硬件资源允许前提下,batch越大,训练速度越快,但并不等价于模型收敛速度越快或准确度越好。

LAMP在AdamW基础上针对batch训练进行了针对性的优化,支持自适应元素级更新和准确的逐层修正,将BERT预训练的batch size扩展到64k,仅用76分钟就完成了原来需要3天才能跑完的BERT训练(google TPU v3)[4]。

直白一点就是,AdamW训练BERT,batch较小时有效,batch大了效果反而不好。AdamW进化到LAMP后,batch size可以扩展到64k,并且训练依然有效。

以下是LAMP的计算过程(参考[5]),可以看出大部分的计算和AdamW没有区别。

差异体现在使用u(update)对梯度更新ratio的计算上,在batch粒度上进行了类似于正则化的修正,以维持batch内梯度更新的精度。

m = beta1*m + (1 - beta1) * dx

v = (beta2) *v + (1 - beta2) * dx**2,   

u = m/(sqrt(v) + eps) + wd*p(t)

p_norm = tf.norm(p(t), ord=2)
u_norm = tf.norm(update, ord=2)
ratio = tf.where(
                tf.greater(p_norm, 0),
                tf.where(tf.greater(u_norm, 0), (p_norm/ u_norm), 1.0),
                1.0,
            )

p(t+1) = pt  - lr*ratio*u

Adam(非AdamW)经常使用的参数配置。

  • TensorFlow: learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08.
    Keras: lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0.
  • Blocks: learning_rate=0.002, beta1=0.9, beta2=0.999, epsilon=1e-08, decay_factor=1.
  • Lasagne: learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08
  • Caffe: learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08
  • MxNet: learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8
  • Torch: learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8

----

[1] Adam:  A method for stochastic optimization, https://arxiv.org/pdf/1412.6980.pdf 

[2] Sylvain Gugger and Jeremy Howard, AdamW and Super-convergence is now the fastest way to train neural nets, https://www.fast.ai/2018/07/02/adam-weight-decay/

[3] 梯度平法的指数移动平均 https://github.com/dream-catcher/learning_blogs/tree/master/Adam_Optimizer

[4] Yang YouJing Li. et.al. Large Batch Optimization for Deep Learning: Training BERT in 76 minutes. https://arxiv.org/pdf/1904.00962.pdf

[5] lamp, https://github.com/tensorflow/addons/blob/master/tensorflow_addons/optimizers/lamb.py

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值