优化算法与正则化
概述
深度学习的训练过程本质是优化问题:找到一组参数使得损失函数最小化。优化算法决定了参数如何更新,正则化控制模型复杂度防止过拟合。本文整理了常见优化算法(SGD、Momentum、Adam、AdamW等)、学习率调度和归一化技术(Batch Normalization等)。
梯度下降家族
批量梯度下降 (BGD)
- 原理:遍历全部训练集计算梯度,然后更新一次参数
- 公式:θ=θ−α∇J(θ),其中∇J是全部样本平均梯度
- 优点:收敛稳定,得到全局最优(凸问题)
- 缺点:数据量大时计算非常慢,无法在线更新
随机梯度下降 (SGD)
- 原理:每次只用一个样本计算梯度,更新一次参数
- 优点:更新快,支持在线学习,大数据集效率高
- 缺点:梯度方差大,收敛过程震荡,可能在最优值附近波动
小批量梯度下降 (MBGD)
- 原理:将数据分成多个batch,每个batch计算梯度更新参数
- 现在深度学习标准做法:兼顾BGD和SGD优点
- batch size选择:通常取2的幂,如32、64、128、256,充分利用矩阵运算加速
SGD为什么支持online learning:
online learning是流式学习,每来一个样本就更新一次模型,SGD的思想正好符合,每次只需要一个样本就可以更新参数,不需要保存全部数据。
带动量的优化方法
Momentum
-
思想:累加历史梯度的指数移动平均,减少震荡,加速收敛
-
公式:
v_t = γ * v_{t-1} + α * ∇J(θ)
θ = θ - v_t
γ通常取0.9
-
为什么Momentum能加速训练:
动量累加了历史梯度方向,如果当前梯度与历史方向一致,会加速这个方向;如果方向不一致,会抑制震荡。这样减少了摆动,使得收敛更快。
Nesterov Momentum (NAG)
- 改进:先按照历史动量走一步,再计算梯度,然后修正,相当于"先往前走一步,再看哪里不对调整"
- 理论上比标准Momentum更稳定,收敛更好
自适应学习率算法
AdaGrad
- 思想:对不同参数自适应调整学习率,频繁更新的参数学习率减小,稀疏更新的参数学习率增大
- 适合处理稀疏数据(如NLP中的词特征)
- 缺点:学习率单调递减,训练后期学习率变得太小,提前停止
RMSProp
- 改进AdaGrad:使用指数移动平均累积梯度平方,避免学习率过早下降
- 对梯度平方做指数衰减,忘掉较早的梯度,只关注最近的
Adam
Adam结合了Momentum和RMSProp的思想,是目前最常用的自适应优化算法。
- 维护两个指数移动平均:
- mt=β1mt−1+(1−β1)gt (一阶矩,动量)
- vt=β2vt−1+(1−β2)gt2 (二阶矩,梯度平方的指数平均)
- 偏差修正:因为初始都是0,需要修正偏差
- m^t=mt/(1−β1t)
- v^t=vt/(1−β2t)
- 参数更新:
θt=θt−1−α⋅m^t/(v^t+ϵ)
- 默认参数:β1=0.9,β2=0.999,α=1e−3,ϵ=1e−8
Adam vs SGD:
- Adam收敛速度快,对学习率选择不敏感,自适应调整
- SGD+Momentum最终泛化性能往往更好,特别是在大数据集上
- 常用策略:先用Adam快速收敛,最后用SGD精调
Adam vs SGD使用场景:
- Adam:稀疏数据、需要快速收敛、验证效果
- SGD:模型最终发布、追求极致泛化性能、大数据集
AdamW
AdamW是对Adam的改进,正确处理权重衰减。
- 问题:原始Adam在Adam中对权重衰减的实现不正确,权重衰减和L2正则化不等价
- 改进: decoupled weight decay,将权重衰减从梯度计算中分离出来,直接衰减权重
- 效果:在fine-tuning大模型时,AdamW泛化性能更好,是现在BERT等Transformer模型的标准优化器
优化算法对比
| 算法 | 特点 | 适用场景 |
|---|
| SGD | 简单,最终泛化好,收敛慢 | 大规模数据,最终精调 |
| SGD+Momentum | 加速收敛,减少震荡 | 传统深度学习通用 |
| RMSProp | 自适应学习率,解决AdaGrad问题 | 深度学习通用 |
| Adam | 结合动量和自适应,收敛快 | 默认首选,快速实验 |
| AdamW | 正确处理权重衰减 | Transformerfine-tuning,现代大模型 |
学习率调度
学习率对训练影响非常大:
- 学习率太大:loss震荡,不收敛,甚至发散
- 学习率太小:收敛非常慢,训练时间长,可能陷入局部最优
常见学习率调整策略
- 分段常数衰减:验证集性能不提升时,学习率除以2或5
- 指数衰减:学习率按指数规律递减:αt=α0∗γt
- 多项式衰减:学习率按多项式递减
- 余弦退火(Cosine Annealing):学习率按余弦周期变化,配合热重启
- 线性衰减:从初始学习率线性降到0
学习率选择建议
- 从大范围试,找一个loss下降最快的学习率
- 训练过程中监测验证集,性能平台期就衰减学习率
- 不要用太大的初始学习率,也不要太小
Batch Normalization
为什么需要BN
深度神经网络训练过程中,每一层参数更新会导致下一层输入分布发生变化,这叫做内部协变量偏移,使得训练变得困难。BN通过归一化每一层的输入,稳定分布,加速训练。
BN算法步骤
对于一个mini-batch的激活输入:
- 计算batch均值:μB=m1∑i=1mxi
- 计算batch方差:σB2=m1∑i=1m(xi−μB)2
- 归一化:x^i=σB2+ϵxi−μB
- 缩放平移:yi=γx^i+β
γ和β是可学习参数,恢复网络的表达能力,如果需要原始分布,可以学习得到。
BN的优点
- 可以使用更高的学习率,加速收敛
- 缓解梯度消失问题,让训练更稳定
- 减少对初始化的依赖
- 具有一定正则化效果,可以减少Dropout的使用
- 允许网络使用更大的学习率,训练更快
BN训练 vs 测试
- 训练时:用当前batch的均值和方差做归一化,同时用滑动平均保存全局均值方差
- 测试时:用训练好的全局均值和方差,不使用当前batch统计量
其他归一化技术
Layer Normalization (LN)
- BN对batch依赖,batch太小统计量不准,RNN序列模型每个长度不同,BN不好用
- LN对单个样本的隐藏层归一化,按特征归一化,不依赖batch size
- 适用场景:RNN、Transformer、小batch-size、序列模型
Instance Normalization (IN)
- 对每个样本的每个通道单独归一化
- 适用场景:图像生成任务,风格迁移
Group Normalization (GN)
- 将通道分成组,在组内归一化
- 不依赖batch size,batch很小时比BN好
- 适用场景:计算机视觉,小batch
对比总结
| 方法 | 归一化维度 | 适用场景 |
|---|
| BatchNorm | 跨batch,按通道 | CV,大batch,CNN |
| LayerNorm | 跨特征,按样本 | NLP,Transformer,RNN |
| InstanceNorm | 跨空间,按样本通道 | 图像生成,风格迁移 |
| GroupNorm | 分组,按样本 | CV,小batch |
正则化技术
什么是过拟合
模型在训练集上表现很好,但在测试集上表现很差,模型过度拟合了训练数据中的噪声,泛化能力差。
产生原因:
- 模型复杂度太高,能力太强
- 训练数据太少,噪声多
- 训练迭代太多
防止过拟合的方法
- L1/L2正则化:损失函数加惩罚项,限制权重大小
- Dropout:训练时随机失活神经元,减少共适应
- Batch Normalization:稳定分布,有正则化效果
- 数据增强:增加训练数据多样性
- 早停:验证集性能下降就停止训练
- 集成学习:多个模型投票,降低方差
- 剪枝:移除冗余参数
L1 vs L2正则化
| L1正则化 | L2正则化 |
|---|
| 惩罚项是$\lambda \sum | w_i |
| 产生稀疏解,很多权重为0 | 不会产生稀疏性,权重都很小但不为0 |
| 可以做特征选择 | 防止过拟合,提升泛化 |
| 0点不可导,需要特殊处理 | 处处可导,计算简单 |
为什么L1正则化能产生稀疏性:
L1在原点处绝对值的导数是常数,最优解很容易落在原点,使得很多权重变为0,从而得到稀疏解。
Dropout
- 训练:每个神经元以概率p保留,概率1-p失活
- 测试:保留所有神经元,权重乘以p(或者训练时缩放)
- 原理:减少神经元之间的共适应,迫使网络学习更鲁棒的特征,相当于集成多个模型
早停 (Early Stopping)
- 监测验证集性能,当验证集性能不再提升时停止训练
- 最简单有效的正则化方法,防止过度训练
面试常见问题
-
**SGD、BGD、MBGD的区别?
- BGD:用全部数据计算一次梯度,更新一次。收敛稳定但速度慢,不适合大数据。
- SGD:每次用一个样本更新一次。速度快支持在线学习,但梯度方差大震荡。
- MBGD:每次用一小批样本,兼顾速度和稳定性,是现在深度学习主流。
-
**Momentum为什么能加速训练?
动量累加历史梯度的指数移动平均,如果当前梯度方向和历史一致就加速,不一致就抑制震荡,减少了SGD的摆动,使得收敛更快。
-
**Adam的原理是什么?偏差修正的作用?
Adam维护梯度一阶矩(动量)和二阶矩(梯度平方)的指数移动平均,做偏差修正后更新参数。偏差修正是因为初始m和v都是0,迭代初期期望偏置接近0,修正后更准确。
-
**AdamW和Adam的区别是什么?
AdamW正确解耦了权重衰减和梯度更新。原始Adam中将权重衰减等价于L2正则化实现不正确,AdamW将权重衰减直接应用到参数上, decouple了权重衰减和梯度,在fine-tuning大模型上泛化更好。
-
**Adam vs SGD,各有什么优缺点?
- Adam:收敛快,自适应学习率,调参方便,适合快速验证模型。但最终泛化性能可能不如SGD。
- SGD:简单,最终泛化性能更好,适合大数据集最终精调。但对学习率敏感,收敛较慢。
- 常用策略:Adam热身快速下降,然后SGD精调。
-
**BN的原理是什么?训练和测试有什么区别?
BN通过对每一层激活做归一化,解决内部协变量偏移,稳定训练。训练时用当前batch的均值方差,测试时用训练阶段滑动平均得到的全局均值方差。通过γ和β可学习缩放平移保留表达能力。
-
**BN、LN、GN、IN的区别?分别用在什么场景?
- BN:按batch归一化,适合CV大batch,CNN
- LN:按样本特征归一化,不依赖batch,适合NLP、Transformer、RNN
- GN:分组归一化,适合CV小batch
- IN:按实例归一化,适合图像生成、风格迁移
-
**学习率太大或太小会发生什么?
- 太大:梯度更新幅度过大,loss震荡,不收敛,甚至发散,weights变成NaN
- 太小:收敛非常慢,训练时间长,可能陷入不好的局部最优
-
**什么是梯度裁剪?用来解决什么问题?
梯度裁剪就是当梯度范数超过某个阈值时,将梯度按比例缩放,限制最大范数。主要用来解决梯度爆炸问题,在RNN和深层网络中常用。
-
**为什么Batch Normalization能加速训练?
BN把每一层输出归一化到均值0方差1,缓解了梯度消失,使得梯度更大,更新更有效;同时减少了内部协变量偏移,每一层分布更稳定,不需要不断适应新分布,所以训练收敛更快。
-
**Dropout在训练和测试时有什么不同?
训练时随机失活一部分神经元,迫使网络不依赖个别神经元,增加鲁棒性。测试时所有神经元都保留,不做随机失活,并且权重要按dropout概率缩放(或者训练时已经缩放了,测试不用变)。
-
**L1正则化怎么处理不可导的问题?
常用方法有:坐标轴下降法、近端梯度下降、ADMM交替方向乘子法。