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

深度学习优化算法:AdaGrad算法原文链接:动手学深度学习pytorch版:7.5AdaGrad算法github:https://github.com/ShusenTang/Dive-into-DL-PyTorch原论文:[1]Duchi,J.,Hazan,E.,&Singer,Y.(2011).Adaptivesubgradientmethodsforonlinelearningandstochasticoptimization.JournalofMachineLearningR

大家好,欢迎来到IT知识分享网。

原文链接:动手学深度学习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

请添加图片描述
下面将学习率增大到2。可以看到自变量更为迅速地逼近了最优解。

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

输出:

epoch 20, x1 -0.002295, x2 -0.000000

请添加图片描述

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/22810.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信