学习率与调度器:今天真正弄懂
先记住:一句话定义 + 一句记忆口诀
学习率(Learning Rate, $\eta$)是模型参数更新的“步长”;调度器(Scheduler)是训练过程中动态调整这个步长的“变速器”。
【生活类比】 想象你蒙着眼睛在山谷里找最低点(下山): - 学习率就是你每走一步迈出的距离。迈太大容易扯着蛋直接跳过谷底甚至坠崖(梯度爆炸/无法收敛);迈太小像蚂蚁爬,天黑了也到不了山底(训练极慢或卡在局部鞍点)。 - 调度器就像你的策略导航:一开始不熟悉地形先小心试探(Warmup 预热),中间路好走大步流星,快到谷底时慢慢小碎步精细调整(Cosine 退火衰减)。
【核心公式与符号】 最基础的梯度更新公式: $$W_{t+1} = W_t - \eta_t \cdot \nabla L(W_t)$$ - $W_t$:当前时刻第 $t$ 步的模型参数(权重)。 - $\nabla L(W_t)$:损失函数对当前参数的梯度(告诉你往哪走是上坡)。 - 负号($-$):因为要找损失最低点,必须逆着梯度方向下坡。 - $\eta_t$:第 $t$ 步的学习率。如果用了调度器,$\eta_t$ 会随时间 $t$ 动态变化,而不是固定常数。
【它解决什么问题?没有它会怎样?】 - 没有合适的学习率:模型要么 Loss 变成 NaN(步子太大炸了),要么 Loss 停在 2.3 纹丝不动(步子太小学不动)。 - 没有调度器(只用恒定学习率):前期模型参数随机初始化,大梯度容易把预训练好的特征洗坏;后期参数接近最优解,固定大步长会在最优解附近来回震荡跳跃,无法精细收敛到最低 Loss。
【在音视频理解与说话人日志中的实际用法】 1. 说话人日志(Speaker Diarization / ECAPA-TDNN):提取声纹 Embedding 时,通常使用 `CosineAnnealingLR` 或 `CyclicLR`,配合 5~10% steps 的线性 Warmup,防止分类损失(如 AAM-Softmax)在训练初期大梯度破坏声学浅层卷积层。 2. 音视频大模型(如 Whisper、Video-LLaMA 微调):冻结主干只微调音频投影层或 LoRA 时,微调模块用较大学习率(如 $1\text{e-}4$),预训练主干若解冻则用极小学习率(如 $1\text{e-}6$)进行差异化衰减调度。
学习率过大和过小分别会导致模型出现什么现象?
Warmup(预热)的主要目的是什么?
余弦衰减(Cosine Decay)调度器的学习率变化曲线是怎样的?
【发展流程:之前怎么做 → 为什么出现 → 现在怎么用】 1. 早期(固定学习率):整场训练从头到尾用一个数字(如 0.01)。痛点:调参全靠运气,前期慢后期震荡。 2. 中期(阶梯衰减 StepLR / 按盘衰减 ReduceLROnPlateau):训练到第 30/60 轮强行砍半,或验证集 Loss 不下降时除以 10。痛点:超参数多且衰减点生硬。 3. 现代标配(Warmup + 余弦退火 Cosine Annealing): - Warmup(预热):前几百步将 $\eta$ 从 0 线性增加到设定的峰值 $\eta_{max}$。因为初始权重不稳定、Adam 的一阶二阶矩估计还不准,需要小步缓冲。 - Cosine 退火:随后沿着余弦曲线平滑衰减到近乎为 0(如 $\eta_{max} \times 0.01$),让模型平稳落入平坦谷底。
【与相近概念的区别】 - 学习率 vs 优化器(Optimizer, 如 AdamW/SGD):优化器决定梯度的方向和相对各参数的自适应缩放;学习率决定全局更新的基础步长标量。 - 学习率 vs Batch Size:通常 Batch Size 扩大 $k$ 倍,单步梯度的方差减小,学习率也要相应线性或平方根放大(Linear Scaling Rule: $LR \propto \text{BatchSize}$)。 - 调度器 vs 早停(Early Stopping):调度器负责改变步长以辅助收敛;早停是监控验证集指标在适当时机终止训练。
【当前局限与未来作用】 - 当前事实局限:调度器的超参(峰值 LR、Warmup 步数、衰减终点)依然高度依赖人工经验或网格搜索;不同任务(如声纹提取 vs 视频时序分割)的最优 LR 差异很大。 - 未来推测:基于损失景观(Loss Landscape)曲率自动调整步长的二阶/无超参优化调度算法(如类似 D-Adaptation/Prodigy 的免调参路线)可能会进一步普及。
【推荐学习路径】 - 学习底层推导推荐查看 Dive into Deep Learning:先看直觉和公式,再运行章节中的代码加深理解。 - 学习 API 调用推荐查看 PyTorch Tutorials:对照官方示例掌握 `torch.optim.lr_scheduler` 的标准写法。
- 为什么在微调预训练音频模型(如 Conformer/HuBERT)时,初始学习率通常要比从头训练小 1~2 个数量级?
- 余弦退火(Cosine Annealing)相比固定步长衰减(StepLR),为什么更容易收敛到更平坦的极小值点?
- 在 PyTorch 中,如果把 `scheduler.step()` 写在 `optimizer.step()` 之前,会发生什么警告或隐患?