# Adagrad

将优化算法的框架搬来. 首先定义符号. $$w$$为待优化参数, $$f(w)$$为目标函数, $$\alpha$$为初始学习率.

在每步$$t$$中:

1. 计算目标函数关于当前参数$$w\_t$$的梯度: $$g\_{t}=\nabla f\left(w\_{t}\right)$$
2. 根据历史梯度$$g\_{1}, g\_{2}, \cdots, g\_{t}$$计算一阶动量和二阶动量: $$m\_{t}=\phi\left(g\_{1}, g\_{2}, \cdots, g\_{t}\right)$$; $$V\_{t}=\psi\left(g\_{1}, g\_{2}, \cdots, g\_{t}\right)$$
3. 计算当前时刻的下降梯度: $$\eta\_{t}=\alpha \cdot m\_{t} / \sqrt{V\_{t}}$$
4. 根据下降梯度更新参数: $$w\_{t+1}=w\_{t}-\eta\_{t}$$

## Adagrad

从Adagrad开始, 将**自适应学习率**引入到优化算法中. 自适应学习率指的是对于网络中的每个参数, 其学习率都是不同的, 而且是自动调整适应的. 这对于网络的优化是很有帮助的. 神经网络中的参数很多, 且角色不同. 对于经常更新的参数, 我们已经积累了大量关于它的知识, 不希望被单个样本影响太大, 希望学习速率慢一些; 对于偶尔更新的参数, 我们了解的信息太少, 希望能从每个偶然出现的样本身上多学一些, 即学习速率大一些.

这样自适应学习率与就与参数的**历史更新频率**联系在了一起. 怎样去衡量更新频率, 使用**二阶动量**, 即该参数迄今为止所有梯度的平方和:

$$V\_{t}=\sum\_{\tau=1}^{t} g\_{\tau}^{2}=V\_{t-1} + g\_{t}^{2}$$

二阶动量是在框架的第三部引入的:

$$\eta\_{t}=\alpha \cdot m\_{t} / \sqrt{V\_{t}}$$

上式相当于学习率由$$\alpha$$变成了$$\frac{\alpha}{\sqrt{V\_{t}}}$$. 为了避免分母为0, 一般会在分母上加上一个小的平滑项$$\frac{\alpha}{\sqrt{V\_{t}+\varepsilon}}$$.

可以看到, 参数更新的幅度越大, 即参数更新的越频繁, 二阶动量就越大, 学习率就越低, 实现了对不同表现的参数的差异化学习.

### 优点

* 当梯度更新较大时, 能够约束梯度; 更新较小时, 能够放大梯度, 加快收敛
* 对于稀疏数据处理较好

### 问题

* $$\sqrt{V\_{t}}$$是单调递增的, 会使得学习率逐渐递减至0, 可能会导致训练的提前结束
* 仍需要设置全局的学习率$$\alpha$$
