news 2026/4/16 3:16:35

学习率调度(Learning Rate Scheduling)策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
学习率调度(Learning Rate Scheduling)策略

概念

 学习率调度(Learning Rate Scheduling)是指在模型训练过程中动态调整优化器的学习率,以平衡收敛速度与稳定性,从而提升模型性能。固定学习率往往难以兼顾训练初期的快速下降和后期的精细收敛,而学习率调度策略通过在不同训练阶段智能地增减学习率,帮助模型更高效、更稳定地找到最优解。

常见的调度策略包括:Step Decay(每隔固定轮数衰减学习率)、Exponential Decay(指数衰减)、Cosine Annealing(余弦退火,平滑降至零)、Warmup(训练初期线性或非线性地从小学习率升温)、以及组合策略如 Warmup + Cosine Decay(广泛用于Transformer等大模型)。此外,还有自适应调度方法如 ReduceLROnPlateau(当验证损失停滞时降低学习率)和带重启的 SGDR(Stochastic Gradient Descent with Restarts)。这些策略可根据任务、模型结构和数据规模灵活选用。

这里只介绍最常用的,Warmup + 余弦退火(Cosine Annealing with Warmup),适合于Transformer 系列模型(如 BERT、ViT、LLaMA)、ResNet 等。

Warmup

Warmup(学习率预热) 是一种在训练初期逐步增大学习率的调度策略,通常从一个很小的值(甚至0)线性增长到设定的初始学习率。其主要作用是缓解训练初期因参数随机初始化和优化器状态不稳定(如 Adam 的动量估计偏差)导致的梯度震荡或发散问题,尤其在使用大批次(large batch size)或 Transformer 类模型时效果显著。

示例:

def adjust_learning_rate(optimizer, base_lr, max_iters, cur_iters, warmup_iter=None, power=0.9): if warmup_iter is not None and cur_iters < warmup_iter: warmup_ratio = 0.1 # 从 base_lr 的 10% 开始 lr = base_lr * (warmup_ratio + (1 - warmup_ratio) * cur_iters / max(1, warmup_iter - 1)) else: lr = base_lr * ((1 - float(cur_iters - warmup_iter) / (max_iters - warmup_iter)) ** power) for param_group in optimizer.param_groups: param_group['lr'] = lr return lr

我这里并没有使用scheduler.step()之类的操作,而是通过语句param_group['lr'] = lr # ← 直接赋值!直接修改 optimizer.param_groups 中的 'lr' 字段。

如果使用的是 torch.optim.lr_scheduler 中的调度器(比如 StepLR, CosineAnnealingWarmRestarts, LambdaLR 等),它们已经内置了 .step() 方法,只需在训练循环中调用它,学习率就会自动更新。

在train()函数中:

optimizer.zero_grad() loss.backward() if args.grad_clip > 0: torch.nn.utils.clip_grad_norm_(model.parameters(), args.grad_clip) optimizer.step() # 学习率调度 total_iters = args.epochs * len(train_loader) warmup_iters = args.warmup_epochs * len(train_loader) cur_iter = (epoch - 1) * len(train_loader) + step current_lr = adjust_learning_rate(optimizer, args.lr_rate, total_iters, cur_iter, warmup_iters, power=0.9)

前 warmup_iter 步:学习率从 0.1 * base_lr 线性增长到 base_lr;

之后:使用多项式衰减(Polynomial Decay),指数为 power=0.9(即 "poly" 调度)。

余弦退火(Cosine Annealing)

余弦退火是一种学习率调度策略,它让学习率按照余弦函数从初始值平滑地衰减到一个最小值(如 eta_min)。

其核心思想是:在训练初期使用较大学习率快速收敛,在后期使用较小学习率精细调整模型参数。而 CosineAnnealingWarmRestarts 是其增强版本——每当学习率衰减到最低点时,“重启” 学习率回到初始值,重新开始新一轮余弦衰减,形成周期性探索与收敛的机制。这种方式有助于跳出局部最优,提升模型泛化能力。

示例:

