深度学习常用优化器
前置知识:梯度计算、指数加权平均
1. 背景
为深度学习模型选择合适的 optimizer 不是一项容易的任务。Pytorch、Tensorflow、Paddle 等深度学习库都提供了多种优化器,它们各有优缺点,选择合适的优化器能够提高训练效果、收敛速度等。因此,optimizer 是搭建、优化和部署深度学习模型过程中的关键一环。
2. 常用优化器
接下来,介绍几种常见的优化器。用 代表权重参数, 代表梯度,
2.1 基础
2.1.1 BGD (Batch Gradient Descent)
规则:计算整个数据集后执行一次梯度更新
缺点:训练非常慢。对于很大的数据集来说,可能会有相似的样本,BGD 在计算梯度时会出现冗余。此外还不能加入新数据实时更新模型。
2.1.2 SGD (Stochastic Gradient Descent)
规则:对每个样本进行一次梯度更新
优点:和 BGD 相比,能够解决冗余问题,训练速度比较快,并且可以新增样本。
缺点:SGD 的噪音较 BGD 要多,使得迭代过程中会出现频繁震荡。所以虽然训练速度加快了,但是稳定性也下降了。
2.1.3 MBGD (Mini-Batch Gradient Descent)
规则: 每次利用一小批样本进行梯度更新
优点:可以降低参数更新时的方差,收敛更稳定。并且,深度学习库对矩阵运算进行了高度优化,可以非常高效计算梯度。
(之后提及的 SGD 多指 MBGD 优化器)
2.1.4 局限性
a. 在最小化非凸损失函数时,陷入局部最小值,或者停留在鞍点。因为该点处的梯度接近于0,以上三种梯度更新方法都很难逃脱。有时候可以修改学习率来减缓这种情况的发生,但是选择合适的学习率十分困难。学习率太小会导致收敛时间过长,而学习率过大又会阻碍收敛导致损失函数在最小值附近波动甚至发散。先前的方法是根据预定义的时间表或者目标函数变化调整学习率。但是,这些计划和阈值必须预先定义,因此无法适应数据集的特征。
b. 采用相同学习率更新所有参数。如果数据集稀疏,可能并不想将所有模型特征更新到相同的程度,且对很少出现的特性执行较大的更新。
2.2 进阶
针对局限性 a,这里介绍了 Momentum 和 Nesterov Accelerated Gradient,对于局限性 b,介绍了 AdaGrad、RMSprop 和 Adam。
2.1.1 Momentum
假如我们最小化目标函数的任务,是从坡顶到坡底的过程,如下图所示。SGD 难以在沟壑中有效移动,会频繁震荡,沿着底部最优的方向缓慢下降,如下左图所示。当我们将一个小球从山上滚下来时,没有阻力的话,它的动量会越来越大,但是如果遇到了阻力,就会变小。
规则:在 SGD 中引入了 Momentum
如上右图所示,加入的这一项,**可以使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢,这样就可以加快收敛并减小震荡。**用如下公式计算,
$
其中,超参数
2.1.2 NAG (Nesterov Accelerated Gradient)
然而,从山上滚下来的球盲目地跟随斜坡是不尽如人意的。我们希望有一个更聪明的球,快要上坡时,就知道需要减速了,适应性会更好。
NAG 是一种能够给 Momentum 带来上述能力的方法,将
同样,超参数
Momentum 和 NAG 的区别,如下图所示,
- 蓝色向量是 Momentum。首先计算当前的梯度值 ,然后再计算累计的动量 ,因此会有一个大跳跃,
- 其余向量都是描述 NAG。首先在先前累积梯度(棕色向量) 方向上前进一大步,再计算当前位置的梯度值 做一个修正(红色向量),从而完成 NAG 更新(绿色向量)。
这个具有预见性的更新参数方法,防止梯度前进得太快,同时增强了算法的适应能力,对于 RNN 的性能提升有着重要的意义。
目前为止,可以做到在更新模型权重时顺应损失函数的梯度进行调整,使 SGD 减弱震荡,加快收敛。接下来,就是希望根据每个参数的重要性,对不同的参数进行不同程度的更新。
2.1.3 AdaGrad (Adaptive Gradient Algorithm)
之前提到的优化器均是以相同的学习率去更新权重参数,而深度学习模型中往往涉及大量的参数,不同参数的更新频率也有所区别。因此, 采用了自适应的学习率,可以对低频的参数做较大的更新,对高频的做较小的更新。这样,对于稀疏数据收敛更快,很好地提高了
其中, 为 时刻参数 的梯度,这里的学习率随着时间 和参数 发生变化。 是到 时刻为止,梯度
推广到
简记为,
优点:无需手动调整学习率。
缺点:梯度平方的累加和会越来越大,导致学习率变小,模型也就提前更新不动了。
接下来的算法就是为了解决这个问题。
2.1.4 AdaDelta
和 AdaGrad 相比,不在计算某个参数历史所有梯度的平方和,而是计算梯度平方的指数加权平均,梯度缩放不太积极了(缩放系数增大较缓)。如下所示,在 时刻的均值
一般情况下,超参数
那么,就可以得到如下的更新公式,(也就是接下来要讲的 )
分母是梯度的均方根 ,每次梯度的更新量可以简记为,
但作者指出,以上谈到的所有优化器存在单位不匹配的问题,因此定义了另一个指数衰减均值,由参数变化量的平方计算:
参数变化量的均方根为,
利用 替换先前的更新中的学习率 ,得到 AdaDelta 的更新规则,
因此不需要设置学习率了。
2.1.5 RMSprop
和 都是为了解决 学习率急剧下降问题的。与 的第一种形式相同,某一维度的梯度比较大,则其均方根 就大(学习率越小),某一维度的梯度比较小,则其均方根
一般情况下,超参数
2.1.6 Adam
这个算法相当于 +
除了像 和 一样采用过去梯度平方的指数加权平均 ,也像
$v_{t}=\beta_{2} \cdot v_{t-1}+\left(1-\beta_{2}\right) \cdot g_{t}^{2} $
如果 和 被初始化为 0 向量,那它们就会偏向于 0 ,需要做偏差校正,来抵消这些偏差,
$\hat{m}{t}=\frac{m{t}}{1-\beta_{1}^{t}} $
所以,最后的参数更新计算如下所示,
一般情况下,超参数 和
将 、 和 方法结合到一起。每一步的方向由梯度的指数加权平均决定,步长由梯度平方的指数加权平均和超参数 (学习率)决定。此外,类似于 , 对梯度的每个维度进行重新缩放。 和 (或 )之间一个主要区别是对 和