深度学习笔记(二):各种梯度下降优化算法总结

本文详细介绍了梯度下降算法的多种变种,包括批量梯度下降、随机梯度下降、小批量梯度下降等,以及为解决梯度下降问题提出的动量梯度下降法、Nesterov动量梯度下降法、Adagrad、RMSprop、AdaDelta和Adam优化算法,深入探讨了这些算法的工作原理和优缺点。

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

1. 批量梯度下降 (Batch Gradient Descent)

定义代价函数为所有样本的代价
J(θ)=12m∑i=1m(hθ(x(i))−y(i))2J(\theta)=\frac{1}{2m}\sum^m_{i=1}(h_{\theta}(x^{(i)})-y^{(i)})^2J(θ)=2m1i=1m(hθ(x(i))y(i))2
θj=θj−α⋅∇θjJ(θ)  (for j=0:n)\theta_j = \theta_j - \alpha\cdot\nabla_{\theta_j}J(\theta)  (for j = 0 : n)θj=θjαθjJ(θ)  (for j=0:n)

  • 批量梯度下降,对所有样本计算梯度后求平均,并更新参数。
  • 因为在执行每次更新时,我们需要在整个数据集上计算所有的梯度,所以批梯度下降法的速度会很慢,同时,批梯度下降法无法处理超出内存容量限制的数据集。批梯度下降法同样也不能在线更新模型,即在运行的过程中,不能增加新的样本。
  • 对于凸误差函数,批梯度下降法能够保证收敛到全局最小值,对于非凸函数,则收敛到一个局部最小值

2. 随机梯度下降 (SGD)

在 SGD 中,定义代价函数为单一训练实例(随机选取)的代价
J(θ)=12(hθ(x(i))−y(i))2  (for i=1:m)J(\theta)=\frac{1}{2}(h_{\theta}(x^{(i)})-y^{(i)})^2  (for i = 1 : m)J(θ)=21(hθ(x(i))y(i))2  (for i=1:m)
更新参数
θj=θj−α⋅∇θjJ(θ;x(i);y(i))  (for j=0:n)\theta_j=\theta_j-\alpha\cdot \nabla_{\theta_j}J(\theta;x^{(i)};y^{(i)})  (for j = 0 : n)θj=θjαθjJ(θ;x(i);y(i))  (for j=0:n)

  • 与批量梯度下降相比,SGD 运行速度更快,SGD 在每次计算后便更新参数 θ\thetaθ,而不需要首先将所有训练样本求和,可以用于在线学习
  • SGD 的缺点在于:不是每一步都朝着正确的方向迈出,虽然会走向全局最小值,但可能无法站到最小值那一点上,而是在附近徘徊,因此使用 SGD 会一直持续波动;然而当我们缓慢减小学习率,SGD 与批量梯度下降具有同样的收敛行为。

3. 小批量梯度下降 (Mini-Batch Gradient Descent)

介于批量梯度下降和 SGD 之间的算法,即每次计算常数 b 个训练样本的误差,便更新一次参数。

定义代价函数为
J(θ)=12b∑k=ii+b−1(hθ(x(k))−y(k))2  (for i=1:m)J(\theta)=\frac{1}{2b}\sum^{i+b-1}_{k=i}(h_{\theta}(x^{(k)})-y^{(k)})^2  (for i = 1 : m)J(θ)=2b1k=ii+b1(hθ(x(k))y(k))2  (for i=1:m)
更新参数
θj=θj−α∇θjJ(θ)  (for j=0:n)\theta_j=\theta_j-\alpha\nabla_{\theta_j}J(\theta)  (for j = 0 : n)θj=θjαθjJ(θ)  (for j=0:n)

4. 原始梯度下降的问题

  • 在梯度平缓的区域下降缓慢,在梯度陡峭的区域容易抖动。
  • 容易陷入局部极小值或鞍点。
  • 选择一个合适的学习率比较困难。学习率太小会导致收敛的速度很慢,学习率太大会妨碍收敛,导致损失函数在最小值附近波动甚至偏离最小值。

