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

本文介绍了AdaDelta优化算法,它是RMSProp的一种变体,解决了AdaGrad学习率逐渐下降的问题。AdaDelta算法不需要设置学习率,通过使用自变量更新量的指数加权移动平均来调整更新步长。文章提供了从零开始的PyTorch实现及简洁版本,并展示了训练过程。
摘要由CSDN通过智能技术生成

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

原论文:
[1] Zeiler, M. D. (2012). ADADELTA: an adaptive learning rate method. arXiv preprint arXiv:1212.5701.

AdaDelta算法

除了 RMSProp 算法以外,另一个常用优化算法 AdaDelta 算法也针对 AdaGrad 算法在迭代后期可能较难找到有用解的问题做了改进 [1]。有意思的是,AdaDelta 算法没有学习率这一超参数。

算法

AdaDelta 算法也像 RMSProp 算法一样,使用了小批量随机梯度 g t g_t gt 按元素平方的指数加权移动平均变量 s t s_t st 。在时间步0,它的所有元素被初始化为0。给定超参数 0 ≤ ρ < 10 0≤\rho<10 0ρ<10(对应RMSProp算法中的 γ \gamma γ),在时间步 t > 0 t>0 t>0,同 RMSProp 算法一样计算
s t ← ρ s t − 1 + ( 1 − ρ ) g t ⊙ g t {{\text{s}}_{t}}\leftarrow \rho {{s}_{t-1}}+(1-\rho ){{g}_{t}}\odot {{g}_{t}} stρst1+(1ρ)gtgt

与RMSProp算法不同的是,AdaDelta算法还维护一个额外的状态变量 Δ x t \Delta {{x}_{t}} Δxt,其元素同样在时间步0时被初始化为0。我们使用 Δ x t − 1 \Delta {{x}_{t-1}} Δxt1 来计算自变量的变化量:
g ′ t ← Δ x t − 1 + ε s t + ε ⊙ g t g{{'}_{t}}\leftarrow \sqrt{\frac{\Delta {{x}_{t-1}}+\varepsilon }{{{s}_{t}}+\varepsilon }}\odot {{g}_{t}} gtst+εΔxt1+ε gt

其中 ϵ \epsilon ϵ 是为了维持数值稳定性而添加的常数,如 1 0 − 5 10^{-5} 105。接着更新自变量:
x t ← x t − 1 − g ′ t {{x}_{t}}\leftarrow {{x}_{t-1}}-g{{'}_{t}} xtxt1gt

最后,我们使用 Δ x t \Delta {{x}_{t}} Δxt 来记录自变量变化量 g t ′ g'_t gt 按元素平方的指数加权移动平均:
Δ x t ← ρ Δ x t − 1 + ( 1 − ρ ) g ′ t ⊙ g ′ t \Delta {{x}_{t}}\leftarrow \rho \Delta {{x}_{t-1}}+(1-\rho )g{{'}_{t}}\odot g{{'}_{t}} ΔxtρΔxt1+(1ρ)gtgt

可以看到,如不考虑 ϵ \epsilon ϵ 影响,AdaDelta 算法跟 RMSProp 算法的不同之处在于使用 Δ x t − 1 \sqrt{Δx_{t-1}} Δxt1 来代替学习率 η η η

从零开始实现

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

features, labels = d2l.get_data_ch7()

def init_adadelta_states():
    s_w, s_b = torch.zeros((features.shape[1], 1), dtype=torch.float32), torch.zeros(1, dtype=torch.float32)
    delta_w, delta_b = torch.zeros((features.shape[1], 1), dtype=torch.float32), torch.zeros(1, dtype=torch.float32)
    return ((s_w, delta_w), (s_b, delta_b))

def adadelta(params, states, hyperparams):
    rho, eps = hyperparams['rho'], 1e-5
    for p, (s, delta) in zip(params, states):
        s[:] = rho * s + (1 - rho) * (p.grad.data**2)
        g =  p.grad.data * torch.sqrt((delta + eps) / (s + eps))
        p.data -= g
        delta[:] = rho * delta + (1 - rho) * g * g

d2l.train_ch7(adadelta, init_adadelta_states(), {'rho': 0.9}, features, labels)

输出:

loss: 0.243535, 0.057486 sec per epoch

请添加图片描述

简洁实现

d2l.train_pytorch_ch7(torch.optim.Adadelta, {'rho': 0.9}, features, labels)

输出:

loss: 0.304975, 0.058008 sec per epoch

请添加图片描述

小结

  • AdaDelta算法没有学习率超参数,它通过使用有关自变量更新量平方的指数加权移动平均的项来替代RMSProp算法中的学习率。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值