查看全课大纲(第 32 / 93 节)
  1. 1.计算机视觉概述
  2. 2.计算机视觉应用场景
  3. 3.困难与挑战
  4. 4.开源库介绍
  5. 5.图像显示与存储
  6. 6.CLAHE
  7. 7.腐蚀膨胀与开闭运算
  8. 8.滤波与边缘填充
  9. 9.各种滤波
  10. 10.图像金字塔
  11. 11.傅里叶变换
  12. 12.短时傅里叶变换与小波变换
  13. 13.颜色特征与颜色直方图
  14. 14.几何特征_边缘
  15. 15.几何特征-角点与斑点
  16. 16.局部特征-SIFT特征描述子
  17. 17.局部特征-SURF特征描述子
  18. 18.局部特征-ORB特征描述子
  19. 19.其他特征描述子
  20. 20.传统图像分割技术
  21. 21.GraphCut
  22. 22.GrabCut
  23. 23.人脸检测的传统方法
  24. 24.行人检测的传统方法HOG+SVM
  25. 25.行人检测DPM
  26. 26.人工神经网络的架构
  27. 27.目标函数与梯度下降
  28. 28.误差反向传播
  29. 29.可手算的神经网络
  30. 30.改进目标函数与克服梯度消散
  31. 31.神经网络之传统神经网络与深度网络的差异
  32. 32.各种梯度下降算法
  33. 33.如何选择合适的梯度下降算法
  34. 34.避免过适应
  35. 35.CNN的架构
  36. 36.CNN的误差反向传播_卷积层
  37. 37.CNN的误差反向传播_池化层
  38. 38.分类所用的数据集
  39. 39.Alexnet详解
  40. 40.VGG详解
  41. 41.GoogLeNet_v1
  42. 42.BatchNormalization
  43. 43.GoogLeNet_v3v4
  44. 44.ResNet
  45. 45.ResNeXt
  46. 46.CNN设计准则
  47. 47.图像检索与推土机距离
  48. 48.基于颜色相似性
  49. 49.基于形状相似性
  50. 50.基于纹理相似性
  51. 51.基于局部特征相似性
  52. 52.DL的二值哈希编码
  53. 53.高维空间中检索KDTree
  54. 54.高维空间中检索LSH
  55. 55.目标识别任务综述
  56. 56.RCNN
  57. 57.SPP-Net
  58. 58.Fast R-CNN
  59. 59.Faster R-CNN
  60. 60.R-CNN系列模型回顾
  61. 61.R-FCN的设计思路
  62. 62.R-FCN的实现
  63. 63.YOLOv1
  64. 64.YOLOv2_9000
  65. 65.YOLOv3
  66. 66.图像分割应用场景与数据集
  67. 67.上采样的实现方式
  68. 68.FCN网络架构的由来
  69. 69.FCN构建细节
  70. 70.DeepLabv1
  71. 71.CRF
  72. 72.DeepLabv2
  73. 73.DeepLabv3
  74. 74.特定的医学影像分割任务
  75. 75.U-Net
  76. 76.3D U-Net
  77. 77.V-Net
  78. 78.DenseNet
  79. 79.病理切片分析任务及数据集
  80. 80.病理切片分析
  81. 81.图说任务及其传统处理方法
  82. 82.深度语言模型与RNN
  83. 83.LSTM及其变种
  84. 84.NIC模型
  85. 85.SAT模型
  86. 86.图说的性能指标
  87. 87.判别模型与生成模型
  88. 88.KL散度与JS散度
  89. 89.VAE
  90. 90.GAN的基本原理
  91. 91.DCGAN与CGAN
  92. 92.Wasserstein GAN
  93. 93.SRGAN

各种梯度下降算法

小象实战讲义 · 基于深度学习的计算机视觉

在深度学习的训练过程中,我们通过最小化损失函数来调整模型的参数。梯度下降法及其变体是实现这一目标的核心优化算法。本节我们将深入探讨从经典的随机梯度下降(SGD)到现代自适应优化器(如Adam)的演进历程,理解它们如何解决学习率设置、稀疏数据优化以及逃离鞍点等关键挑战,从而让模型训练得更快、更稳。

