指数加权平均与偏差修正

指数加权平均

指数加权平均也叫指数加权移动平均,是一种常见的序列数据处理方式,计算公式如下:

at=βat1+(1β)bta_t = \beta a_{t-1} + (1-\beta) b_t

在上式中,

  • btb_t表示第t天的观测值;
  • ata_t是要代替btb_t的估计值,也就是第t天的指数加权平均值;
  • β\beta表示at1a_{t-1}的权重,是可调节的超参。

简单来说,就是用ata_t作为btb_t的估计值,这种方法可以抚平短期波动,起到平滑的作用。

为什么叫做指数加权平均?

若将at,a_t,展开,可以得到下式:

at=(1β)bt+(1β)βbt1+(1β)β2bt2++(1β)βt1b1a_t = (1-\beta)b_t + (1-\beta)*\beta b_{t-1} + (1-\beta)*\beta^2 b_{t-2} + \dots + (1-\beta)*\beta^{t-1} b_{1}

加权系数随着时间以指数形式递减,时间越靠近,权重越大,越靠前,权重越小。若当β=0.9\beta=0.9时,0.9100.351e0.9^{10}\approx 0.35 \approx \frac{1}{e},若依次为界,权重衰减到这个值以下忽略不计,那么此时指数加权平均就是10天的平均值,推广到一般情况就是11β\frac{1}{1-\beta}

偏差修正

偏差修正的主要目的是为了提高指数加权平均的精确值,主要针对前期加权平均值的计算精度。

在上式中,a0a_0的初始值设为0,这造成了前期指数加权平均存在较大误差(相当于对当前值做了一个近似1β1-\beta的衰减),所以通过偏差修正来减少前期指数加权平均的误差。具体做法是对ata_t除以1βt1-\beta^t,则修正后的公式为:

at=at1βta_t = \frac{a_t}{1-\beta^t}

前期可以平衡btb_t前的权重,后期1βt1-\beta^t趋于1,偏差修正对指数加权平均没有影响。

梯度下降的三种形式

Batch Gradient Descent (BGD)

采用整个训练集的数据来计算目标函数对参数的梯度。

这种方法需要存储整个数据集,计算起来比较慢;对于凸函数可以收敛到全局极小值,对于非凸函数可以收敛到局部极小值。

Stochastic Gradient Descent (SGD)

SGD更新时对每个样本进行梯度更新,没有冗余,运算较快,并且方便在线学习;

SGD的噪声较BGD多使得每次迭代不能总向着整体最优方向,准确度下降,并不是全局最优。

Mini-Batch Gradient Descent (MBGD)

每次利用一小批样本进行更新,可以降低参数更新时的方法,收敛更稳定,同时可以利用矩阵操作进行更有效的梯度计算。

MBGD不能保证很好的收敛性,学习率的影响较大,学习率太大会在极小值处来回震荡,学习率太小,收敛速度会很慢。

什么是优化器?

优化器就是在反向传播过程中,指引网络模型的各个参数往正确的方向更新合适的大小,使得更新后的参数让目标函数值不断逼近全局最小。

一般过程为,首先定义变量,ω\omega表示待优化参数,f(x)f(x)表示目标函数,α\alpha表示初始学习率,tt表示epoch。

  1. 计算目标函数关于当前参数的梯度

gt=f(ωt)g_t = \nabla f(\omega_t)

  1. 根据历史梯度就算一阶动量和二阶动量

mt=ϕ(g1,g2,g3,,gt)Vt=i=0txi2m_t= \phi(g_1,g_2,g_3,\dots,g_t)\\ V_t= \sum_{i=0}^tx_i^2

  1. 计算当前时刻的下降梯度

ηt=αmtVt\eta_t=\alpha \frac{m_t}{\sqrt{V_t}}

  1. 根据下降梯度更新参数

ωt+1=ωtηt\omega_{t+1} = \omega_{t} - \eta_t

常见优化器

SGD

每次随机选择一个样本进行学习,没有动量概念,因此

mt=gtVt=I2m_t=g_t\\V_t=I^2

每次更新为

ωt+1=ωtαgt\omega_{t+1}=\omega_{t}-\alpha g_t

优点:

  • 每次只用一个样本更新模型参数,训练速度快
  • 随机梯度下降所带来的波动有利于优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,这样对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。

缺点:

  • 当遇到局部最优点或鞍点时,梯度为0,无法继续更新参数
  • 沿陡峭方向震荡,而沿平缓维度进展缓慢,难以迅速收敛

SGD with Momentum

为了抑制SGD的震荡,加入了惯性,即一阶矩

mt=β1mt1+(1β1)gtm_t=\beta_1 m_{t-1} + (1-\beta_1) g_t

更新公式为

ωt+1=ωtα(β1mt1+(1β1)gt)\omega_{t+1} = \omega_{t} - \alpha (\beta_1 m_{t-1} + (1-\beta_1) g_t)