5. 动量梯度下降法 (Momentum)

  • Momentum 借用了物理中的动量概念,即,前几次的梯度也会参与运算。
  • 为了表示动量,引入一个新的变量 vvvvvv 是之前的梯度的累加,但每回合都有一定的衰减。
    在这里插入图片描述
    vvv 表示之前梯度的累加,这一点可以通过计算梯度的指数加权平均数实现,首先通过 Mini-batch 计算权重和偏置项的偏导数 dw,dbdw,dbdw,db
    令 vdw=βvdw+(1−β)dw,vdb=βvdb+(1−β)db令 v_{dw}=\beta v_{dw}+(1-\beta)dw,v_{db}=\beta v_{db}+(1-\beta)db vdw=βvdw+(1β)dwvdb=βvdb+(1β)db
    β\betaβ 一般设置为接近 1 的数,如 0.9,β\betaβ代表了现在的 vdwv_{dw}vdwvdbv_{db}vdb 与之前的 1/(1−β)1 / (1 - β)1/(1β)dwdwdwdbdbdb 有关
    然后更新权重
    w=w−αvdw,b=b−αvdbw=w-\alpha v_{dw},b=b-\alpha v_{db}w=wαvdwb=bαvdb
    这样每一次梯度下降都会有一个之前的速度的作用,如果这次的方向与之前相同,则会因为之前的速度继续加速;如果这次的方向与之前相反,则会由于之前存在速度的作用不会产生一个急转弯,而是尽量把路线向一条直线拉过去。
    这样就解决了梯度下降路线纵轴摆动较大的问题,同时也加快了横轴方向的学习速率。

6. Nesterov 动量梯度下降法

Nesterov 是对 Momentum 的一种改进:先对参数进行估计,然后使用估计后的参数来计算误差。
首先对参数进行临时更新:θ~=θ+αv\tilde{\theta}=\theta+\alpha vθ~=θ+αv
使用临时更新的参数计算误差用于求梯度:g=1m∇θ~∑iL(f(xi;θ~),yi)g = \frac{1}{m}\nabla_{\tilde{\theta}}\sum_i L(f(x_i;\tilde{\theta}),y_i)g=m1θ~iL(f(xi;θ~),yi)
计算速度更新:v=αv−ϵgv=\alpha v-\epsilon gv=αvϵg
更新参数:θ=θ+v\theta=\theta+vθ=θ+v

其中,学习速率 ϵ\epsilonϵ,初始参数 θ\thetaθ,初始速率 vvv,动量衰减参数 α\alphaα

7. Adagrad 梯度下降法

Adagrad 的目的是为不同的参数设置不同的学习步长。
计算梯度:
g~=1m∇θ∑iL(f(xi;θ),yi)\tilde{g}=\frac{1}{m}\nabla_{\theta}\sum_iL(f(x_i;\theta),y_i)g~=m1θiL(f(xi;θ),yi)
累加梯度的平方:r=r+g~⊙g~r=r+\tilde{g}\odot\tilde{g}r=r+g~g~
计算更新值:Δθ=−ηδ+r⊙g~\Delta\theta=-\frac{\eta}{\delta+\sqrt{r}}\odot\tilde{g}Δθ=δ+rηg~
由上式得,梯度越小,则学习步长越大,反之亦然;其中 δ\deltaδ 是一个很小的数,为了防止分母为 0 ,常用 δ=10−8\delta=10^{-8}δ=108

更新参数:θ=θ+Δθ\theta=\theta+\Delta\thetaθ=θ+Δθ

存在问题:使用累加的方式计算梯度,但凡前面存在一个较大的梯度,往后就无法以较大的步长进行学习,但这也符合梯度下降中学习步长需要不断减小的规律;但问题是往后经过梯度平缓的区域就不能以较大的步长通过。

8. RMSprop 算法

RMSprop 是一种改进的 Adagrad,通过引入一个衰减系数,让累加得到的 rrr 每回合都衰减一定比例,这种方法很好地解决了 Adagrad 中步长过早变小的问题,适合处理非平稳目标,对于 RNN 效果很好。