💡 核心导读

  • 学习率的困境:学习率过大可能导致震荡甚至发散,过小则训练缓慢。宏观上,学习率应随训练轮次增加而衰减。
  • 动量的引入:借鉴物理中的动量概念,将历史梯度信息融入当前更新,既能加速收敛,又能帮助逃离鞍点。
  • 参数自适应性:为不同参数分配不同的学习率,对稀疏特征(出现频率低)给予更大的更新,对频繁变化的参数则抑制其更新幅度。
  • 算法的演进:从SGD到Momentum、Adagrad,再到RMSprop和最终的集大成者Adam,每一步改进都旨在更智能地调整学习过程。

学习率:训练中的关键超参数

在神经网络训练中,学习率(learning rate)可以说是最重要的超参数之一。它决定了参数更新的步长。设置不当会直接导致训练失败。

学习率过大的问题:想象一个巨人站在山谷边缘,如果他的步长过大,一步就可能迈过山谷的最低点,落到对面的山坡上。在优化中,这意味着参数更新后,损失函数的值可能比更新前还要大,导致训练震荡甚至发散。

学习率过小的问题:反之,如果步长过小,就像一只小蚂蚁在山谷中缓慢爬行,虽然最终可能到达谷底,但需要极其漫长的时间。这会导致训练过程异常缓慢,计算成本高昂。

因此,一个直观的解决方案是动态调整学习率。从宏观训练过程来看,学习率应该满足一个基本规律:随着训练轮次的增加,学习率应逐渐减小。这是因为在训练初期,我们距离最优解较远,可以使用较大的步长快速靠近;而在训练后期,接近最优解时,需要用小步长精细调整,避免“一步跨过”最优点。

一种常见的衰减策略是: ηt=η0t+1\eta_t = \frac{\eta_0}{\sqrt{t+1}} 其中 ηt\eta_t 是第 tt 轮(或第 tt 个 mini-batch)的学习率,η0\eta_0 是初始学习率。这种随着时间 tt 开根号倒数衰减的方式,实现了学习率的缓慢减小。

然而,仅有一个全局的、随时间衰减的学习率仍然不够。我们面临更深层的问题:

  1. 稀疏数据问题:在自然语言处理(NLP)或某些视觉任务中,特征可能是稀疏的(例如词袋模型)。对于出现频率低的特征,我们希望其对应的参数更新幅度能大一些,以便更快地学习到这些特征的信息。
  • 鞍点问题:深度神经网络训练困难的主要原因往往不是陷入局部极小值,而是被困在鞍点(saddle point)。鞍点处梯度为零,但它在某些方向上曲率向上(像极小点)、在另一些方向上曲率向下(像极大点)。标准的梯度下降法在梯度接近零时会几乎停止更新,误以为到达了最优点。

接下来,我们将看到各种优化算法如何巧妙地解决这些问题。

带动量的随机梯度下降(Momentum SGD)

为了解决鞍点问题和加速收敛,我们引入了动量(Momentum) 的概念,其灵感来源于物理学。

物理直观:想象将一个弹珠放在马鞍形曲面的高处,让它自由滚落。当它经过鞍点(曲面上梯度为零的点)时,由于惯性(动量),它不会恰好停在鞍点,而是会继续向前运动一点。正是这一点偏移,使得它能够滑向曲率更大的方向,最终逃离鞍点区域。

在优化算法中,我们引入一个速度变量 vv 来积累历史的梯度信息。参数的更新不再仅仅依赖于当前的梯度,而是当前梯度与历史速度的加权组合。

算法公式:

  1. 计算当前 mini-batch 的梯度:gt=∇θJ(θt)g_t = \nabla_{\theta} J(\theta_t)
  2. 更新速度(动量):vt=γvt−1+ηgtv_t = \gamma v_{t-1} + \eta g_t
  3. 更新参数:θt+1=θt−vt\theta_{t+1} = \theta_t - v_t

其中:

  • θt\theta_t 是第 tt 步的参数。
  • J(θt)J(\theta_t) 是损失函数。
  • η\eta 是学习率。
  • γ\gamma 是动量系数,通常设置为 0.9 左右,它决定了历史梯度信息衰减的速度。
  • vtv_t 是累积的速度(动量)。

