目录
老饼讲解:一步一步上手学习

【优化】一篇入门之-AdaDelta-算法

作者 : 老饼 发表日期 : 2025-12-17 00:04:01 更新日期 : 2026-05-11 01:04:47
老饼讲解-简单易懂,干货满满,爽过嗦螺!


AdaDelta是2012年提出的一种优化算法,它是一种完完全全不需要设置学习率的算法,它在RMProp算法的基础上加入了Delta量,从而使得整个训练算法完全自动化,下面就让我们一起来看看AdaDelta算法到底是怎么干的吧!

一、AdaDelta算法-原理与公式

AdaDelta算法是RMProp算法的一种改进,事实上,AdaGrad、RMSProp、AdaDelta算法是层层改进,它们的根本目的都是解决梯度下降法中学习率的自适应问题,由于它们是层层改进,建议将它们按顺序阅读,解理起来就会非常简单和流畅。

1.1. AdaDelta算法-更新公式

好了,继续来说AdaDelta算法,AdaDelta算法是在RMProp算法的基础上,去掉学习率,使得算法完全不需要设置学习率,更加"自适应"化。不妨记待优化的第个参数为,则,AdaDelta算法的更新公式如下:

   

其中,:参数的梯度                               

  :衰减系数,取值范围为[0,1] 

                  :初始值为0,它实际就是的累计平方和

                             :初始值为0,它实际就是参数变化量的累计平方和

                      :一个极小的常数,它的作用避免分母为0 

AdaDelta与RMProp类似,只是它用来替代了RMProp算法中的学习率,AdaDelta通过引入,解决了AdaGrad、RMProp依赖学习率的问题,使得算法的学习率更加"自适应"化。

AdaDelta的更新公式共有4个式子,看着有点乱,其实它跟RMProp是很类似的,我们逐步来解说。

1.2. AdaDelta算法-更新公式-解说

先说(1)式,它跟RMProp中的公式是一样的,也就是的原始目的就是用来累计,然后又担心会越来越大,所以加入衰减系数,使它成为(历史累积)与新的加权和,从而勉强无限增长,这里计算是为了用来评估的梯度的量级大概是多少。

再说(2)式,它计算的是的更新量,可以把它写为,这里不妨忽略掉,因为它是为了避免数值问题而已。那么它就是将梯度除以,来去掉量级上的区别,然后以作为学习率,好了,这个就是AdaDelta算法的特色了,也就是它并不是设置一个固定的学习率,而是用一个自适应的量(AdaDelta)来作为学习率,下面我们在(4)式中再来看这个是怎么来的。

(3)式就不用说了,就是用更新量来更新

最后就是(4)式,它与(1)式其实是类似的,只不过它记录的是更新量的累计平方和,进一步地,与(1)式一样,直接记录的累计平方和会无限增长,所以加入了衰减系数,按(1)式来理解它就好了,总的来说计算它就是为了用来评估更新量的量级。

所以总的来说,核心就在于(2)式,也就是的更新量,它先用来消除梯度的量级差别,然后再以的历史更新量的量级来作为本次的学习率。

二、AdaDelta算法-代码与实现

下面我们来实现一下AdaDelta算法,配合代码,就非常具体的理解AdaGrad算法了。

2.1. AdaDelta-代码

不妨设目标函数为:

下面我们使用AdaDelta算法来求它的最小值。

由于AdaDelta算法需要使用目标函数的梯度,所以需要先算出梯度,如下:

  ,

求出梯度后我们就可以编写代码了,AdaDelta算法的具体实现代码如下:

"""
本代码展示AdaDelta算法求y= (x1-2)^2+(x2-3)^2的最小解
本代码来自《老饼讲解-机器学习》www.bbblearn.com 
"""
import numpy as np
x   = np.array([0,0])                                               # 初始化x
rho = 0.9                                                           # 设置衰减系数
s   = np.array([0,0])                                               # 初始化梯度累计量
delta   = np.array([0,0])                                           # 初始化x调整累计量
esp = 0.000001                                                      # 很小的常数
for i in range(1000):                                               # 最大迭代1000次
    g  = np.array([2*x[0]-4, 2*x[1]-6])                             # 计算x的梯度  
    s  = rho*s + (1-rho)*g*g                                        # 计算梯度累计量
    dx =  np.sqrt((delta+esp)/(s+esp))*g                            # x的调整量
    x  = x - dx                                                     # 更新x
    delta  = rho*delta + (1-rho)*dx*dx                              # 更新x调整累计量
    y = (x[0]-2)**2+(x[1]-3)**2                                     # 当前函数值
    print("第 %d 轮迭代:x=[%.4f,%.4f],y=%.5f"%(i+1,x[0],x[1],y))    # 打印当前结果
    if((max(abs(g))< 0.0001) ):break                                # 如果梯度过小,则退出迭代

运行结果如下:

AdaDelta优化结果

可以看到,经过了844轮迭代,所得到解已经非常接近真实极小解[2,3] 。

2.2. AdaDelta的特点

如果对比AdaGrad、RMSProp、AdaDelta算法的结果,就会发现AdaDelta需要的迭代步数特别多,这是因为AdaDelta的学习率完全是靠调节,不管是梯度的量级估算、还是学习率的量级估算都需要通过长期的积累,所以在我们例子中的这种超短任务中就不占优势。而对于长期任务,AdaDelta的好处就体现出来了,它完全不需要设置学习率,会自动调节。

总结

AdaGrad算法就是一种完全不需要设置学习率的学习算法,这种自适应体现在两方面,一个是梯度的量级、另一个是基础学习率的量级,它都依靠估算来自动调节,所以完全不需要设置学习率。



图标 评论
添加评论