首先计算梯度:
g~=1m∇θ∑iL(f(xi;θ),yi)\tilde{g}=\frac{1}{m}\nabla_{\theta}\sum_iL(f(x_i;\theta),y_i)g~=m1θiL(f(xi;θ),yi)
累加梯度的平方:r=ρr+(1−ρ)g~⊙g~r=\rho r+(1-\rho)\tilde{g}\odot\tilde{g}r=ρr+(1ρ)g~g~
(这里未必是递增,计算的是当前和过往的滑动平均值)

计算更新值:Δθ=−ηδ+r⊙g~\Delta\theta=-\frac{\eta}{\delta+\sqrt{r}}\odot\tilde{g}Δθ=δ+rηg~

更新参数:θ=θ+Δθ\theta=\theta+\Delta\thetaθ=θ+Δθ

9. AdaDelta 算法

AdaDelta 与 RMSprop 一样也是为了解决 Adagrad 中步长过早变小的问题,但 AdaDelta 中没有学习率这一超参数。
同 RMSprop 一样计算累加梯度的平方:rt=ρrt−1+(1−ρ)g~⊙g~r_{t}=\rho r_{t-1}+(1-\rho)\tilde{g}\odot\tilde{g}rt=ρrt1+(1ρ)g~g~

但 AdaDelta 会维护一个额外的状态变量 Δxt\Delta x_tΔxt,其元素同样初始化为 0,接着使用 Δxt−1\Delta x_{t-1}Δxt1 计算自变量的变化量:
gt′=Δxt−1+ϵrt+ϵ⊙gtg'_t=\sqrt{\frac{\Delta x_{t-1}+\epsilon}{r_t + \epsilon}}\odot g_tgt=rt+ϵΔxt1+ϵgt
其中 ϵ\epsilonϵ 是为了维持数值稳定性而添加的常数,如 10-e5。接着更新自变量
xt=xt−1−gt′x_t=x_{t-1}-g'_txt=xt1gt
最后使用 Δxt\Delta x_tΔxt 来记录自变量来记录自变量 gt′g'_tgt 按元素平方的指数加权平均数
Δxt=ρΔxt−1+(1−ρ)g′⊙gt′\Delta x_t=\rho \Delta x_{t-1}+(1-\rho) g'\odot g'_tΔxt=ρΔxt1+(1ρ)ggt
如不考虑 ϵ 的影响,AdaDelta 算法与 RMSProp 算法的不同之处在于使用 Δxt−1\sqrt{\Delta x_{t-1}}Δxt1 来替代超参数 η\etaη

10. Adam 优化算法

Adam 基本上就是将 Momentum 和 RMSprop 结合在一起,即带动量的 RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

首先使用 Mini-batch 计算梯度:
g=1m∇θ∑iL(f(xi;θ),yi)g=\frac{1}{m}\nabla_{\theta}\sum_iL(f(x_i;\theta),y_i)g=m1θiL(f(xi;θ),yi)
计算一阶矩估计:s=ρ1s+(1−ρ1)gs=\rho_1 s+(1-\rho_1)gs=ρ1s+(1ρ1)g

计算二阶矩估计:r=ρ2r+(1−ρ2)g⊙gr=\rho_2 r+(1-\rho_2)g\odot gr=ρ2r+(1ρ2)gg

修正偏差:由于 s,rs,rs,r 初始化为 0 向量,容易向 0 偏置,这样处理会减少这种偏置影响,其中 ttt 代表迭代次数
s~=s1−ρ1t\tilde{s}=\frac{s}{1-\rho^t_1}s~=1ρ1ts
r~=r1−ρ2t\tilde{r}=\frac{r}{1-\rho^t_2}r~=1ρ2tr
更新参数:
Δθ=−αs~r~+δ\Delta\theta=-\alpha\frac{\tilde{s}}{\sqrt{\tilde{r}}+\delta}Δθ=αr~+δs~
θ=θ+Δθ\theta=\theta+\Delta\thetaθ=θ+Δθ

其中,学习率 α\alphaα 需要经常调试,ρ1\rho_1ρ1 常用 0.9,ρ2\rho_2ρ2 常用 0.999,δ\deltaδ 建议 10−810^{-8}108


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值