优势:

  • 加速收敛:在梯度方向一致的“缓坡”区域,动量会不断累积,产生“加速度”效应,使参数更新更快。
  • 抑制震荡:在梯度方向频繁变化的“锯齿状”路径上,动量起到平滑作用,减少不必要的震荡。
  • 逃离鞍点:在梯度为零的鞍点,由于 vtv_t 保留了之前的运动方向,参数仍会更新,从而有机会逃离。

Nesterov 加速梯度(NAG)

Nesterov Momentum 是对标准动量法的一个改进,其核心思想是“往前看”。

在标准动量法中,我们先计算当前点的梯度,然后结合动量进行一次更新。而 Nesterov 动量法则先根据当前动量“向前看”一步,得到一个参数的临时估计值 θt−γvt−1\theta_{t} - \gamma v_{t-1}(注意方向:实际行走方向是 −v-v),然后在这个“未来”的位置上计算梯度,再用这个梯度来更新动量。

算法公式:

  1. 临时更新参数:θ~t=θt−γvt−1\tilde{\theta}_t = \theta_t - \gamma v_{t-1}
  2. 在临时点计算梯度:gt=∇θJ(θ~t)g_t = \nabla_{\theta} J(\tilde{\theta}_t)
  3. 更新速度:vt=γvt−1+ηgtv_t = \gamma v_{t-1} + \eta g_t
  4. 更新参数:θt+1=θt−vt\theta_{t+1} = \theta_t - v_t

直观理解:这好比在冰面上溜冰。标准动量法是根据当前的位置和速度决定下一步怎么走。而 Nesterov 法则会先预估一下“如果按当前速度滑行,我会到哪里”,然后根据那个预估位置的地形(梯度)来调整我的动作。这使得优化器对未来的变化有了一定的预见性,在实践中通常能获得比标准动量法略好的性能。

自适应学习率算法

动量法解决了如何利用历史梯度方向信息的问题。另一个重要的改进思路是:能否为不同的参数设置不同的学习率? 这对于处理稀疏数据和不同参数更新频率差异大的情况至关重要。

Adagrad

Adagrad(Adaptive Gradient)的核心思想是:对于在过去更新中梯度较大的参数,降低其学习率;对于梯度较小的参数,则提高其学习率。它通过累积历史梯度的平方来实现这一点。

算法公式:

  1. 计算梯度:gt=∇θJ(θt)g_t = \nabla_{\theta} J(\theta_t)
  2. 累积梯度平方:rt=rt−1+gt⊙gtr_t = r_{t-1} + g_t \odot g_t (⊙\odot 表示逐元素相乘)
  3. 计算参数更新:Δθt=−ηrt+δ⊙gt\Delta \theta_t = -\frac{\eta}{\sqrt{r_t + \delta}} \odot g_t
  4. 更新参数:θt+1=θt+Δθt\theta_{t+1} = \theta_t + \Delta \theta_t

其中 δ\delta 是一个很小的常数(如 10−810^{-8}),用于防止除以零。

工作原理:

  • rtr_t 累积了所有历史梯度的平方和,对于每个参数是独立的。
  • 当某个参数的历史梯度 gg 很大时,rr 会很大,导致 ηr\frac{\eta}{\sqrt{r}} 变小,从而该参数的学习率被抑制。
  • 当某个参数的历史梯度 gg 很小时,rr 很小,ηr\frac{\eta}{\sqrt{r}} 相对较大,该参数的学习率被放大。

优点与缺陷:

  • 优点:非常适合处理稀疏数据。对于不常出现的特征(梯度小),给予大的更新;对于频繁出现的特征(梯度大),给予小的更新。同时,由于 rtr_t 单调递增,学习率总体上是衰减的,符合训练后期的需求。
  • 缺陷:rtr_t 会随着训练一直累加,导致分母 rt\sqrt{r_t} 变得非常大,学习率过早、过度地衰减到近乎为零,使得训练可能提前结束,无法充分优化。

RMSprop 与 Adadelta

为了克服 Adagrad 学习率过早衰减的问题,RMSprop(Root Mean Square Propagation)和 Adadelta 被提出。它们不再无限制地累加所有历史梯度平方,而是使用指数移动平均来估计梯度的二阶矩(即平方的期望),让“久远”的梯度信息逐渐衰减。

