梯度下降法及系列变体介绍

本文介绍了梯度下降法及其各种变体,包括一维和多维梯度下降、随机梯度下降、小批量随机梯度下降。动量法通过指数加权平均解决了不同方向更新幅度不一致的问题,而AdaGrad、RMSProp和AdaDelta则通过调整学习率适应不同维度的更新。最后,Adam算法结合了动量法和RMSProp的优点,通过偏差修正保持学习率的稳定性。这些算法在深度学习和优化问题中扮演着重要角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次通过书本系统学到梯度下降法和相关的变体算法,记录下自己的经历,以后方便查阅,这里只记录算法,不追究数学上的准确描述。

目录

1、一维梯度下降

2、多维梯度下降

3、随机梯度下降(stochastic gradient descent)

4、小批量随机梯度下降(mini-batch stochastic gradient descent)

5、动量法(momentum)

6、AdaGrad 

7、RMSProp

8、AdaDelta

9、Adam

总结


1、一维梯度下降

假设有连续可导的函数f:\mathbb{R} \rightarrow \mathbb{R},其输入和输出均为标量,给定足够小的数\varepsilon,根据泰勒公式可以得到如下近似:

f(x+\varepsilon) \approx f(x) + \varepsilon f'(x)

这里f'(x)就是函数在该处的梯度,一维情况下就是导数。

\varepsilon = -\eta f'(x),\eta >0,上式可以写为:

 f(x-\eta f'(x)) \approx f(x) - \eta f'(x)^2

当导数f'(x) \ne 0,那么f(x - \eta f'(x)) \lesssim f(x),这表示通过令x\leftarrow x - \eta f'(x)进行迭代,则函数值有下降的趋势。

数学上的解释:梯度方向是函数值增长最快的方向,沿着梯度方向的反方向就是函数值下降最快的方向。

上述迭代格式中的\eta称为学习率,用于控制每次自变量变化的幅度,太小则会导致自变量变化太慢,从而需要更多次迭代来获得较好的解;太大则会导致泰勒公式不再成立,此时无法保证迭代格式会使函数值下降。

2、多维梯度下降

假设目标函数f:\mathbb{R}^d \rightarrow \mathbb{R}的输入为d维向量\boldsymbol{x}=(x_1,x_2,\cdots,x_d)^T,目标函数关于输入的梯度为偏导数组成的向量:

\nabla f(\boldsymbol{x})=\nabla_x f(\boldsymbol{x})= \left(\frac{\partial f(\boldsymbol{x})}{\partial x_1}, \frac{\partial f(\boldsymbol{x})}{\partial x_2}, \cdots, \frac{\partial f(\boldsymbol{x})}{\partial x_d}\right)^T

那么更新策略为:\boldsymbol{x} \leftarrow \boldsymbol{x} - \eta \nabla f(\boldsymbol{x})

3、随机梯度下降(stochastic gradient descent)

深度学习中,损失函数一般为训练集中各个样本的损失函数的平均。设f_i (\boldsymbol{x})为第i个训练样本的损失函数,n为训练集的样本总数,那么问题总的损失函数一般表示为:

f(\boldsymbol{x}) = \frac{1}{n}\sum^{n}_{i=1}f_i (\boldsymbol{x})

 如果计算梯度:

\nabla f(\boldsymbol{x}) = \frac{1}{n}\sum^{n}_{i=1} \nabla f_i(\boldsymbol{x})

因此计算开销为\mathcal{O}(n),当样本数很大时会产生很大的计算量。

随机梯度下降正是为了解决这个问题。在每次迭代时,我们不按照上式计算梯度,而是在训练样本中随机采样一个样本k \in \{1, 2, \cdots,n\}进行梯度计算,并更新自变量:

\boldsymbol{x} \leftarrow \boldsymbol{x} - \eta \nabla f_k(\boldsymbol{x})

此时计算开销变为\mathcal{O}(1)。另外,随机梯度\nabla f_k(\boldsymbol{x}) 恰好是对梯度\nabla f(\boldsymbol{x})的无偏估计:

