- 在
python
中进行机器学习和深度学习时,学习率(Learning Rate)
是一个至关重要的超参数。它控制着模型在每次迭代(或更新)中,根据损失函数的梯度
来调整模型参数(如权重和偏置)的梯度,简单来说,学习率决定模型“学习”的速度和步长。
重要性
学习率的重要性
理解学习率的重要性,可以将其类比为下山的过程:
-
学习率过大(步子迈太大):
- 风险:模型可能会在损失函数曲面的最低点(最优解)附近拉回震荡,甚至超过最低点,导致模型无法收敛或收敛到次优解
- 表现:训练过程中损失值剧烈波动,甚至不降反升,模型性能不稳定
-
学习率过小(步子迈太小):
- 风险:模型更新参数的速度非常慢,导致训练过程极其漫长,可能需要很长时间才能收敛。更糟糕的是,模型可能会陷入局部最优解,无法找到全局最优解
- 表现:训练损失下降缓慢,模型收敛速度慢
-
选择一个合适的学习率是平衡模型收敛速度的收敛质量的关键
工作原理
学习率的工作原理
- 在大多数优化算法中(如梯度下降,随机梯度下降
SGD
,Adam
,RMSprop
等),模型参数的更新公式通常包含学习率:
新参数 = 旧参数 − 学习率 ∗ 损失函数梯度 新参数=旧参数-学习率*损失函数梯度 新参数=旧参数−学习率∗损失函数梯度 - 其中,损失函数梯度指示了损失函数下降最快的方向,学习率则决定了我们在这个方向上前进的
步长
如何设置与调整
- 在
python
当中,我们使用主流的机器学习和深度学习库(如TensorFlow、Pytorch、Scikit-learn
等)时,学习率通常作为优化器的参数进行设置
初始学习率设置
- 最简单的方式是设置一个固定的学习率
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的模型
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.linear = nn.Linear(10, 1)
def forward(self, x):
return self.linear(x)
model = SimpleModel()
# 定义损失函数和优化器
criterion = nn.MSELoss()
# 设置一个固定的学习率,例如 0.01
learning_rate = 0.01
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
# 训练循环(简化)
# for epoch in range(num_epochs):
# for inputs, targets in dataloader:
# optimizer.zero_grad() # 梯度清零
# outputs = model(inputs)
# loss = criterion(outputs, targets)
# loss.backward() # 反向传播,计算梯度
# optimizer.step() # 更新参数
学习率调度器(Learning Rate Schedulers/Decay
)
在实际训练当中,固定学习率往往不是最优选择,通常的做法是,在训练初期使用较大的学习率以较快的速度接近最优解,然后在训练后期逐渐减小学习率,以便更精细地调整参数,避免震荡并帮助模型更好收敛,这被称为
学习率调度(Learning Rate ScheDuling)
或学习率衰减(Learning Rate Decay)
常用的学习率调度策略
Step Decay(步长衰减)
:每隔一定数量的epoch
或迭代,学习率乘以一个衰减因子Exponential Decay(指数衰减)
:学习率以指数方式衰减
l r = l r 0 ∗ d e c a y r a t e e p o c h / d e c a y s t e p s l_r = l_{r0}*decay_{rate}^{epoch/decay_steps} lr=lr0∗decayrateepoch/decaystepsCosine Annealing(余弦退火)
:学习率按照余弦函数周期性变化,通常从一个最大值平滑下降到最小值ReduceLROnPlateau(基于验证指标的衰减)
:当监控的指标(如验证损失)在一定数量的epoch
内没有改善时,学习率下降
import torch.optim.lr_scheduler as lr_scheduler
# ... (模型、损失函数、优化器定义同上) ...
# 步长衰减示例:每10个epoch,学习率乘以0.1
scheduler = lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
# 余弦退火示例
# scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=num_epochs)
# ReduceLROnPlateau 示例
# scheduler = lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5)
# 训练循环
# for epoch in range(num_epochs):
# # ... 训练代码 ...
# # 在每个 epoch 结束后调用 scheduler.step()
# scheduler.step()
# # 如果是 ReduceLROnPlateau,需要传入监控指标
# # scheduler.step(val_loss)