深度学习中的学习率调度器(scheduler)分析并作图查看各方法差异
文章目录
- 1. 指数衰减调度器(Exponential Decay Scheduler)
- 工作原理
- 适用场景
- 实现示例
- 2. 余弦退火调度器(Cosine Annealing Scheduler)
- 工作原理
- 适用场景
- 实现示例
- 3. 步长衰减调度器(Step Decay Scheduler)
- 工作原理
- 适用场景
- 实现示例
- 4. 多项式衰减与预热调度器(Polynomial Decay with Warm-up)
- 工作原理
- 适用场景
- 实现示例
- 5. 多步衰减调度器(MultiStep Decay Scheduler)
- 工作原理
- 适用场景
- 实现示例
- 总结
- 参考资料
在深度学习模型训练过程中, 学习率调度器(Learning Rate Scheduler)是优化过程中不可或缺的重要组成部分。它们能够在训练的不同阶段自动调整学习率,从而提高模型的收敛速度和最终性能。选择合适的学习率调度器对于优化训练过程至关重要,不同的调度器适用于不同的训练需求和模型架构。本文将介绍几种常用的学习率调度器,并通过 PyTorch 提供的
torch.optim.lr_scheduler
和
transformers
库中的调度器,展示具体的实现示例及其适用场景。可以通过
运行示例代码来作图查看学习率变化情况
,能帮助大家更好的了解不同方法的区别。
1. 指数衰减调度器(Exponential Decay Scheduler)
工作原理
指数衰减调度器通过在每个训练步骤中以固定的速率减小学习率,从而逐步降低学习率。这种调度器适用于需要平稳且持续减小学习率的训练过程,有助于模型在训练后期稳定收敛。
适用场景
- 稳定收敛:适用于希望学习率在整个训练过程中持续且缓慢降低,以避免训练后期的震荡。
- 简单调整:当训练过程相对稳定,不需要复杂的学习率调整策略时,指数衰减是一个简单有效的选择。
实现示例
import matplotlib.pyplot as plt
import torch
from torch.optim import AdamW
from torch.optim.lr_scheduler import ExponentialLR
# 定义优化器和参数
initial_lr = 5e-5
num_training_steps = 3000
decay_rate = 0.99
params = [torch.nn.Parameter(torch.randn(10, 10)) for _ in range(5)] # 示例模型参数
optimizer = AdamW(params, lr=initial_lr)
# 定义指数衰减调度器
scheduler = ExponentialLR(optimizer, gamma=decay_rate)
# 模拟学习率变化
learning_rates = []
for step in range(num_training_steps):
optimizer.step()
scheduler.step()
current_lr = optimizer.param_groups[0]['lr']
learning_rates.append(current_lr)
# 绘制学习率变化曲线
plt.figure(figsize=(12, 6))
plt.plot(learning_rates, label='Learning Rate')
plt.xlabel('Steps')
plt.ylabel('Learning Rate')
plt.title('Exponential Decay Scheduler')
plt.legend()
plt.grid(True)
plt.show()
2. 余弦退火调度器(Cosine Annealing Scheduler)
工作原理
余弦退火调度器通过余弦函数调整学习率,使其在训练过程中呈现周期性变化。这种调度器特别适用于处理模型训练中的振荡现象,能够在训练末期提供较低的学习率以帮助模型更好地收敛。
适用场景
- 避免局部最优:通过周期性调整学习率,可以帮助模型跳出局部最优解。
- 动态调整:适用于需要在训练过程中动态调整学习率以应对不同训练阶段需求的场景。
- 模型复杂度较高:对于复杂模型,如深层神经网络,余弦退火有助于更好地探索参数空间。
实现示例
import matplotlib.pyplot as plt
import torch
from torch.optim import AdamW
from torch.optim.lr_scheduler import CosineAnnealingLR
# 优化器和参数定义同上
initial_lr = 5e-5
num_training_steps = 3000
T_max = 1000 # 一个周期内的步数
params = [torch.nn.Parameter(torch.randn(10, 10)) for _ in range(5)] # 示例模型参数
optimizer = AdamW(params, lr=initial_lr)
# 定义余弦退火调度器
scheduler = CosineAnnealingLR(optimizer, T_max=T_max)
# 模拟学习率变化
learning_rates = []
for step in range(num_training_steps):
optimizer.step()
scheduler.step()
current_lr = optimizer.param_groups[0]['lr']
learning_rates.append(current_lr)
# 绘制学习率变化曲线
plt.figure(figsize=(12, 6))
plt.plot(learning_rates, label='Learning Rate')
plt.xlabel('Steps')
plt.ylabel('Learning Rate')
plt.title('Cosine Annealing Scheduler')
plt.legend()
plt.grid(True)
plt.show()
3. 步长衰减调度器(Step Decay Scheduler)
工作原理
步长衰减调度器在训练过程中每隔一定的步数(step_size
)后按指定的因子(gamma
)降低学习率。这种调度器适用于需要在训练过程中分阶段减小学习率的场景,有助于模型在不同训练阶段进行有效的学习。
适用场景
- 分阶段训练:适用于需要在训练的特定阶段进行学习率调整的任务,如先快速学习再细致调整。
- 明确的训练阶段:当训练过程可以划分为多个明确的阶段,每个阶段需要不同学习率时,步长衰减是理想选择。
- 资源受限的训练:在有限的训练资源下,通过分阶段调整学习率可以更有效地利用计算资源。
实现示例
import matplotlib.pyplot as plt
import torch
from torch.optim import AdamW
from torch.optim.lr_scheduler import StepLR
# 调度器参数
initial_lr = 5e-5
num_training_steps = 3000
step_size = 500 # 每隔 step_size 个 step,学习率衰减一次
gamma = 0.1 # 衰减因子
params = [torch.nn.Parameter(torch.randn(10, 10)) for _ in range(5)] # 示例模型参数
optimizer = AdamW(params, lr=initial_lr)
# 定义步长衰减调度器
scheduler = StepLR(optimizer, step_size=step_size, gamma=gamma)
# 模拟学习率变化
learning_rates = []
for step in range(num_training_steps):
optimizer.step()
scheduler.step()
current_lr = optimizer.param_groups[0]['lr']
learning_rates.append(current_lr)
# 绘制学习率变化曲线
plt.figure(figsize=(12, 6))
plt.plot(learning_rates, label='Learning Rate')
plt.xlabel('Steps')
plt.ylabel('Learning Rate')
plt.title('Step Decay Scheduler')
plt.legend()
plt.grid(True)
plt.show()
4. 多项式衰减与预热调度器(Polynomial Decay with Warm-up)
工作原理
多项式衰减与预热调度器结合了学习率预热和多项式衰减的优势。训练初期通过预热阶段逐步增加学习率,随后按照多项式函数逐步降低学习率。这种调度器适用于如 BERT 等复杂模型的训练,有助于在训练初期稳定模型参数并在后期促进收敛。
适用场景
- 复杂模型训练:适用于需要在训练初期进行稳定性的复杂模型,如 Transformer、BERT 等。
- 防止初期震荡:通过预热阶段逐步增加学习率,可以防止训练初期由于学习率过高导致的梯度震荡。
- 需要精细控制:适用于需要对学习率进行精细控制,以实现最佳收敛效果的任务。
实现示例
import matplotlib.pyplot as plt
import torch
from torch.optim import AdamW
from transformers import get_polynomial_decay_schedule_with_warmup
# 调度器参数
initial_lr = 5e-5
warmup_steps = 100
num_training_steps = 3000
lr_end = 1e-7 # 最低学习率
power = 2.0 # 多项式衰减的幂次
params = [torch.nn.Parameter(torch.randn(10, 10)) for _ in range(5)] # 示例模型参数
optimizer = AdamW(params, lr=initial_lr)
# 定义多项式衰减与预热调度器
scheduler = get_polynomial_decay_schedule_with_warmup(
optimizer,
num_warmup_steps=warmup_steps,
num_training_steps=num_training_steps,
lr_end=lr_end,
power=power
) # 二次衰减
# 模拟学习率变化
learning_rates = []
for step in range(num_training_steps):
optimizer.step()
scheduler.step()
current_lr = optimizer.param_groups[0]['lr']
learning_rates.append(current_lr)
# 绘制学习率变化曲线
plt.figure(figsize=(12, 6))
plt.plot(learning_rates, label='Learning Rate')
plt.axvline(x=warmup_steps, color='r', linestyle='--', label='End of Warm-up')
plt.xlabel('Steps')
plt.ylabel('Learning Rate')
plt.title('Polynomial Decay Scheduler with Warm-up')
plt.legend()
plt.grid(True)
plt.show()
5. 多步衰减调度器(MultiStep Decay Scheduler)
工作原理
多步衰减调度器在预设的多个步数(milestones
)时刻按指定的因子(gamma
)降低学习率。这种调度器允许在训练过程中在多个关键点调整学习率,适用于需要在多个阶段显著改变学习率的训练任务。
适用场景
- 多阶段训练:适用于训练过程中有多个关键阶段,每个阶段需要不同学习率的任务。
- 灵活调整:当训练过程不规则或需要根据训练进展手动调整学习率时,多步衰减提供了灵活性。
- 特定任务需求:适用于一些特定任务或模型架构,需要在特定步数后调整学习率以优化性能。
实现示例
import matplotlib.pyplot as plt
import torch
from torch.optim import AdamW
from torch.optim.lr_scheduler import MultiStepLR
# 调度器参数
initial_lr = 5e-5
num_training_steps = 3000
milestones = [1000, 2000] # 指定的步数
gamma = 0.1 # 衰减因子
params = [torch.nn.Parameter(torch.randn(10, 10)) for _ in range(5)] # 示例模型参数
optimizer = AdamW(params, lr=initial_lr)
# 定义多步衰减调度器
scheduler = MultiStepLR(optimizer, milestones=milestones, gamma=gamma)
# 模拟学习率变化
learning_rates = []
for step in range(num_training_steps):
optimizer.step()
scheduler.step()
current_lr = optimizer.param_groups[0]['lr']
learning_rates.append(current_lr)
# 绘制学习率变化曲线
plt.figure(figsize=(12, 6))
plt.plot(learning_rates, label='Learning Rate')
for i, milestone in enumerate(milestones):
if i == 0:
plt.axvline(x=milestone, color='r', linestyle='--', label=f'Milestone at Step {milestone}')
else:
plt.axvline(x=milestone, color='r', linestyle='--')
plt.xlabel('Steps')
plt.ylabel('Learning Rate')
plt.title('MultiStep Decay Scheduler')
plt.legend()
plt.grid(True)
plt.show()
注意:在多步衰减调度器的绘图代码中,
plt.axvline
函数仅在第一个里程碑处添加标签,后续的里程碑标签设置为None
或'_nolegend_'
,以避免图例中出现重复的标签。
总结
以上示例代码展示了不同学习率调度器的实现方式以及学习率随训练步骤变化的过程。选择合适的调度器可以根据具体任务和模型的需求来优化训练效果。以下是各类调度器的快速参考:
- 指数衰减调度器(Exponential Decay Scheduler):适用于希望学习率持续且缓慢降低,稳定收敛的训练过程。
- 余弦退火调度器(Cosine Annealing Scheduler):适用于需要动态调整学习率以避免局部最优,尤其适合复杂模型。
- 步长衰减调度器(Step Decay Scheduler):适用于分阶段训练,明确划分训练阶段的任务。
- 多项式衰减与预热调度器(Polynomial Decay with Warm-up):适用于复杂模型训练,防止初期震荡并促进后期收敛。
- 多步衰减调度器(MultiStep Decay Scheduler):适用于多阶段训练,需要在多个关键点调整学习率的任务。
在实际应用中,可以根据模型的复杂度、数据集的特性以及训练的阶段性需求,灵活选择和调整学习率调度策略,以实现最佳的训练效果。
参考资料
- PyTorch 官方文档 - Learning Rate Scheduler
- Transformers 库 - 调度器