E_k \nabla f_k(\boldsymbol{x})=\frac{1}{n}\sum^{n}_{k=1}\nabla f_k (\boldsymbol{x})=\nabla f(\boldsymbol{x})

这意味着随机梯度是梯度的良好估计。

4、小批量随机梯度下降(mini-batch stochastic gradient descent)

梯度下降使用全部的训练样本计算梯度,有时被称为批量梯度下降(batch gradient descent),随机梯度下降则是随机采样一个样本进行梯度计算并迭代,小批量随机梯度下降则结合了“batch”与“stochastic”的想法。

设目标函数f:\mathbb{R}^d \rightarrow \mathbb{R},计算第t步的梯度时,小批量随机梯度下降法首先对原始训练数据集随机均匀采样,从而获得一个小批量的训练集\mathcal{B},采样可以是重复的或不重复的,前者允许同一个小批量出现相同的样本,后者则不允许,但是更常见。

那么,在这一小批数据上计算梯度:

\boldsymbol{g}_t = \frac{1}{\left | \mathcal{B} \right |} \sum_{k \in \mathcal{B}}\nabla f_k(\boldsymbol{x}_{t-1})

其中\left | \mathcal{B} \right |表示小批量中的样本数量,是一个超参数。

当给定学习率\eta_t后,就可以进行更新:

\boldsymbol{x}_t = \boldsymbol{x}_{t-1} - \eta_t \boldsymbol{g}_t

尽管随机采样计算的小批量随机梯度是梯度的无偏估计,但是方差在迭代过程中无法减小,为了让更新策略更符合梯度下降,一般将学习率设置为可衰减的学习率,如\eta_t = \eta t^\alpha(通常\alpha =-1 \quad or\quad 0.5)、\eta_t = \eta \alpha ^t(如\alpha = 0.95),又或者是迭代若干次后学习率衰减一次。这样学习率和小批量随机梯度的乘积的方差就会减小。

小批量随机梯度下降的计算开销为\mathcal{O}(\mathcal{\left | \mathcal{B} \right |})当批量大小为1时,算法成为随机梯度下降;当批量大小等于训练样本总数时,算法成为梯度下降

5、动量法(momentum)

梯度的反方向代表了目标函数在当前位置下降最快的方向,因此梯度下降又叫最速下降(steepest descent)。但是当存在多个自变量时,关于它们的偏导数可能相差较大,也即目标函数在不同方向上的斜率存在较大差异,由于以上迭代过程中学习率对于每个自变量都是相同的,因此这会导致不同自变量的更新步伐差异较大。如果为了防止变量越过最优值而采取小学习率,则会使其他方向朝最优值移动变慢;反之采取大点的学习率会使某个方向越过最优值而发散。

动量法就是为了上述问题。设时间步0时,动量法创建速度变量\boldsymbol{v}_0=\boldsymbol{0},在时间步t,动量法的迭代格式为(\boldsymbol{g}_t为小批量随机梯度):

\\ \boldsymbol{v}_t = \gamma \boldsymbol{v}_{t-1} + \eta_t \boldsymbol{g}_t \\ \boldsymbol{x}_t = \boldsymbol{x}_{t-1} - \boldsymbol{v}_t

动量超参数\gamma满足\gamma \in [0,1),当\gamma =0时,动量法变为小批量随机梯度下降 。

书上利用指数加权平均移动来解释动量法。

假设给定超参数0\leqslant \gamma < 1,时间步t的变量y_t由上一时间步的变量y_{t-1}和当前时间步的另一个变量x_t共同决定:

y_t = \gamma y_{t-1} + (1- \gamma)x_t

y_t进行展开:

\begin{aligned} \\y_t &= (1-\gamma)x_t + \gamma y_{t-1} \\ &=(1-\gamma)x_t +(1-\gamma)\cdot \gamma x_{t-1} + \gamma^2 y_{t-2}\\ & = (1-\gamma) x_t + (1-\gamma)\cdot\gamma x_{t-1} +(1-\gamma)\cdot \gamma^2 x_{t-2} + \gamma^3y_{t-3}\\ & \cdots \end{aligned}

可以看到末端存在过去时间步的变量y的指数加权,下面对这一项进行处理。

由已知公式:

