本文目录导读:

设置优化工具参数是一个需要结合理论理解和实际调试的过程,没有一套“万能参数”适用于所有问题,我为你梳理一个通用的方法论和具体步骤,涵盖常见的梯度下降类和进化类算法。
核心原则:观察损失曲线,理解“欠拟合”与“过拟合”。
第一阶段:理解核心参数
最常用的优化器是 Adam 和 SGD (随机梯度下降),它们的核心参数不同。
学习率 —— 最重要的参数
- 定义:控制参数更新的步长。
- 太大:损失值剧烈震荡,甚至发散(不收敛)。
- 太小:训练速度极慢,容易陷入局部最优。
- 常见范围:0.1 ~ 0.00001(对数尺度调整)。
动量 —— 适用于 SGD
- 定义:模拟物理惯性,让更新方向不仅依赖当前梯度,也依赖历史梯度。
- 作用:加速收敛,平滑震荡,帮助跳出局部极小值。
- 常见值:0.9、0.99。
Adam 的 β1, β2 和 ε
- β1(一阶矩衰减):通常取 0.9(记忆近期梯度)。
- β2(二阶矩衰减):通常取 0.999(记忆近期梯度平方)。
- ε:防止除以零,默认 1e-8 通常足够。
- 特殊点:Adam 自带自适应学习率,通常比 SGD 更容易调,但泛化性能有时稍差。
权重衰减 / L2 正则化 —— 防止过拟合
- 定义:在更新时对权重进行衰减惩罚。
- 太大:欠拟合,模型过于简单。
- 太小:过拟合。
- 常见范围:1e-4 ~ 1e-6。
批次大小 (Batch Size)
- 定义:每次更新参数时使用的样本数量。
- 太大:内存占用高,收敛慢,降低泛化能力。
- 太小:梯度噪声大,训练不稳定,收敛慢。
- 常见值:32、64、128、256,通常使用 32 或 64 作为起点。
第二阶段:分步调试流程(实践方法)
不要盲目随机尝试,按以下顺序调整:
-
先固定
- 选择一个常见优化器,如 Adam(对新手友好)。
- 设学习率为 1e-3(Adam的常用起点)。
- 设批次大小为 32 或 64。
- 不加入权重衰减(设为 0)。
-
观察初始训练曲线
- 运行几轮(epoch)。
- 如果损失值不下降:说明学习率太小或模型有问题(需排查网络结构)。
- 如果损失值变成 NaN 或剧烈震荡:说明学习率太大。
-
调整学习率(关键步骤)
- 学习率搜索:从 1e-5 开始,以 3 倍或 10 倍的间隔尝试(1e-5, 3e-5, 1e-4, 3e-4, 1e-3, 3e-3, 1e-2)。
- 运行少量迭代,观察哪个学习率让损失下降最快最稳。
- Adam 在 1e-3 ~ 3e-4 之间表现良好;SGD 在 1e-1 ~ 1e-3 之间。
-
观察过拟合现象
- 当训练损失持续下降但验证损失不再下降或开始上升时,说明过拟合。
- 策略:
- 增加权重衰减:尝试 1e-4, 3e-4, 1e-3。
- 减小模型容量(减少层数/神经元)。
- 使用 Dropout 或 数据增强。
-
调整批次大小
- 如果显存够用,尝试把批次大小翻倍(64 -> 128)。
- 注意:增大批次通常需要相应增加学习率(线性缩放法则)。
-
替换为 SGD + 动量
- 当 Adam 的验证集性能达到瓶颈时,可以尝试迁移到 SGD。
- 设学习率=0.01,动量=0.9,SGD 通常需要更精细的“学习率调度”才能发挥威力。
第三阶段:进阶技巧(自动调参)
学习率调度 (Learning Rate Scheduler)
- 阶梯式衰减:每若干轮(epoch)将学习率乘以一个因子(如 0.1)。
- 余弦退火:学习率随周期余弦下降,有时能跳出局部最优。
- ReduceLROnPlateau:当验证损失停滞时自动降低学习率。
超参数优化工具
-
网格搜索:穷举所有组合(计算成本高)。
-
随机搜索:随机选取组合,通常比网格搜索更有效。
-
贝叶斯优化:基于先前结果智能推荐下一个参数组合(工具:Optuna, Hyperopt, Ray Tune)。
示例使用 Optuna 框架:
import optuna def objective(trial): # 建议要调参的值 lr = trial.suggest_loguniform('lr', 1e-5, 1e-1) batch_size = trial.suggest_categorical('batch_size', [32, 64, 128]) weight_decay = trial.suggest_loguniform('weight_decay', 1e-6, 1e-2) optimizer_name = trial.suggest_categorical('optimizer', ['SGD', 'Adam']) # 用这些参数训练模型 model = MyModel() optimizer = get_optimizer(model, optimizer_name, lr, weight_decay) accuracy = train_and_evaluate(model, optimizer, batch_size) return accuracy # 返回要优化的指标 study = optuna.create_study(direction='maximize') study.optimize(objective, n_trials=50) # 运行50次实验 print(study.best_params)
第四阶段:常见问题与解决
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 损失值不下降 | 学习率太小;模型未收敛 | 增大学习率;增加迭代次数 |
| 损失值震荡 / NaN | 学习率太大;梯度爆炸 | 减小学习率;添加梯度裁剪;检查数据是否有异常值 |
| 过拟合 | 模型复杂;数据少;权重衰减太小 | 增加权重衰减;使用 Dropout;数据增强;降低模型复杂度 |
| 欠拟合 | 模型容量不足;权重衰减太大 | 增加模型层数/神经元;减小权重衰减;确保学习率合适 |
最优参数从何而来?
- 从已知最佳实践开始:查阅类似任务(如图像分类用ResNet、文本用Transformer)的论文,用它们的参数作为起点。
- 快速小规模测试:先用少量 data 训练少量 epoch,快速定位学习率范围。
- 使用自动调参库:让 Optuna 或 Ray Tune 帮你跑 50-100 个参数组合,通常能找到在验证集上表现最好的配置。
没有银弹,每次更换数据集、模型架构或任务类型(分类 vs 生成 vs 强化学习),都需要重新调整参数,记录每次实验的参数和结果,形成自己的调参经验库。
标签: 参数设置
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。