前言
bert中使用的优化器整体是一个带有线性调整学习率的带有<code>权重衰减</code>而不进行bias correct的Adam优化器。下面一步一步介绍。
优化器
首先,在上一篇 《深度学习中的优化器》中提到,由于Adam在初期,一阶动量 m 和 二阶动量 v 值较小,会导致最初的优化会朝着 0 偏移,比如:
β1 = 0.9, m0 = 0, m1=β1 * m0 + (1-β1)*g1 = 0.1g1, 这个值太小了,所以我们想办法给他还原,即 β^1 = β1 /(1 - β1 ** t), 此时m1 = g1。
而 在bert中,使用的Adam却没有进行这一项修正,具体原因放在下面一起讲。
此外,在源码中,对Adam进行了权重衰减,并添加了一句注释:
# Just adding the square of the weights to the loss function is *not*
# the correct way of using L2 regularization/weight decay with Adam,
# since that will interact with the m and v parameters in strange ways.
#
# Instead we want ot decay the weights in a manner that doesn't interact
# with the m/v parameters. This is equivalent to adding the square
# of the weights to the loss with plain (non-momentum) SGD.
if self._do_use_weight_decay(param_name):
update += self.weight_decay_rate * param
作者指出,在Adam上直接添加权重的平方不是一种正确的L2正则/权重衰减的方式,为了不影响m 和 v,他们使用了另一种的权重衰减方式,来等效L2正则。
这个问题可以参考DECOUPLED WEIGHT DECAY REGULARIZATION
下面介绍一下这个问题:
首先,L2 Norm是
而 weight decay是
weight decay 在标准SGD下,令
则两者是等价的,所以在实现时可以直接用weight decay来实现。
update项中与权重 θ 有关的项为
而梯度变化越快的方向上,vt越大,而调整的项越小,即在这个方向上被正则化的越少,这显然是不合理的;此外,L2 Norm 与 weight decay 应该是各向同性的。而为了降低过拟合,达到和L2 Norm 同样的效果,一种改进就是将权重衰减(square weight loss)与 梯度下降解耦,在梯度下降完成后再进行权重衰减(下图绿色部分)
Adam with L2 regularization and AdamW
学习率
下面讲讲学习率,bert中的学习率是一个两段线性学习率:
首先,在前10%的steps中,lr从0线性增加到 init_learning_rate,这个阶段又叫 warmup,然后,lr又从 init_learning_rate 线性衰减到0(完成所有steps)
首先,lr进行decay是为了降低后期震荡,提高稳定性,是一个常规手段了。而为什么前期需要warmup呢?
- 可以避免较早的对mini-batch过拟合,即较早的进入不好的局部最优而无法跳出;
2.保持模型深层的稳定性
具体可以参考warmup 为什么有效
此外,由于warmup要求前期保持较小的更新,所以Adam中由于前期会导致更新变小而需要进行的bias correct也可以去掉了
总结
以上就是bert中使用的优化算法相关内容,具体代码请参考https://github.com/google-research/bert中 bert/optimization.py
此外,我自己也有实现相关内容,repo:toolkit4nlp 欢迎三连
网友评论