\lim_{n \to \infty}\left(1-\frac{1}{n} \right)^n =e^{-1}

\gamma = 1-\frac{1}{n},则有:

\lim_{\gamma \to 1}\gamma^{\frac{1}{1-\gamma}}=e^{-1}

由于\gamma事先给定,我们尝试忽略掉系数指数大于\frac{1}{1-\gamma}的变量y,此时可以得到:

\begin{aligned} y_t &\approx(1-\gamma)x_t+(1-\gamma)\cdot \gamma x_{t-1}+\cdots +(1-\gamma)\gamma^q x_{t-q}\\ & = (1-\gamma )\sum^q_{i=0}\gamma^i x_{t-i} \end{aligned}

其中q=\left \lceil {\frac{1}{1-\gamma} - 1} \right \rceil,例如若\frac{1}{1-\gamma}=20(对应的\gamma =0.95),则q=19;若20<\frac{1}{1-\gamma}\leq 21,则q=20

于是y_t看成了最近\frac{1}{1-\gamma}个时间步的变量x的加权平均,且权重都是以指数形式存在,因此叫做指数加权移动平均。另外可以看出离当前时间步越近的x的权重越大。

现在再看动量法的公式:

\begin{aligned} \boldsymbol{v}_t &= \gamma \boldsymbol{v}_{t-1} + \eta_t \boldsymbol{g}_t\\ & =\gamma \boldsymbol{v}_{t-1} + (1-\gamma)\left(\frac{\eta _t\boldsymbol{g}_t}{1-\gamma}\right) \end{aligned}

这相当于对序列\left\{\frac{\eta_{t-i} \boldsymbol{g}_{t-i} }{1-\gamma}, i = 0, \cdots, \left \lceil \frac{1}{1-\gamma}-1\right\rceil \right\}做指数加权移动平均,即动量法的每个时间步自变量的更新量为最近\frac{1}{1-\gamma}个时间步的普通更新量的\frac{1}{1-\gamma}倍做指数加权移动平均,这里的普通更新量就是\eta_k\boldsymbol{g}_k那个倍数也可以理解为先做普通更新量的指数加权移动平均,然后再除以1-\gamma,那么净结果相当于\boldsymbol{v}_t \approx \sum^q_{i=0}\gamma^i\left(\eta_{t-i}\boldsymbol{g}_{t-i}\right)

由此可以看到,动量法在各个方向上的更新幅度不仅取决于当前梯度,还取决于过去时间步的各个梯度在各个方向上是否一致。

 直观上,如果过去若干时间步的梯度方向相同,那么下一时间步的更新幅度就会加大;如果方向不同,那么下一时间步的更新幅度就会减小。此时学习率就可以设置得更大一些,不仅可以使自变量向最优解快速移动,还因为过去梯度的约束规避了发散的问题。

6、AdaGrad 

在之前的优化算法中,对于多个参数的更新都是使用同一个学习率。当不同的自变量的梯度值存在较大差异时,正如动量法描述的那样,学习率太小会降低速度,学习率太大可能会导致发散,动量法通过对过去时间步的梯度做指数加权移动平均来使得自变量的更新方向更加一致,能够降低发散的可能,从而可以使用大学习率。AdaGrad算法则是根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免同一个学习率难以适应所有维度的更新幅度。

在时间步0,AdaGrad初始化累加变量\boldsymbol{s}_0=\boldsymbol{0},在时间步t,累加变量和自变量的更新方式如下:

\\ \boldsymbol{s}_t = \boldsymbol{s}_{t-1} + \boldsymbol{g}_t\odot \boldsymbol{g}_t \\ \boldsymbol{x}_t = \boldsymbol{x}_{t-1} - \frac{\eta}{\boldsymbol{s}_t + \varepsilon} \odot \boldsymbol{g}_t

这里\odot表示哈达玛积,\boldsymbol{g}_t为小批量随机梯度,\varepsilon是一个较小的常数使得分母不为0,如10^{-6}。这里的开方、除法和乘法都是按元素进行,从而使得每个自变量都拥有自己的学习率。

