深度学习优化算法:AdaGrad算法

原文链接:动手学深度学习pytorch版:7.5 AdaGrad算法
github:https://github.com/ShusenTang/Dive-into-DL-PyTorch

原论文:
[1] Duchi, J., Hazan, E., & Singer, Y. (2011). Adaptive subgradient methods for online learning and stochastic optimization. Journal of Machine Learning Research, 12(Jul), 2121-2159.

AdaGrad算法

在动量法中我们看到当 x 1 x_1 x1 x 2 x_2 x2 的梯度值有较大差别时,需要选择足够小的学习率使得自变量在梯度值较大的维度上不发散。但这样会导致自变量在梯度值较小的维度上迭代过慢。动量法依赖指数加权移动平均使得自变量的更新方向更加一致,从而降低发散的可能。AdaGrad算法,它根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题

算法

AdaGrad算法会使用一个小批量随机梯度 g t g_t gt 按元素平方的累加变量 s t s_t st。在时间步0,AdaGrad将 s 0 s_0 s0 中每个元素初始化为0。在时间步 t t t,首先将小批量随机梯度 g t g_t gt 按元素平方后累加到变量 g t g_t gt
s t ← s t − 1 + g t ⊙ g t {{\text{s}}_{t}}\leftarrow {{s}_{t-1}}+{{g}_{t}}\odot {{g}_{t}} stst1+gtgt

其中 ⊙ \odot 是按元素相乘。接着,我们将目标函数自变量中每个元素的学习率通过按元素运算重新调整一下:
x t ← x t − 1 − η s t + ε ⊙ g t {{x}_{t}}\leftarrow {{x}_{t-1}}-\frac{\eta }{\sqrt{{{s}_{t}}+\varepsilon }}\odot {{g}_{t}} xtxt1st+ε ηgt

其中 η η η 是学习率, ε \varepsilon ε 是为了维持数值稳定性而添加的常数,如 1 0 − 6 10^{-6} 106。这里开方、除法和乘法的运算都是按元素运算的。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率。

特点

如果目标函数有关自变量中某个元素的偏导数一直都较大,那么该元素的学习率将下降较快;反之,如果目标函数有关自变量中某个元素的偏导数一直都较小,那么该元素的学习率将下降较慢。

缺点:
由于 s t s_t st 一直在累加按元素平方的梯度,自变量中每个元素的学习率在迭代过程中一直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。

例子

下面以目标函数 f ( x ) = 0.1 x 1 2 + 2 x 2 2 f(x)=0.1x^2_1+2x^2_2 f(x)=0.1x12+2x22 为例观察 AdaGrad 算法对自变量的迭代轨迹。我们实现 AdaGrad 算法并设置学习率0.4。可以看到,自变量的迭代轨迹较平滑。但由于 s t s_t st 的累加效果使学习率不断衰减,自变量在迭代后期的移动幅度较小。

而且出现了上述问题,学习率初始设置太小,移动幅度到后面越来越小,很难接近最优解。

%matplotlib inline
import math
import torch
import sys
sys.path.append("..") 
import d2lzh_pytorch as d2l
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

def adagrad_2d(x1, x2, s1, s2):
    g1, g2, eps = 0.2 * x1, 4 * x2, 1e-6  # 前两项为自变量梯度
    s1 += g1 ** 2
    s2 += g2 ** 2
    x1 -= eta / math.sqrt(s1 + eps) * g1
    x2 -= eta / math.sqrt(s2 + eps) * g2
    return x1, x2, s1, s2

def f_2d(x1, x2):
    return 0.1 * x1 ** 2 + 2 * x2 ** 2

eta = 0.4
d2l.show_trace_2d(f_2d, d2l.train_2d(adagrad_2d))

输出:

epoch 20, x1 -2.382563, x2 -0.158591

深度学习优化算法:AdaGrad算法_第1张图片
下面将学习率增大到2。可以看到自变量更为迅速地逼近了最优解。

eta = 2
d2l.show_trace_2d(f_2d, d2l.train_2d(adagrad_2d))

输出:

epoch 20, x1 -0.002295, x2 -0.000000

深度学习优化算法:AdaGrad算法_第2张图片

你可能感兴趣的:(NLP/ML/DL,pytorch,深度学习,优化算法,AdaGrad)