Adam优化器详解
最近在实验室搞的和某公司的校企合作面试中被问到有关Adam优化器的问题。笔者之前也总结过PyTorch中的几种常见优化器的接口和用法,但没有对原理进行详解。于是抽出时间对Adam优化器的细节进行了仔细的学习。
Adam的发展
Adam于2014年12月Kingma和Lei Ba两位学者提出,结合了AdaGrad和RMSProp的优点,对梯度的均值和方差进行综合考虑,计算更新的步长。
AdaGrad
我们都知道在一般的SGD算法中,参数每个维度都是依据相同的人为设定的梯度进行优化。
事实证明这种方法很多时候不能满足需要,这是由于不同维度上的梯度值并不一致。采取相同的学习率很多时候会造成某些梯度大的维度过早出现发散。
AdaGrad根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题。
AdaGrad优化器维护一个变量s_t, 并用这个变量来控制学习率的变化。如果用x表示参数,g表示梯度,则s_t的更新公式如下:
其中⊙表示逐个元素相乘,实际上就是得到了梯度的平方数值。很明显随着迭代次数的增加,s_t不断增加。
参数的更新公式如下:
其中η表示超参数基准学习率,ε通常设置为一个常数值,是为了保证数值的稳定,以及防止分母出现负值。该更新公式会随着迭代次数的增加不断降低学习率,同时由于s_t是一个长度为参数个输的向量,每个参数的学习率下降程度都是动态调整的。
通过pytorch进行一个简单的实现:
adagrad主要缺点在于当梯度较大的时候,s_t会迅速变大,从而导致η迅速减小。这可能使得模型的训练停滞不前,寻找不到最佳的结果。
RMSProp
RMSProp和AdaGrad十分类似,区别在于为了避免学习率过早地降得太低,采用了一个超参数γ来控制梯度数值对于s_t的影响:
当γ值较大的时候,s_t的变化也会较小,从而模型可以以比较均匀的速度优化。当γ值较小的时候,s_t变化比较剧烈,从而学习率也会迅速减小,模型可以放慢优化速度以寻找最优解。
γ的引入使得使用者可以更加方便地控制学习率移动的幅度, 这种方法被称为指数加权移动平均(exponentially weighted moving average)。
AdaDelta
另一种进行指数加权移动平均的算法是AdaDelta算法。在RMSProp的基础上,该算法不再需要提供η这个基础学习率超参数。而是对参数的实际变化值进行指数加权移动平均。如下所示:
Δx初始化为0,然后通过下式进行迭代更新:
其中g'是经过学习率调整后的实际参数变化值。ρ和γ通常取相同的值。
Adam算法具体思路和实现
Adam(Adaptive moment estimation)算法是综合了RMSProp中的指数加权平均和SGD中的动量法思路。Adam采用两个不同的超参数β1和β2来控制动量以及RMSP中s_t的更新。
此外通过计算设计者发现在t时刻,各时刻动量的权值之和为1 - β1^t。为了保证在t较小时该值也能接近1,Adam算法会进行一次梯度修正。即:
每一轮实际梯度为
Adam综合了动量法和指数加权平均的办法。从而也就综合了两者的优点。前者是参考了物理学中动量的概念,使得过去的梯度下降结果对本次梯度产生一定的影响,后者则是一定程度上避免了参数更新的发散。
最后更新于