AdaGrad

SGD系列的都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种以同样的学习率更新每个参数,但深度神经网络往往包含大量的参数,这些参数并不是总会用得到。对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。因此,Adagrad 非常适用于稀疏数据。

Dean 等人发现 Adagrad 能够大幅提高 SGD 的鲁棒性,并在 Google 用其训练大规模神经网络,这其中就包括 在 YouTube 中学习识别猫。除此之外,Pennington 等人用 Adagrad 来训练 GloVe 词嵌入,因为罕见的词汇需要比常见词更大的更新。

AdaGrad算法就是将每一个参数的每一次迭代的梯度取平方累加后在开方,用全局学习率除以这个数,作为学习率的动态更新。对于不同的参数动态的采取不同的学习率,让目标函数更快的收敛。为了简洁,我们用\(g_{t}\)来表示t时刻的梯度,\(g_{t,i}\)就是目标函数的偏导数:

\[g_{t,i}=\nabla_{\theta}J(\theta_{t,i})\]

SGD在在每个时刻t对参数\(\theta_{i}\)的更新为:

\[\theta_{t+1,i}=\theta_{t,i}-\eta \cdot g_{t,i}\]

Adagrad修改了t时刻对于每个参数\(\theta_{i}\)的学习率\(\eta\):

\[\theta_{t+1,i}=\theta_{t,i}-\frac{\eta}{\sqrt{G_{t,ii}+\epsilon}} \cdot g_{t,i}\]

其中\(G_{t}\in R^{d \times d}\)是对角矩阵,其中每一个对角元素i,i是\(\theta_{i}\)在时刻t的梯度平方和,一般为了避免分母为0,会在分母上加一个小的平滑项,用符号\(\epsilon\)表示,通常为\(10^{-8}\) 左右。因此\(\sqrt{G_{t}+\epsilon} \)恒大于0,而且参数更新越频繁,二阶动量越大,学习率就越小。有趣的是,如果去掉开方操作,算法性能会大幅下降。

优点

  • 在稀疏数据场景下表现非常好

  • 此前的SGD及其变体的优化器主要聚焦在优化梯度前进的方向上,而AdaGrad首次使用二阶动量来关注学习率(步长),开启了自适应学习率算法的里程。大多数实现使用一个默认值 0.01 。

缺点

  • \(\sqrt{G_{t}+\epsilon}\)是单调递增的,会使得学习率单调递减至0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的知识。