在迭代过程中,累加变量一直在累加梯度,如果某个自变量的偏导数过大,则该自变量的学习率下降得也快。但是随着累加变量的增长,所有自变量的学习率都在下降,因此当学习率在迭代早期下降得快但当前解依然不满足精度时,AdaGrad算法在迭代后期由于学习率过小,可能很难找到一个有用的解。

7、RMSProp

RMSProp算法针对AdaGrad算法中学习率一直下降的问题做出了改进,主要是借用了动量法中指数加权平均的想法

给定超参数0\le \gamma <1,那么状态变量\boldsymbol{s}_t(AdaGrad中的累加变量)的更新策略变为:

\boldsymbol{s}_t = \gamma \boldsymbol{s}_{t-1} + (1-\gamma) \boldsymbol{g}_t \odot \boldsymbol{g}_t

 自变量的更新策略则保持不变:

\boldsymbol{x}_t = \boldsymbol{x}_{t-1} - \frac{\eta}{\boldsymbol{s}_t + \varepsilon} \odot \boldsymbol{g}_t

因为RMSProp算法的状态变量\boldsymbol{s}_t对平方项\boldsymbol{g}_t \odot \boldsymbol{g}_t做指数加权移动平均,因此相当于最近\frac{1}{1-\gamma}个时间步的小批量随机梯度平方项的加权平均。这样的操作使得每个自变量的学习率在迭代过程中不会一直下降。

8、AdaDelta

AdaDelta也是针对AdaGrad存在的问题做出改进的算法,并且该算法没有学习率这一个超参数。

状态变量\boldsymbol{s}_t的更新策略与PMSProp算法保持一致:

\boldsymbol{s}_t = \rho \boldsymbol{s}_{t-1} + (1-\rho)\boldsymbol{g}_t\odot \boldsymbol{g}_t

超参数\rho相当于RMSProp中的\gamma

与PMSProp不同的是,AdaDelta引入了第二个状态变量\Delta x_t(可能是名称中有Delta的原因),它与第一个状态变量一样会被初始化,AdaDelta算法利用该状态变量进行自变量的更新

 \\\boldsymbol{g}_t '=\sqrt{\frac{\Delta x_{t-1}+ \varepsilon}{\boldsymbol{s}_t + \varepsilon} } \odot \boldsymbol{g}_t \\ \boldsymbol{x}_t = \boldsymbol{x}_{t-1} - \boldsymbol{g}_t '

同样的,常数\varepsilon保证数值稳定性,如10^{-5}。 

最后利用对自变量变化量\boldsymbol{g}_t'做指数加权移动平均对第二个状态变量进行更新:

\Delta\boldsymbol{x}_t = \rho \Delta \boldsymbol{x}_{t-1} + (1-\rho) \boldsymbol{g}_t' \odot \boldsymbol{g}_t'

可以看到,若不考虑常数\varepsilon的影响,AdaDelta相比RMSProp只是用新的状态变量\sqrt{\Delta \boldsymbol{x}_{t-1}}代替了学习率\eta

9、Adam

Adam 算法在RMSProp算法上做出了改进,主要是对小批量随机梯度也做了指数加权平均,可以看作是RMSProp算法和动量法的结合。

引入动量变量\boldsymbol{v}_t和RMSProp中的状态变量\boldsymbol{s}_t,在时间步0初始化为\boldsymbol{0},给定超参数0\leq \beta_1<1(建议0.9),动量变量的更新策略即为对小批量随机梯度做指数加权平均

\boldsymbol{v}_t = \beta_1 \boldsymbol{v}_{t-1}+ (1-\beta_1)\boldsymbol{g}_t

状态变量的更新策略与RMSProp保持一致,给定超参数0\leq \beta_2<1(建议0.999):

\boldsymbol{s}_t =\beta_2 \boldsymbol{s}_{t-1} + (1-\beta_2)\boldsymbol{g}_t\odot \boldsymbol{g}_t

由于两个变量的初始状态均为\boldsymbol{0},根据迭代公式可以得到:

