资讯动态

机器学习学习率调参指南:从原理到实战的优化策略

发布时间:2026/10/14 14:12:15 来源:尧图企业网站定制
1. 学习率 η 到底在调什么从参数更新公式说起很多人第一次接触机器学习最先记住的超参数就是学习率通常写成 η 或者 α。它出现在几乎所有梯度类优化器的更新公式里最朴素的形式是# 最基础的梯度下降更新 # theta: 当前参数 # grad: 当前参数处的梯度 # eta: 学习率 theta theta - eta * grad这个公式看起来简单到不能再简单但它背后藏着整个训练过程最核心的权衡。η 决定了你每次沿着梯度反方向迈出的步子有多大。步子太小收敛慢训练到天荒地老步子太大直接跨过最低点损失函数震荡甚至发散。我见过太多项目模型结构设计得漂漂亮亮数据清洗也做得干干净净最后卡在 loss 不下降一查就是学习率设成了 0.1 这种“默认值”。这里有个很直观的类比。你可以把损失函数想象成一片连绵的山谷参数就是山谷里的一个位置梯度告诉你脚下哪边是下坡。学习率就是你每一步跨出去的距离。山谷平缓的地方你跨大一点没关系但接近谷底的时候如果还跨那么大就会在谷底两边来回横跳永远停不下来。所以真正难的地方在于同一个 η 不可能对所有参数、所有训练阶段都最优。这也是为什么后来出现了动量、AdaGrad、RMSProp、Adam 这一系列自适应优化器。它们本质上都在做一件事让每个参数的有效学习率根据历史梯度动态调整。但即便如此基础学习率 η 仍然是这些优化器里最需要手工干预的超参数。Adam 的默认 1e-3 在不少任务上能跑但你要真想榨出模型性能η 还是得调。从理论角度看学习率和损失函数的曲率直接相关。对于二次型损失最优的固定学习率是 2/(Lμ)其中 L 是最大曲率μ 是最小曲率。这个式子告诉我们两件事条件数 L/μ 越大最优学习率越小而且单一学习率很难同时兼顾曲率差异大的方向。这就是为什么在实际项目里我们往往需要学习率调度策略而不是一个固定值从头用到尾。2. 常见学习率调度策略与选型逻辑2.1 阶梯衰减、余弦退火与热重启的适用场景固定学习率在早期训练阶段通常没问题但到了中后期损失曲面变得平坦大学习率会导致参数在最优点附近反复跳动验证集指标上不去。这时候就需要调度策略介入。阶梯衰减是最早被广泛使用的方案。比如每 30 个 epoch 把学习率乘以 0.1。它的逻辑很直接训练初期大步快走后期小步微调。但阶梯衰减的问题在于衰减时机和倍率都是超参数设得不好要么衰减太早导致欠拟合要么衰减太晚浪费计算资源。余弦退火是这几年更受欢迎的方案。学习率按照余弦曲线从初始值平滑下降到接近零import math def cosine_annealing(eta_max, eta_min, T_cur, T_max): return eta_min 0.5 * (eta_max - eta_min) * (1 math.cos(math.pi * T_cur / T_max))它的优势是下降过程平滑没有阶梯衰减那种突变模型在后期能更稳定地收敛到局部最优。而且余弦退火天然适合配合热重启使用每隔 T_max 个 epoch 把学习率重置回初始值让模型有机会跳出当前局部最优探索新的区域。我在几个图像分类任务上对比过余弦退火加热重启相比固定学习率验证集准确率通常能高出 1 到 3 个百分点训练后期 loss 曲线也更干净。2.2 预热阶段为什么越来越重要如果你用过 Transformer 类模型一定见过 warmup 这个设置。预热阶段的学习率从接近零线性增加到初始值通常持续几百到几千步。为什么需要这个因为模型刚初始化时参数是随机的梯度方向可能非常嘈杂。如果一上来就用大学习率很容易把参数推到糟糕的区域后面很难拉回来。预热的步数选择有个经验公式总训练步数的 1% 到 5% 之间。太少起不到稳定作用太多则浪费训练时间。我一般会先设成总步数的 2%然后观察前几百步的 loss 曲线。如果 loss 在预热结束后出现明显尖峰说明预热不够如果预热阶段 loss 几乎不降说明预热太长或者初始学习率太低。2.3 不同优化器下的学习率默认值与调整范围优化器常用默认 η典型调整范围适用场景SGD0.01 ~ 0.11e-3 ~ 1e-1计算机视觉配合动量SGDMomentum0.01 ~ 0.11e-3 ~ 1e-1ResNet 等经典网络Adam1e-31e-5 ~ 1e-2NLP、TransformerAdamW1e-31e-5 ~ 1e-2带权重衰减的 TransformerRMSProp1e-31e-5 ~ 1e-2RNN、强化学习这张表只是起点不是终点。我见过在某个细粒度分类任务上SGD 用 0.001 比 0.01 效果好很多也见过在另一个任务上Adam 用 3e-4 比 1e-3 稳定。关键还是得结合具体任务做实验。3. 学习率搜索的实操方法与参数计算3.1 学习率范围测试一次运行找到合理区间Leslie Smith 提出的学习率范围测试是我最推荐的方法。做法很简单从一个极小的学习率开始每个 batch 后按指数增长同时记录 loss最后画出 loss 随学习率变化的曲线。import torch import torch.optim as optim import matplotlib.pyplot as plt def lr_range_test(model, train_loader, criterion, start_lr1e-7, end_lr1.0, num_iter200): optimizer optim.SGD(model.parameters(), lrstart_lr) lrs [] losses [] lr_mult (end_lr / start_lr) ** (1 / num_iter) for i, (inputs, targets) in enumerate(train_loader): if i num_iter: break optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, targets) loss.backward() optimizer.step() lrs.append(optimizer.param_groups[0][lr]) losses.append(loss.item()) for param_group in optimizer.param_groups: param_group[lr] * lr_mult plt.plot(lrs, losses) plt.xscale(log) plt.xlabel(Learning Rate) plt.ylabel(Loss) plt.show()看曲线的时候找 loss 下降最快的那段区间通常取下降段中点对应的学习率作为初始值或者取下降段起点稍大一点的值。如果曲线在某个点之后开始上升那个点就是发散阈值你的学习率绝对不能超过它。3.2 网格搜索与随机搜索的取舍网格搜索适合参数维度低、计算资源充足的情况。比如你只想调学习率和权重衰减两个参数各取 5 个值一共 25 组实验跑起来还能接受。但一旦维度上去网格搜索的代价是指数增长的。随机搜索在同样计算预算下通常更高效因为不是所有超参数都同等重要。学习率往往是最重要的那个随机搜索能让它在更大范围内被采样到。我一般会先做 20 到 30 组随机搜索锁定学习率的大致范围再在这个范围附近做精细网格。3.3 基于预算的贝叶斯优化入门如果计算资源有限贝叶斯优化是更聪明的选择。它通过高斯过程建模超参数与目标函数的关系每次选择最有希望提升的点进行实验。常用工具是 Optuna 或 Ax。import optuna def objective(trial): lr trial.suggest_loguniform(lr, 1e-5, 1e-1) weight_decay trial.suggest_loguniform(weight_decay, 1e-6, 1e-2) model build_model() optimizer optim.AdamW(model.parameters(), lrlr, weight_decayweight_decay) val_acc train_and_evaluate(model, optimizer) return val_acc study optuna.create_study(directionmaximize) study.optimize(objective, n_trials50) print(study.best_params)贝叶斯优化的好处是通常 30 到 50 次实验就能找到不错的配置比随机搜索省一半以上的计算量。但它也有代价每次实验的串行依赖比较强不太适合大规模并行。4. 训练中学习率异常的排查与调整实录4.1 loss 震荡、发散与 NaN 的应对训练过程中最常见的异常就是 loss 震荡。如果 loss 在某个值附近上下跳动但整体不下降大概率是学习率偏大。这时候可以先尝试把学习率降一个数量级观察 loss 是否变得平滑。如果降了之后 loss 下降但速度太慢再考虑加预热或者换自适应优化器。发散比震荡更严重表现为 loss 迅速增大甚至变成 NaN。遇到这种情况第一步是检查数据里有没有异常值或者标签错误第二步是把学习率降到原来的十分之一甚至百分之一。如果降了还是发散那可能是模型结构或者初始化有问题不能全怪学习率。NaN 的出现往往和梯度爆炸有关。除了降低学习率还可以加梯度裁剪torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0)这个操作会把梯度范数限制在 1.0 以内防止个别 batch 产生过大梯度把参数带飞。我在训练 RNN 和深层 Transformer 时基本都会加上。4.2 验证集指标不升反降的判断思路有时候训练 loss 在降但验证集指标不升反降这通常是过拟合的信号但也可能是学习率调度不当。如果学习率在训练后期仍然偏大模型会在最优点附近跳动验证集指标就会波动。这时候可以尝试更激进的衰减策略比如把余弦退火的周期缩短或者手动在验证指标停滞时把学习率乘以 0.5。还有一种情况是训练初期验证指标上升很快然后突然掉下去。这往往是因为学习率太大模型跳出了好的区域。加预热或者降低初始学习率通常能解决。4.3 学习率与 batch size 的联动关系学习率和 batch size 不是独立的。经验规则是batch size 翻倍学习率也大致翻倍。这个规则的背后逻辑是更大的 batch 提供了更准确的梯度估计所以可以迈更大的步子。但这不是线性的当 batch size 大到一定程度学习率的增益会递减。Batch Size建议学习率缩放说明321x基准641.5x ~ 2x常用配置1282x ~ 3x需要预热2563x ~ 4x建议配合 warmup5124x ~ 6x需要线性缩放预热我在实际项目里一般会先固定 batch size调好学习率再尝试增大 batch size 并同步调整学习率。如果增大 batch size 后效果变差那可能是学习率没跟上或者需要加预热。5. 进阶话题从自适应优化器到学习率与架构的协同5.1 Adam 家族中 η 的角色变化Adam 的出现让很多人觉得学习率不用怎么调了默认 1e-3 就能跑。但 Adam 里的 η 仍然重要它决定了更新量的整体尺度。Adam 的自适应机制主要调整的是各参数更新方向的相对比例而不是整体步长。所以当你把 η 从 1e-3 降到 1e-4所有参数的更新幅度都会缩小训练变慢但可能更稳定。AdamW 把权重衰减从梯度更新里解耦出来这让学习率和权重衰减的关系更清晰。我通常会把学习率设成 1e-3 到 3e-4权重衰减设成 0.01 到 0.1然后根据验证集表现微调。5.2 学习率与权重衰减、dropout 的交互影响学习率、权重衰减和 dropout 都在控制模型的有效复杂度。学习率大模型探索范围广可能更容易过拟合权重衰减大参数被拉向零模型更保守dropout 高训练时随机丢弃神经元相当于集成学习。这三者需要协同调整。我的经验是如果验证集过拟合明显先加权重衰减或 dropout而不是急着降学习率。降学习率会让训练变慢但不一定解决过拟合。反过来如果训练 loss 都降不下去那优先调学习率而不是加正则化。5.3 小样本、迁移学习场景下的 η 设置经验小样本任务上模型容易过拟合学习率通常要设小一点比如 1e-4 到 1e-5。如果做迁移学习微调预训练模型时底层参数的学习率应该比顶层小。常见做法是分层设置学习率optimizer optim.AdamW([ {params: model.base.parameters(), lr: 1e-5}, {params: model.classifier.parameters(), lr: 1e-3} ], weight_decay0.01)这样底层只做微小调整顶层可以快速适应新任务。我在几个小样本分类项目里用这个策略相比统一学习率验证集准确率能高出 5 到 10 个百分点。6. 我踩过的坑与常用排查清单6.1 学习率设置中最容易犯的五个错误第一个错误是直接用默认值不调。很多教程里 Adam 用 1e-3但你的任务可能适合 3e-4 或者 5e-4。第二个错误是只调学习率不看其他超参数。学习率和 batch size、权重衰减是联动的单独调一个往往事倍功半。第三个错误是训练全程用固定学习率。除非你的任务特别简单否则后期衰减几乎总是有帮助的。第四个错误是预热时间设得太短或太长。预热太短起不到稳定作用太长浪费计算。第五个错误是不记录实验。学习率调参是个迭代过程不记录每次的配置和结果很容易重复踩坑。6.2 一套可复用的学习率调参流程我现在的流程基本固定下来了。第一步用学习率范围测试找到大致区间。第二步在这个区间内做 10 到 20 组随机搜索配合余弦退火和预热。第三步选验证集最好的 3 组配置跑完整训练并观察 loss 曲线。第四步如果效果还不够尝试分层学习率或者换优化器。第五步把最终配置和结果记录下来方便以后参考。这套流程在图像分类、文本分类、序列标注任务上都用过基本能在可接受的计算预算内找到不错的学习率配置。6.3 常见问题速查表现象可能原因优先尝试loss 震荡不降学习率偏大降一个数量级loss 下降太慢学习率偏小升 2 到 5 倍loss 变 NaN梯度爆炸降学习率梯度裁剪验证指标波动后期学习率偏大加强衰减训练初期不稳定缺少预热加 warmup过拟合明显正则不足加权重衰减/dropout微调效果差分层学习率未设底层小顶层大这张表是我自己排查时最常用的基本覆盖了八成以上的学习率相关问题。当然具体问题还得具体分析但有个起点总比盲目试要好。学习率这个事说到底是个经验活。理论能告诉你方向但具体数值还是得靠实验。我自己的体会是与其花大量时间追求最优学习率不如先把数据、模型结构、训练流程这些基础打好学习率调参的收益才会显现出来。如果基础有问题再好的学习率也救不回来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