11.10.1. 算法¶
Adam算法的关键组成部分之一是:它使用指数加权移动平均值来估算梯度的动量和二次矩,即它使用状态变量
(11.10.1)¶\[\begin{split}\begin{aligned}
\mathbf{v}_t & \leftarrow \beta_1 \mathbf{v}_{t-1} + (1 - \beta_1) \mathbf{g}_t, \\
\mathbf{s}_t & \leftarrow \beta_2 \mathbf{s}_{t-1} + (1 - \beta_2) \mathbf{g}_t^2.
\end{aligned}\end{split}\]
这里\(\beta_1\)和\(\beta_2\)是非负加权参数。
常将它们设置为\(\beta_1 = 0.9\)和\(\beta_2 = 0.999\)。
也就是说,方差估计的移动远远慢于动量估计的移动。
注意,如果我们初始化\(\mathbf{v}_0 = \mathbf{s}_0 = 0\),就会获得一个相当大的初始偏差。
我们可以通过使用\(\sum_{i=0}^t \beta^i = \frac{1 - \beta^t}{1 - \beta}\)来解决这个问题。
相应地,标准化状态变量由下式获得
(11.10.2)¶\[\hat{\mathbf{v}}_t = \frac{\mathbf{v}_t}{1 - \beta_1^t} \text{ and } \hat{\mathbf{s}}_t = \frac{\mathbf{s}_t}{1 - \beta_2^t}.\]
有了正确的估计,我们现在可以写出更新方程。
首先,我们以非常类似于RMSProp算法的方式重新缩放梯度以获得
(11.10.3)¶\[\mathbf{g}_t' = \frac{\eta \hat{\mathbf{v}}_t}{\sqrt{\hat{\mathbf{s}}_t} + \epsilon}.\]
与RMSProp不同,我们的更新使用动量\(\hat{\mathbf{v}}_t\)而不是梯度本身。
此外,由于使用\(\frac{1}{\sqrt{\hat{\mathbf{s}}_t} + \epsilon}\)而不是\(\frac{1}{\sqrt{\hat{\mathbf{s}}_t + \epsilon}}\)进行缩放,两者会略有差异。
前者在实践中效果略好一些,因此与RMSProp算法有所区分。
通常,我们选择\(\epsilon = 10^{-6}\),这是为了在数值稳定性和逼真度之间取得良好的平衡。
最后,我们简单更新:
(11.10.4)¶\[\mathbf{x}_t \leftarrow \mathbf{x}_{t-1} - \mathbf{g}_t'.\]
回顾Adam算法,它的设计灵感很清楚:
首先,动量和规模在状态变量中清晰可见,
它们相当独特的定义使我们移除偏项(这可以通过稍微不同的初始化和更新条件来修正)。
其次,RMSProp算法中两项的组合都非常简单。
最后,明确的学习率\(\eta\)使我们能够控制步长来解决收敛问题。