一阶矩就是各个时刻梯度的指数移动平均值,也就是此时刻梯度更新的方向有此时刻梯度的方向与此前积累的下降的方向决定。

此方法缓解了SGD在鞍点梯度为0无法更新的问题,和振荡过大的问题,但是当局部最优点沟壑较深,动量加持耗尽的情况下,依然会困在局部最优点。

NAG

改进点在于当前的梯度方向由累积动量决定,

gt=f(ωtαmt1Vt1)g_t = \nabla f(\omega_t - \alpha \frac{m_{t-1}}{\sqrt{V_{t-1}}} )

此方法有利于跳出当前局部最优的沟壑,寻找新的最优值,但是收敛速度慢。

AdaGrad

加入了二阶动量,自适应学习率,对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。

对于二阶动量,采用

Vt=i=0tgi2V_t = \sum_{i=0}^t g_i^2

更新公式为:

ωt+1=ωtαmti=0tgi2\omega_{t+1} = \omega_t - \alpha \frac{m_t}{\sqrt{\sum_{i=0}^t g_i^2}}

一般会在分母上加上一个小的平滑项,Vt\sqrt{V_t}恒大于0,参数更新越频繁,二阶动量越大,学习率就越小。

优点:

  • 在稀疏数据场景下表现非常好
  • 开启了自适应学习率算法的里程

缺点:

  • 优于Vt\sqrt{V_t}单调递增,会使学习率单调递减至0,可能会使训练过程提前结束。

AdaDelta / RMSProp

由于AdaGrad单调递减的学习率变化过于激进,考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度,即采用指数移动平均值来计算二阶累积动量。

Vt=β2Vt1+(1β2)gt2V_t = \beta_2 V_{t-1} + (1-\beta_2) g_t^2

更新公式为:

ωt+1=ωtαmtβ2Vt1+(1β2)gt2\omega_{t+1} = \omega_t - \alpha \frac{m_t}{\sqrt{\beta_2 V_{t-1} + (1-\beta_2) g_t^2}}

此方法避免了二阶动量持续累积、导致训练过程提前结束的问题

Adam

SGD-M加入了一阶动量,AdaGrad和AdaDelta加入了二阶动量,Adam把一阶动量和二阶动量都用了起来。

更新公式为:

ωt+1=ωtαβ1mt1+(1β1)gtβ2Vt1+(1β2)gt2\omega_{t+1} = \omega_t - \alpha \frac{\beta_1 m_{t-1} + (1-\beta_1) g_t}{\sqrt{\beta_2 V_{t-1} + (1-\beta_2) g_t^2}}

两个超参数β1\beta1β2\beta2,前者控制一阶动量,后者控制二阶动量。

通过一阶动量和二阶动量,有效控制学习率步长和梯度方向,防止梯度的振荡和在鞍点的静止。

缺点:

  • 可能不收敛:二阶动量是固定时间窗口内的累积,随着时间窗口的变化,遇到的数据可能发生巨变使得二阶动量不是单调变化的,在后期可能引起学习率的动荡,倒是模型不收敛。修正方法是最二阶动量的变化进行控制,避免上下波动。

Vt=max(β2Vt1+(1β2)gt2,Vt1)V_t = max(\beta_2 V_{t-1}+(1-\beta_2) g_t^2, V_{t-1} )

  • 可能错过全局最优解:自适应学习率算法可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。后期Adam的学习率太低,影响了有效的收敛。

优化算法选择与使用策略

  • 优先考试SGD、NAG与Adam;
  • 如果模型是非常稀疏的,优先考虑自适应学习率算法;
  • 在快速验证新模型效果的时候,可以先用Adam进行快速实验优化;在模型上线或者结果发布前,可以精调SGD进行模型的极致优化;
  • 先用小数据集进行实验。有论文研究指出,随机梯度下降算法的收敛速度和数据集的大小的关系不大。
  • 考虑不同算法的组合。先用Adam进行快速下降,而后再换到SGD进行充分的调优。
  • 数据集一定要充分的打散(shuffle)。这样在使用自适应学习率算法的时候,可以避免某些特征集中出现,而导致的有时学习过度、有时学习不足,使得下降方向出现偏差的问题。
  • 训练过程中持续监控训练数据和验证数据上的目标函数值以及精度或者AUC等指标的变化情况。对训练数据的监控是要保证模型进行了充分的训练——下降方向正确,且学习率足够高;对验证数据的监控是为了避免出现过拟合。
  • 制定一个合适的学习率衰减策略。可以使用定期衰减策略,比如每过多少个epoch就衰减一次;或者利用精度或者AUC等性能指标来监控,当测试集上的指标不变或者下跌时,就降低学习率。

参考资料

深度学习优化器算法
优化器(Optimizer)