RMSprop 算法公式:

  1. 计算梯度:gt=∇θJ(θt)g_t = \nabla_{\theta} J(\theta_t)
  2. 计算梯度平方的指数移动平均:rt=ρrt−1+(1−ρ)gt⊙gtr_t = \rho r_{t-1} + (1 - \rho) g_t \odot g_t
  3. 计算参数更新:Δθt=−ηrt+δ⊙gt\Delta \theta_t = -\frac{\eta}{\sqrt{r_t + \delta}} \odot g_t
  4. 更新参数:θt+1=θt+Δθt\theta_{t+1} = \theta_t + \Delta \theta_t

其中 ρ\rho 是衰减率,通常设为 0.9。

核心改进:rtr_t 不再是单调递增的。如果当前梯度 gtg_t 突然变小,rtr_t 也会随之减小,从而学习率 ηrt\frac{\eta}{\sqrt{r_t}} 又能变大。这解决了 Adagrad 学习率“只减不增”的问题,使得学习率能够自适应地根据近期梯度规模进行调整。

Adadelta 与 RMSprop 同期独立提出、思想相近,同样从 Adagrad 出发改进;它进一步移除了对初始学习率 η\eta 的依赖:除了对梯度平方做指数移动平均,还对参数更新量的平方做指数移动平均,用两者之比来确定步长,从而完全不需要全局学习率。公式稍复杂,但思想与 RMSprop 一脉相承。

自适应矩估计(Adam)

Adam(Adaptive Moment Estimation)可以说是当前深度学习中最流行、效果最好的优化算法之一。它融合了动量法和自适应学习率算法的思想。

Adam 同时维护两个状态变量:

  • 一阶矩估计 mtm_t:梯度 gtg_t 的指数移动平均;其偏差校正版本 m^t\hat{m}_t 相当于动量。
  • 二阶矩估计 vtv_t:梯度平方 gt2g_t^2 的指数移动平均,用于自适应调整每个参数的学习率,类似于 RMSprop。

算法公式:

  1. 计算梯度:gt=∇θJ(θt)g_t = \nabla_{\theta} J(\theta_t)
  2. 更新一阶矩估计:mt=β1mt−1+(1−β1)gtm_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t
  3. 更新二阶矩估计:vt=β2vt−1+(1−β2)gt⊙gtv_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t \odot g_t
  4. 偏差校正(由于 m0,v0m_0, v_0 初始为0,初期估计有偏): m^t=mt1−β1t\hat{m}_t = \frac{m_t}{1 - \beta_1^t} v^t=vt1−β2t\hat{v}_t = \frac{v_t}{1 - \beta_2^t}
  5. 计算参数更新:Δθt=−ηv^t+δ⊙m^t\Delta \theta_t = -\frac{\eta}{\sqrt{\hat{v}_t} + \delta} \odot \hat{m}_t
  6. 更新参数:θt+1=θt+Δθt\theta_{t+1} = \theta_t + \Delta \theta_t

其中,β1\beta_1 和 β2\beta_2 是矩估计的衰减率,推荐值分别为 0.9 和 0.999。δ\delta 同样是为防止除零的小常数。

Adam 的优势:

  • 继承动量优点:通过 m^t\hat{m}_t 加速收敛、抑制震荡、帮助逃离鞍点。
  • 继承自适应优点:通过 v^t\hat{v}_t 为每个参数自适应调整学习率,适合稀疏数据。
  • 偏差校正保证启动稳定:由于 m0,v0m_0, v_0 初始化为 0,训练初期的矩估计会明显偏向 0;除以 1−βt1-\beta^t 可纠正这一偏差,使最初几步的更新幅度不会被过度压低。
  • 超参数鲁棒性好:推荐的 β1,β2,δ\beta_1, \beta_2, \delta 值在大多数问题上表现良好。

后续还有在 Adam 基础上结合 Nesterov 思想的 Nadam 等变体,但 Adam 本身因其出色的性能和简便性,已成为深度学习优化器的默认选择之一。

📝 动手练一练

  1. 概念辨析:请简述带动量(Momentum)的 SGD 与 Adagrad 算法各自的核心改进思想是什么?它们分别解决了 SGD 的哪些问题?