import torch import torch.nn as nn import torch.optim as optim from torch.optim.lr_scheduler import CosineAnnealingLR import matplotlib.pyplot as plt # 1. 构造一个简单模型 model = nn.Linear(10, 1) # 2. 优化器(初始学习率 = 0.1) optimizer = optim.SGD(model.parameters(), lr=0.1) # 3. 余弦退火调度器:周期 T_max = 50 个 epoch,最小学习率 eta_min = 0 scheduler = CosineAnnealingLR(optimizer, T_max=50, eta_min=0.0) # 4. 记录学习率变化 lrs = [] # 5. 模拟训练过程(100 个 epoch) for epoch in range(100): # 假装做了一次训练(这里省略 forward/backward) # 更新学习率(每个 epoch 结束后调用) scheduler.step() # 记录当前学习率 current_lr = scheduler.get_last_lr()[0] lrs.append(current_lr) if epoch % 10 == 0: print(f"Epoch {epoch:3d} | LR: {current_lr:.6f}") # 6. 可视化学习率变化 plt.figure(figsize=(8, 4)) plt.plot(lrs) plt.title("Cosine Annealing Learning Rate") plt.xlabel("Epoch") plt.ylabel("Learning Rate") plt.grid(True) plt.show()

组合使用示例

import torch import torch.nn as nn import torch.optim as optim from torch.optim.lr_scheduler import LambdaLR, CosineAnnealingLR import matplotlib.pyplot as plt # 超参数 total_epochs = 100 warmup_epochs = 10 initial_lr = 1e-3 eta_min = 1e-6 # 模拟模型和优化器 model = nn.Linear(10, 1) optimizer = optim.Adam(model.parameters(), lr=initial_lr) # 第一阶段:Warmup(线性增长) def warmup_lambda(epoch): if epoch < warmup_epochs: return float(epoch + 1) / float(warmup_epochs) else: return 1.0 warmup_scheduler = LambdaLR(optimizer, lr_lambda=warmup_lambda) # 第二阶段:余弦退火(从 warmup 结束后开始) # 注意:CosineAnnealingLR 的 T_max 是从它开始算起的周期长度 cosine_scheduler = CosineAnnealingLR( optimizer, T_max=total_epochs - warmup_epochs, eta_min=eta_min ) # 记录学习率变化 lrs = [] for epoch in range(total_epochs): if epoch < warmup_epochs: # Warmup 阶段 lr = optimizer.param_groups[0]['lr'] lrs.append(lr) warmup_scheduler.step() else: # 切换到余弦退火(注意:第一次调用时 epoch == warmup_epochs) if epoch == warmup_epochs: # 重置优化器的学习率为 warmup 最终值(避免跳变) # 实际上 LambdaLR 已经设为 initial_lr,所以通常不需要额外操作 pass lr = optimizer.param_groups[0]['lr'] lrs.append(lr) cosine_scheduler.step() # 可视化学习率变化 plt.figure(figsize=(10, 4)) plt.plot(lrs, label='Learning Rate') plt.axvline(x=warmup_epochs - 1, color='r', linestyle='--', label='End of Warmup') plt.title('Warmup + Cosine Annealing Learning Rate Schedule') plt.xlabel('Epoch') plt.ylabel('Learning Rate') plt.legend() plt.grid(True) plt.show()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 18:00:02

【计算机毕业设计案例】基于springboot的企业人事管理系统基于Spring Boot+Vue的人事管理系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/10 15:50:11

Java计算机毕设之基于Spring Boot+Vue的人事管理系统基于springboot的企业人事管理系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/3 8:21:04

【C++STL】容器适配器——stack用法详解

1. 栈的本质&#xff1a;容器适配器 首先理解关键点&#xff1a;C中的stack不是独立的容器&#xff0c;而是“容器适配器”。它不自己管理内存&#xff0c;而是包装一个已有的底层容器&#xff08;默认是deque&#xff09;&#xff0c;为其添加栈的接口&#xff08;LIFO操作&a…

作者头像 李华
网站建设 2026/4/5 12:16:14

电影个性化推荐与分析系统 | Python Django MySQL 协同过滤 Echarts可视化 大数据 人工智能 deepseek 毕业设计源码(建议收藏)✅

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ > &#x1f345;想要获取完整文章或者源码&#xff0c;或者代做&#xff0c;拉到文章底部即可与…

作者头像 李华