参数选择
1. 优化器(Optimizer)
作用:
优化器负责 根据损失函数的梯度来更新模型参数,目标是逐步减小损失值,使模型逼近最优解。
核心机制:
计算梯度:通过反向传播(Backpropagation)计算损失函数对模型参数的梯度。
参数更新:根据梯度方向和优化策略来调整参数。
常见优化器类型:
优化器 | 特点 | 适用场景 |
---|---|---|
SGD | 基础随机梯度下降,无动量,直接沿负梯度方向更新参数。 | 简单任务,需精细调参时。 |
SGD + Momentum | 引入动量(惯性),累积历史梯度方向,加速收敛并减少震荡。 | 非凸优化、存在局部极小值的场景。 |
Adam | 结合动量(一阶矩估计)和自适应学习率(二阶矩估计),自动调整学习率。 | 大多数深度学习任务,默认选择。 |
AdamW | 在Adam基础上解耦权重衰减 | 大规模深度学习模型 |
RMSprop | 自适应调整学习率,对梯度平方进行指数加权平均,缓解学习率消失问题。 | RNN、非平稳目标函数场景。 |
Adagrad | 为每个参数分配独立的学习率,适合稀疏数据,但学习率会单调下降至零。 | 自然语言处理、稀疏特征任务。 |
AdamW 和 Adam 的详细对比:
- 权重衰减(Weight Decay)的作用
权重衰减是一种正则化方法,通过在损失函数中加入参数的 L2 范数(即权重平方和),防止模型过拟合。其公式为:
$$
L_{total}=L_{task}+λ⋅\frac{1}{2}∑_iw_i^2
$$
其中:
Ltask 是任务损失(如交叉熵损失)。
λ 是权重衰减系数。
wi 是模型参数(较小的权重意味着模型不会对输入特征的微小变化过于敏感,从而降低了模型的复杂度)。
在优化过程中,权重衰减会直接影响参数的更新。
2. Adam 中的权重衰减问题
在 Adam 优化器中,权重衰减被直接添加到梯度中,导致权重衰减与自适应学习率耦合。具体表现为:
权重衰减的梯度会被 Adam 的自适应学习率机制(如动量、二阶矩估计)调整。
这种耦合会导致权重衰减的效果不稳定,尤其是在学习率较大时,可能无法有效防止过拟合。
3. AdamW 的改进
AdamW 将权重衰减从梯度更新中分离出来,直接作用于参数本身,而不是通过梯度调整。具体改进如下:
解耦权重衰减:
在 Adam 中,权重衰减被添加到梯度中:
$$
g_t=∇L(w_t)+λw_t
$$在 AdamW 中,权重衰减直接作用于参数:
$$
w_{t+1}=w_t−η⋅Adam(g_t)−ηλw_t
$$其中:
η 是学习率。
Adam(gt) 是 Adam 优化器的更新规则。
λ 是权重衰减系数。
更稳定的正则化效果:
由于权重衰减不再受自适应学习率的影响,其正则化效果更加稳定。
能够更好地防止过拟合,尤其是在大规模数据集和复杂模型上。
4. AdamW 的优势
更好的泛化能力:通过解耦权重衰减,AdamW 能够更有效地控制模型复杂度,提高泛化性能。
更稳定的训练:权重衰减的效果不再受自适应学习率的影响,训练过程更加稳定。
适用于大规模模型:在训练大规模模型(如 Transformer、BERT)时,AdamW 表现优于 Adam。
5. 使用场景
推荐使用 AdamW 的场景:
训练大规模深度学习模型(如 Transformer、BERT)。
需要较强的正则化效果(如防止过拟合)。
训练过程中学习率变化较大(如使用学习率调度器)。
推荐使用 Adam 的场景:
简单任务或小规模模型。
不需要强正则化效果的任务。
Momentum(动量)
原理
momentum
借鉴了物理学中动量的概念,在优化算法(如随机梯度下降 SGD)中引入动量项可以加速收敛并减少震荡。在传统的随机梯度下降中,参数的更新仅依赖于当前计算得到的梯度。而引入动量后,参数的更新不仅考虑当前梯度,还会结合之前的更新方向。
具体来说,动量优化算法在更新参数时,会计算一个累积的梯度移动平均值。这个移动平均值就像物体的动量,它会使得梯度更新具有一定的惯性,使得在梯度方向大致不变的地方能够加速前进,而在梯度方向频繁变化的地方能够减少震荡。
作用
- 加速收敛:当梯度方向保持一致时,动量项会不断累积,使得参数更新的步长增大,从而加快模型收敛的速度。例如,在一些鞍点或者平缓区域,传统的 SGD 可能会收敛很慢,而引入动量后可以更快地跳出这些区域。
- 减少震荡:在梯度方向频繁变化的地方,动量项会起到平滑的作用,减少参数更新的震荡,使得模型的训练过程更加稳定。
定义优化器
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999)) |
2. 学习率调度器(Learning Rate Scheduler)
作用:
学习率调度器在训练过程中 动态调整学习率,平衡收敛速度与稳定性,避免陷入局部极小值。
核心机制:
学习率衰减:随着训练进行,逐步减小学习率,使模型在后期更精细地调整参数。
周期性调整:通过周期性变化的学习率,帮助模型跳出局部极小值。
常见调度器类型:
调度器 | 特点 | 适用场景 |
---|---|---|
StepLR | 每隔固定epoch将学习率乘以衰减因子(如每10个epoch学习率×0.1)。 | 简单任务,稳定收敛。 |
CosineAnnealingLR | 按余弦函数周期性调整学习率,从初始值下降到最小值再回升,帮助跳出局部极小。 | 存在多个局部极小值的复杂优化场景。 |
ReduceLROnPlateau | 监控验证集损失,当损失不再下降时自动降低学习率。 | 需要自适应调整学习率的任务。 |
OneCycleLR | 结合线性增长和余弦退火,在训练中先升后降学习率,加速收敛并提高泛化能力。 | 快速训练(如图像分类)。 |
ExponentialLR | 每个epoch按指数衰减学习率(如学习率×0.95)。 | 需要平滑衰减的场景。 |
示例(Poly学习策略):
def poly_lr(epoch): |
其它:
optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100, eta_min=1e-6) |
3. 优化器与调度器的协同工作
训练流程:
前向传播:输入数据计算预测值。
计算损失:比较预测值与真实值的差异。
反向传播:计算损失对参数的梯度。
优化器更新:根据梯度更新参数。
调度器调整:按策略更新学习率(通常在每个epoch或batch后)。
代码示例:
python
复制
for epoch in range(num_epochs):
model.train()
for batch in train_loader:
inputs, labels = batch
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step() # 优化器更新参数
# 每个epoch后调整学习率
scheduler.step()
4. 选择优化器和调度器的策略
优化器选择:
默认选择:优先尝试 Adam(自适应学习率,适用于大多数任务)。
精细调优:使用 SGD + Momentum(需要手动调参,但可能达到更高精度)。
调度器选择:
简单任务:使用 StepLR 或 ExponentialLR。
复杂优化:使用 CosineAnnealingLR 或 OneCycleLR。
自适应调整:使用 ReduceLROnPlateau(依赖验证集监控)。
5. 实际应用技巧
学习率预热(Warmup):
训练初期逐步增大学习率,避免初始梯度不稳定(尤其适用于大模型)。权重衰减(Weight Decay):
在优化器中加入L2正则化,防止过拟合(如AdamW优化器)。梯度裁剪(Gradient Clipping):
限制梯度幅值,防止梯度爆炸(常见于RNN)。
总结
优化器:决定如何利用梯度更新参数,直接影响收敛速度和稳定性。
调度器:动态调整学习率,平衡探索(大学习率)与开发(小学习率)。
协同作用:合理搭配优化器和调度器,可显著提升模型性能和训练效率。
batch_size
batch_size
(批量大小)不同会显著影响模型的训练结果,下面从收敛速度、泛化能力、内存使用等多个方面详细分析其影响:
对收敛速度的影响
- 较大的
batch_size
- 通常情况下,较大的
batch_size
能让梯度计算更稳定。因为它基于更多样本的信息来更新模型参数,梯度估计的方差较小,使得参数更新的方向更接近真实的最优方向。这样在训练初期,模型可能会更快地朝着最优解的方向前进。 - 例如,在大规模图像分类任务中,使用较大的
batch_size
(如 256 或 512)可以让模型在较少的迭代次数内达到较高的准确率。 - 然而,当接近最优解时,较大的
batch_size
可能会导致模型越过最优解,难以收敛到精确的最优值,因为每次更新的步长相对较大。
- 通常情况下,较大的
- 较小的
batch_size
- 较小的
batch_size
使得梯度估计的方差较大,每次参数更新的方向可能会有较大波动。但这种随机性也可以帮助模型跳出局部最优解,有可能找到更优的全局最优解。 - 不过,由于梯度不稳定,模型的收敛速度可能会较慢,需要更多的迭代次数才能达到较好的训练效果。例如,在一些复杂的生成对抗网络(GAN)训练中,较小的
batch_size
(如 16 或 32)可以增加训练的随机性,有助于生成更真实的样本。
- 较小的
对泛化能力的影响
- 较大的
batch_size
- 可能会导致模型过拟合。因为较大的
batch_size
会使模型在训练过程中对数据的统计特征学习得过于精细,容易记住训练数据中的噪声和特定模式,而忽略了数据的一般性规律。 - 例如,在图像识别任务中,如果
batch_size
过大,模型可能会对训练集中某些图像的特殊特征过度敏感,而在测试集上表现不佳。
- 可能会导致模型过拟合。因为较大的
- 较小的
batch_size
- 一般能提高模型的泛化能力。较小的
batch_size
引入的随机性使得模型在不同的小批量数据上学习,能够更好地捕捉数据的多样性,从而在测试集上表现出更好的泛化性能。
- 一般能提高模型的泛化能力。较小的
对内存使用和训练时间的影响
- 较大的
batch_size
- 需要更多的内存来存储每个批次的数据和中间计算结果。如果显存有限,可能会导致内存溢出的错误。
- 但由于每次迭代处理的样本数量较多,在一定程度上可以减少训练所需的迭代次数,从而可能缩短总的训练时间。
- 较小的
batch_size
- 内存占用较少,适合在显存较小的设备上训练模型。
- 然而,由于需要更多的迭代次数才能完成训练,总的训练时间可能会更长。