查看全课大纲(第 33 / 93 节)
- 1.计算机视觉概述
- 2.计算机视觉应用场景
- 3.困难与挑战
- 4.开源库介绍
- 5.图像显示与存储
- 6.CLAHE
- 7.腐蚀膨胀与开闭运算
- 8.滤波与边缘填充
- 9.各种滤波
- 10.图像金字塔
- 11.傅里叶变换
- 12.短时傅里叶变换与小波变换
- 13.颜色特征与颜色直方图
- 14.几何特征_边缘
- 15.几何特征-角点与斑点
- 16.局部特征-SIFT特征描述子
- 17.局部特征-SURF特征描述子
- 18.局部特征-ORB特征描述子
- 19.其他特征描述子
- 20.传统图像分割技术
- 21.GraphCut
- 22.GrabCut
- 23.人脸检测的传统方法
- 24.行人检测的传统方法HOG+SVM
- 25.行人检测DPM
- 26.人工神经网络的架构
- 27.目标函数与梯度下降
- 28.误差反向传播
- 29.可手算的神经网络
- 30.改进目标函数与克服梯度消散
- 31.神经网络之传统神经网络与深度网络的差异
- 32.各种梯度下降算法
- 33.如何选择合适的梯度下降算法
- 34.避免过适应
- 35.CNN的架构
- 36.CNN的误差反向传播_卷积层
- 37.CNN的误差反向传播_池化层
- 38.分类所用的数据集
- 39.Alexnet详解
- 40.VGG详解
- 41.GoogLeNet_v1
- 42.BatchNormalization
- 43.GoogLeNet_v3v4
- 44.ResNet
- 45.ResNeXt
- 46.CNN设计准则
- 47.图像检索与推土机距离
- 48.基于颜色相似性
- 49.基于形状相似性
- 50.基于纹理相似性
- 51.基于局部特征相似性
- 52.DL的二值哈希编码
- 53.高维空间中检索KDTree
- 54.高维空间中检索LSH
- 55.目标识别任务综述
- 56.RCNN
- 57.SPP-Net
- 58.Fast R-CNN
- 59.Faster R-CNN
- 60.R-CNN系列模型回顾
- 61.R-FCN的设计思路
- 62.R-FCN的实现
- 63.YOLOv1
- 64.YOLOv2_9000
- 65.YOLOv3
- 66.图像分割应用场景与数据集
- 67.上采样的实现方式
- 68.FCN网络架构的由来
- 69.FCN构建细节
- 70.DeepLabv1
- 71.CRF
- 72.DeepLabv2
- 73.DeepLabv3
- 74.特定的医学影像分割任务
- 75.U-Net
- 76.3D U-Net
- 77.V-Net
- 78.DenseNet
- 79.病理切片分析任务及数据集
- 80.病理切片分析
- 81.图说任务及其传统处理方法
- 82.深度语言模型与RNN
- 83.LSTM及其变种
- 84.NIC模型
- 85.SAT模型
- 86.图说的性能指标
- 87.判别模型与生成模型
- 88.KL散度与JS散度
- 89.VAE
- 90.GAN的基本原理
- 91.DCGAN与CGAN
- 92.Wasserstein GAN
- 93.SRGAN
如何选择合适的梯度下降算法
小象实战讲义 · 基于深度学习的计算机视觉
在深度学习的训练过程中,我们面临着多种梯度下降优化算法的选择,从基础的随机梯度下降(SGD)到复杂的自适应算法如Adam。面对如此多的选项,初学者往往会感到困惑。本节我们将通过实验对比和原理分析,为你梳理出在不同场景下选择优化算法的清晰思路,让你能够根据实际需求,自信地为你的模型挑选最合适的“引擎”。
💡 核心导读
- 实验对比:在MNIST和CIFAR-10数据集上,Adam和带Nesterov动量的SGD通常表现出更快的收敛速度。
- 算法特性:自适应算法(如Adam)擅长处理稀疏数据,收敛快;而传统SGD则更稳定,能更精准地找到最优解。
- 选择策略:没有“最好”的算法,只有“最适合”的。选择应基于数据特性、任务阶段(快速验证 vs. 精细调优)和个人经验。
- 实战建议:包括使用小数据集预实验、数据打散、持续监控训练过程以及制定合适的学习率衰减策略。
梯度下降算法实战效果对比
我们已经学习了多种梯度下降优化算法,从最基础的随机梯度下降(SGD),到引入动量的Momentum和Nesterov Momentum,再到自适应学习率的Adagrad、Adadelta、RMSprop和Adam。面对这么多选择,我们该如何决策呢?最直接的方式是看它们在实战中的表现。
我们可以在两个经典数据集上进行实验对比:
- MNIST:一个手写阿拉伯数字的数据集,包含0-9共10个类别,常用于图像分类的入门任务。
- CIFAR-10:由Hinton和他的学生创建的数据集,包含10个类别的彩色小图片(如飞机、汽车、鸟等),每张图片大小为32x32像素。
实验通常观察训练过程中目标函数值(损失)随训练轮次(Epoch)的变化。不同算法在 MNIST 和 CIFAR-10 上的定性表现可归纳为下表(数值随网络结构、学习率设置而变,这里只比较趋势):
| 算法 | 收敛速度(同等 epoch) | 典型现象 |
|---|---|---|
| SGD | 最慢 | 损失下降平滑但缓慢,平坦区域容易停滞 |
| SGD + Momentum | 中等 | 一致方向上加速,惯性可能冲过谷底 |
| SGD + Nesterov | 中等偏快 | 提前“刹车”,震荡更小 |
| Adagrad | 前期快、后期慢 | 学习率单调减小,后期几乎不再更新 |
| RMSprop | 快 | 学习率自适应,后期仍能调整 |
| Adam | 通常最快 | 前期下降最猛,常处于曲线最下方 |
如何解读:在相同的训练轮次下,哪种算法的损失值下降得更低、更快,通常意味着其收敛性能更好。
从课件中的损失曲线可以观察到:
- Adam(紫色曲线)在大多数情况下都处于最下方,表明其收敛速度最快,损失下降最明显。
- 带Nesterov动量的SGD(橙色或红色曲线)通常紧随其后,表现也非常出色,尽管其原理相对简单。
这是否意味着我们可以无脑选择Adam呢?事情并没有这么简单。课件与实验都提示 Adam 存在两项已知缺陷:① 在某些任务上可能不收敛;② 可能错过全局最优解。实践中常见的现象是 Adam 前期下降很快,但后期有效学习率过小,最终精度往往不及精调的 SGD(例如 CIFAR-10 上的对比)。这正是很多论文在训练后期从 Adam 切换到精调 SGD 的直接原因。
算法特性深度分析
为了理解不同算法的行为,我们可以观察它们在一个简化优化问题(例如狭长山谷状的损失地形)中的“行走路径”。不同算法的差别主要体现在两点:每步迈多大(学习率/自适应缩放)和是否记住历史方向(动量)。据此可以归纳出它们的核心特性:
- 基本SGD:路径稳定,一步步走向最低点,但速度慢,且可能在平坦的鞍点区域停滞。
- 带动量的算法:由于积累了历史梯度方向,在一致方向上能加速,但惯性也可能导致它冲过最优点,在谷底来回震荡。
- 自适应算法:如Adadelta、RMSprop、Adam,它们为每个参数调整独立的学习率。在梯度小的方向(缓坡)迈大步,在梯度大的方向(陡坡)迈小步,因此路径往往更直接。Adam还结合了动量思想。
这就引出了一个生动的比喻:
- Adam等高级算法像是自动挡跑车:上手快,加速猛,能让你快速到达目的地附近。
- 精调的SGD像是手动挡汽车:需要更多经验和技巧(调参)来驾驭,但老司机(资深研究者)能用它更精准、更稳定地停进最优的“车位”。这也是为什么许多顶级论文中,最终模型仍使用SGD进行精细优化。
梯度下降算法选择指南
综合实验效果和原理分析,我们可以得出以下选择策略和建议:
1. 核心选择原则
- 对于初学者:优先考虑 SGD with Nesterov Momentum 或 Adam。它们通常能提供不错的默认性能,减少初期调参的复杂度。
- 根据数据特性:如果数据是稀疏的(例如自然语言处理中高维one-hot向量),优先使用自适应学习率算法(Adagrad、Adadelta、RMSprop、Adam)。因为它们能为不常出现的特征(对应梯度稀疏)分配更大的更新步长。
- 根据任务阶段:
- 模型快速验证/原型开发阶段:使用Adam。它能让你快速看到模型是否有潜力,加速实验迭代。
- 模型最终调优与发布阶段:切换到精调的SGD(可能带动量)。花时间调整学习率衰减策略,让模型收敛到可能更优、更稳定的解。
2. 重要的实战习惯
- 用小数据集做实验:按 epoch 计,随机梯度下降的收敛速度与数据集大小关系不大。在训练全量数据前,先用一个小的代表性数据集(例如CIFAR-10的子集)测试不同优化器。如果某个算法在小数据上都不收敛或收敛极慢,那在大数据上很可能也有问题。这能帮你快速排除模型结构或优化器选择上的重大错误。
- 组合使用算法:一种有效的策略是先用Adam进行快速下降,在训练后期切换到SGD进行精细调优。这结合了二者的优点。
- 务必打散(Shuffle)数据:在每轮训练开始前,随机打乱训练数据顺序。这对于自适应算法尤为重要,可以防止某些特征连续出现导致的更新偏差(时而学习过度,时而学习不足),确保数据满足“独立同分布”的假设。
- 持续监控训练过程:
- 监控训练集损失:确保模型正在有效地学习,损失在稳步下降。
- 监控验证集损失/精度:这是早停(Early Stopping) 的依据。当验证集指标不再提升时,应停止训练,以防止过拟合。
- 制定学习率衰减策略:学习率随着训练进行而逐渐减小是一个基本原则。可以:
- 采用定期衰减:例如每训练30个Epoch,将学习率乘以0.1。
- 采用指标触发衰减:当验证集损失在连续几个Epoch内不再下降时,降低学习率。
3. 关于“熟悉度”
如果你对某个算法(比如SGD)有丰富的调参经验,清楚其学习率、动量参数如何影响训练动态,那么坚持使用你熟悉的算法往往是更高效的选择。经验带来的直觉能帮助你更快地诊断和解决训练中出现的问题。
📝 动手练一练
- 概念辨析:为什么在训练深度神经网络时,我们通常建议使用学习率衰减策略?如果学习率始终保持一个很大的固定值,可能会导致什么问题?
👉 点击查看参考答案
使用学习率衰减策略的主要原因在于优化过程的动态需求。在训练初期,参数离最优解较远,较大的学习率有助于快速逼近。随着训练进行,参数接近最优解,过大的学习率会导致更新步长过大,在最优解附近来回震荡,无法稳定收敛,甚至可能使损失值上升,导致发散。衰减的学习率能让优化过程在后期精细调整,稳定地收敛到(局部)最优点。
- 策略思考:假设你正在训练一个大型图像分类模型,训练一个Epoch需要一天时间。为了在几天内快速评估模型架构的改进是否有效,你会采取哪些与优化器相关的策略来加速实验周期?
👉 点击查看参考答案
可以采取以下组合策略:
- 使用Adam优化器,因为它通常能提供更快的初始收敛速度,让你在更少的Epoch内看到损失下降的趋势。
- 在完整数据集的一个小子集(例如10%)上先进行实验。按 epoch 计,SGD类算法的收敛速度与数据量大小关系不大,在小数据集上表现好的优化设置,在大数据集上通常也有效。这能让你在几小时内完成多次实验迭代,验证想法。
- 监控小数据集上的训练损失和验证精度,如果模型能在小数据上快速学习并达到不错的精度,则说明模型架构有潜力,可以再投入资源进行全量数据的长时间训练和精细调优(此时可考虑切换到SGD)。
本章小结
选择合适的梯度下降算法是深度学习实践中的一项关键技能。本节我们通过实验认识了不同算法的性能差异,并深入分析了其背后的原理:自适应算法(如Adam)善于快速收敛,尤其适合稀疏数据;而传统SGD则以其稳定性和最终收敛精度见长。记住,没有放之四海而皆准的“最佳”算法,明智的选择源于对数据、任务阶段和算法本身特性的综合考量。
放到今天看,结论仍成立,但默认答案已随架构变化:Transformer 类大模型基本默认使用 AdamW;而在 CNN 视觉任务上,调好学习率计划的 SGD + Momentum 依然常用。本节给出的“按任务阶段切换优化器”的思路,比记住某个算法的排名更有长期价值。
📋 行动清单
- 尝试对比:在你当前的项目中,分别用Adam和SGD+Nesterov训练相同的模型几个Epoch,观察损失下降曲线的差异。
- 应用策略:在下一个新项目开始时,先构建一个小的实验数据集,用于快速验证模型和优化器选择。
- 养成习惯:在训练脚本中,加入对训练集和验证集损失/精度的实时监控与可视化,并实现一个简单的学习率衰减策略(如每20个Epoch衰减为原来的0.5倍)。
—— 小象教研组