👉 点击查看参考答案
  • 带动量的SGD:核心思想是引入“惯性”,将历史梯度信息以指数衰减的形式累积到当前更新中。它主要解决了两个问题:(1) 在梯度方向一致的路径上加速收敛;(2) 在梯度为零的鞍点处,依靠动量继续更新,从而帮助逃离。
  • Adagrad:核心思想是为不同参数自适应地设置不同的学习率。它通过累积每个参数历史梯度的平方来实现:对历史梯度大的参数,减小其学习率;对历史梯度小(或稀疏)的参数,增大其学习率。它主要解决了SGD中所有参数共享同一学习率,无法很好处理稀疏数据的问题。
  1. 公式理解:在 Adam 算法的参数更新步骤 Δθt=−ηv^t+δ⊙m^t\Delta \theta_t = -\frac{\eta}{\sqrt{\hat{v}_t} + \delta} \odot \hat{m}_t 中,m^t\hat{m}_t 和 v^t\hat{v}_t 分别代表什么?它们是如何计算得到的?这个更新公式如何体现了对动量法和自适应学习率思想的融合?
👉 点击查看参考答案
  • m^t\hat{m}_t 是经过偏差校正的一阶矩估计,它代表了梯度 gtg_t 的指数移动平均,即带有衰减的动量。其计算过程为:先计算 mt=β1mt−1+(1−β1)gtm_t = \beta_1 m_{t-1} + (1-\beta_1)g_t,再进行偏差校正 m^t=mt/(1−β1t)\hat{m}_t = m_t / (1-\beta_1^t)。它使得更新方向不仅依赖于当前梯度,也依赖于历史梯度方向,起到了加速和稳定训练的作用。
  • v^t\hat{v}_t 是经过偏差校正的二阶矩估计,它代表了梯度平方 gt2g_t^2 的指数移动平均。其计算过程为:先计算 vt=β2vt−1+(1−β2)gt2v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2,再进行偏差校正 v^t=vt/(1−β2t)\hat{v}_t = v_t / (1-\beta_2^t)。它反映了每个参数历史梯度的大小,用于自适应地缩放学习率。
  • 融合体现:更新公式 Δθt=−ηv^t+δ⊙m^t\Delta \theta_t = -\frac{\eta}{\sqrt{\hat{v}_t} + \delta} \odot \hat{m}_t 中,m^t\hat{m}_t 提供了带动量的更新方向,而 ηv^t+δ\frac{\eta}{\sqrt{\hat{v}_t} + \delta} 构成了每个参数自适应的学习率。两者逐元素相乘(⊙\odot),意味着每个参数沿着其动量方向更新的步长,会根据自身历史梯度规模进行独立调整,完美融合了两种改进思路。

本章小结

本节我们系统梳理了深度学习中的核心优化算法。从最基础的随机梯度下降(SGD)出发,我们首先认识了学习率设置的核心矛盾。接着,我们学习了通过引入动量来加速收敛并逃离鞍点的 Momentum SGD 及其改进版 Nesterov 加速梯度。然后,我们转向另一条改进路径:自适应学习率。Adagrad 首次为不同参数分配不同学习率,但其学习率衰减过快;RMSprop 和 Adadelta 通过指数移动平均解决了这一问题。最终,Adam 算法将动量(一阶矩估计)和自适应学习率(二阶矩估计)的思想精妙地结合在一起,成为当前实践中最强大、最通用的优化器之一。

理解这些算法的原理和演进脉络,不仅能帮助我们在实际项目中更好地选择和调优优化器,更能深化我们对深度学习模型训练动力学本质的认识。

从今天的实践看,Adam 系列(尤其是带解耦权重衰减的 AdamW)已成为 Transformer 等大模型训练的默认选择;而在 CNN 视觉任务上,调好学习率计划的 SGD + Momentum 仍常能取得不相上下的泛化表现。换句话说,“自适应 vs 动量”并不是谁彻底取代谁,而是两套思路在不同任务上各有胜场——这也是本节把两条演进线都讲清楚的原因。

📋 行动清单

  • 回顾对比:尝试用一句话总结 SGD、Momentum、Adagrad、RMSprop、Adam 这五种算法的核心区别。
  • 代码实践:在后续的模型训练练习中,有意识地尝试使用不同的优化器(如 SGD with Momentum 和 Adam),观察并记录它们在损失下降曲线和最终精度上的差异。
  • 原理思考:结合“香蕉函数”等经典优化地形,思考为什么自适应学习率算法(如 Adam)在这些场景下通常表现更好。

—— 小象教研组