\boldsymbol{v}_t = (1-\beta_1)\sum^{t-1}_{i=0}\beta_1 ^i \boldsymbol{g}_{t-i} \qquad \boldsymbol{s}_t = (1-\beta_2)\sum^{t-1}_{i=1}\beta_2^i \boldsymbol{g}_t\odot \boldsymbol{g}_t

 可以发现,上面的这些梯度的权重以及梯度平方项的权重都满足:

(1-\beta_1)\sum^{t-1}_{i=0}\beta_1 ^i =1-\beta_1^t \qquad (1-\beta_2)\sum^{t-1}_{i=0}\beta_1 ^i =1-\beta_2^t

从上面的关系可以看出当时间步较小时,这些权重的和也是比较小的。为了消除这种影响,我们对状态变量的迭代公式做权重归一化,使得过去各个时间步的小批量随机梯度(和其平方项)的权重之和等于1:

\\ \hat{\boldsymbol{v}_t} = \frac{\boldsymbol{v}_t}{1-\beta_1^t}\\ \hat{\boldsymbol{s}_t} = \frac{\boldsymbol{s}_t}{1-\beta_2^t}

这一个操作也称为偏差修正。 

然后Adam算法使用这两个修正后的状态变量调整每个自变量的学习率(这里说修改了学习率而不是说修改了自变量更新量,是把\frac{\eta}{\sqrt{\hat{\boldsymbol{s}_t}}+\varepsilon}看成整体):

\boldsymbol{g}_t' = \frac{\eta \hat{\boldsymbol{v}_t}}{\sqrt{\hat{\boldsymbol{s}_t}} + \varepsilon}

同样的,\eta为学习率,常数\varepsilon为了维持数值稳定性,如10^{-8}

最后,Adam算法对自变量进行更新:

\boldsymbol{x}_t = \boldsymbol{x}_{t-1} - \boldsymbol{g}_t'


以上就是梯度下降法及其变体的简单介绍,实际上梯度下降、随机梯度下降、小批量随机梯度下降是其他变体的前提,变体算法都是基于它们做出了不同方面的改进。

总结

1、gd、sgd、mini-batch sgd是基础的优化算法,后两个在更新过程中没有使用全部的梯度,而是采用了梯度的无偏估计,这在一定程度上降低了计算开销。根据参与无偏估计的样本数目,min-batch sgd可以转化为gd或sgd。

2、动量法和AdaGrad算法都是为了解决多个自变量在同一个学习率下更新步伐不一致(有的变化大,有的变化小)的问题,只不过解决的思路不一样。

3、动量法通过对过去时间步的梯度情况做指数加权平均得到当前时间步的梯度更新量,调整了不同变量的更新幅度,从而缓解了上述问题。通过大的学习率,自变量不仅可以朝最优值加速更新,还能避免发散的问题。

4、动量法中提到了指数加权移动平均,这个操作在后续的变体中使用很广泛,但从公式上难以看出加权平均的样子,需要进一步推导。

5、AdaGrad算法则是通过修改了各个自变量的学习率来应对该问题,但是AdaGrad算法中自变量的学习率在迭代过程会一直减小,如果前期未得到最优解,那么后期由于每次更新的变化量太小可能也无法获得最优解。

6、RMSProp、AdaDelta则是对AdaGrad算法的直接改进。它们都使用了动量法中提到的指数加权平均的想法。PMSProp算法对梯度平方项做指数加权移动平均,进而修正学习率,可以使得学习率在迭代过程中不会一直下降。AdaDelta算法则在RMSProp状态变量的基础上引入新的状态变量,利用这两个状态变量充当学习率,因此该算法不需要给定学习率这一超参数

7、Adam算法结合了RMSProp和动量法,拥有一个状态变量和一个动量变量。动量变量对梯度做指数加权移动平均,状态变量对梯度平方项做指数加权移动平均,之后对这两个变量做偏差修正(权重归一化),通过这两个变量即可修正各个自变量的学习率。

8、如果对变体算法进行分类的话,动量法可以归为一类,AdaGrad、RMSProp、AdaDelta、Adam可以归为一类。

9、动量法、RMSProp、AdaDelta、Adam都使用了指数加权移动平均。

10、动量法、AdaGrad、RMSProp都拥有一个状态变量。

11、AdaDelta、Adam都拥有两个状态变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值