0


图解Pytorch学习率衰减策略(一)

写在前面

  1. 在深度学习中,学习率是一个非常重要的超参数,它控制了模型在每次权重更新时的步长。学习率衰减策略是指在训练过程中逐步减少学习率,从而使得模型更稳定地收敛到最优解。以下是几种常见的学习率衰减方法,以及它们的使用场景和具体实现。

一、LinearLR

  1. 线性地调整学习率。它会根据设定的初始学习率、结束学习率和训练轮数,从初始学习率逐步线性地过渡到结束学习率。这个调度器通常用于训练开始时的学习率调整,帮助模型更稳定地收敛。

示例:

  1. import torch
  2. import matplotlib.pyplot as plt
  3. # 假设模型和优化器
  4. model = torch.nn.Linear(10, 1)
  5. optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
  6. # 设置线性学习率调度器
  7. scheduler = torch.optim.lr_scheduler.LinearLR(optimizer, start_factor=1.0, end_factor=0.1, total_iters=20)
  8. # 记录学习率
  9. lrs = []
  10. for epoch in range(20):
  11. # 模拟一次训练步骤
  12. optimizer.zero_grad()
  13. output = model(torch.randn(10))
  14. loss = output.sum()
  15. loss.backward()
  16. optimizer.step()
  17. # 更新学习率
  18. scheduler.step()
  19. # 打印和记录学习率
  20. lr = scheduler.get_last_lr()[0]
  21. print(f'Epoch {epoch + 1}: Learning Rate = {lr}')
  22. lrs.append(lr)
  23. # 绘制学习率曲线
  24. plt.plot(range(1, 21), lrs, marker='o')
  25. plt.xlabel('Epoch')
  26. plt.ylabel('Learning Rate')
  27. plt.title('Learning Rate Schedule')
  28. plt.grid(True)
  29. plt.show()

参数:

  1. start_factor: 学习率的初始缩放因子,通常是相对于初始学习率的比例。例如,如果start_factor1.0,学习率将保持为优化器初始学习率。
  2. end_factor: 学习率的最终缩放因子,表示训练结束时学习率的比例。例如,如果end_factor0.1,最终的学习率将是初始学习率的10%。
  3. total_iters: 迭代的总次数,即从start_factor过渡到end_factor的周期数。在这里,我们设置为20次迭代。

学习率变化曲线:

使用场景:

  1. 很通用的方法,能适应各种任务,但大多用在简单模型。

推荐程度:推荐,简单模型可以用。

二、StepLR

  1. 一种简单且常用的分段衰减策略,适用于大多数模型和任务。它通过在预设的步数后按固定比例衰减学习率,帮助模型在训练的不同阶段调整优化速度。

示例:

  1. import torch
  2. import torch.optim as optim
  3. from torch.optim.lr_scheduler import StepLR
  4. import matplotlib.pyplot as plt
  5. # 创建一个简单的模型
  6. class SimpleModel(torch.nn.Module):
  7. def __init__(self):
  8. super(SimpleModel, self).__init__()
  9. self.fc = torch.nn.Linear(10, 1)
  10. def forward(self, x):
  11. return self.fc(x)
  12. # 初始化模型、优化器和学习率调度器
  13. model = SimpleModel()
  14. optimizer = optim.SGD(model.parameters(), lr=0.01) # 初始学习率为 0.01
  15. # StepLR 学习率调度器
  16. scheduler = StepLR(optimizer, step_size=2, gamma=0.9) # 每 2 个 epoch 将学习率衰减 0.1
  17. # 模拟一个训练过程
  18. num_epochs = 20
  19. num_batches = 10 # 每轮训练的批次数
  20. lr_history = []
  21. for epoch in range(num_epochs):
  22. print(f"\nEpoch {epoch + 1}/{num_epochs}")
  23. for batch in range(num_batches):
  24. # 模拟前向传递
  25. inputs = torch.randn(64, 10) # 批次大小 64,特征维度 10
  26. targets = torch.randn(64, 1)
  27. outputs = model(inputs)
  28. loss = torch.nn.functional.mse_loss(outputs, targets)
  29. # 反向传播和优化
  30. optimizer.zero_grad()
  31. loss.backward()
  32. optimizer.step()
  33. # 更新学习率
  34. scheduler.step()
  35. # 打印每轮的学习率
  36. current_lr = optimizer.param_groups[0]['lr']
  37. lr_history.append(current_lr)
  38. print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")
  39. # 绘制学习率曲线
  40. plt.figure(figsize=(10, 6))
  41. plt.plot(range(num_epochs), lr_history, marker='o')
  42. plt.xlabel('Epoch')
  43. plt.ylabel('Learning Rate')
  44. plt.title('Learning Rate Schedule')
  45. plt.grid(True)
  46. plt.show()

参数:

  1. step_size: 每隔多少个 epoch 衰减一次学习率。
  2. gamma: 衰减系数,通常小于1

学习率变化曲线:

使用场景:

** **适用于需要在训练过程中定期调整学习率的情况,尤其是在训练初期用较大的学习率快速收敛,后期减小学习率以细化优化的场景。在经典的卷积神经网络(CNN),如 ResNet、VGG 等,尤其在图像分类等任务中表现稳定。

推荐程度:推荐,原理简单、效果稳定。

三、MultiStepLR

  1. 类似于 StepLR,但允许在不同 epoch 设置不同的学习率衰减点,提供更精细的控制。

示例:

  1. import torch
  2. import torch.optim as optim
  3. import torch.nn as nn
  4. import matplotlib.pyplot as plt
  5. # 定义一个简单的模型
  6. model = nn.Linear(10, 2)
  7. # 定义优化器
  8. optimizer = optim.SGD(model.parameters(), lr=0.1)
  9. # 定义 MultiStepLR 学习率调度器
  10. scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=[10, 20, 30], gamma=0.1)
  11. # 训练循环
  12. num_epochs = 35
  13. lr_history = []
  14. for epoch in range(num_epochs):
  15. # 模拟一个训练步骤
  16. optimizer.zero_grad()
  17. outputs = model(torch.randn(5, 10))
  18. loss = outputs.sum()
  19. loss.backward()
  20. optimizer.step()
  21. # 打印当前学习率
  22. current_lr = optimizer.param_groups[0]['lr']
  23. lr_history.append(current_lr)
  24. print(f"Epoch {epoch + 1}, Learning Rate: {current_lr:.6f}")
  25. # 调度器更新学习率
  26. scheduler.step()
  27. # 绘制学习率曲线
  28. plt.figure(figsize=(10, 6))
  29. plt.plot(range(num_epochs), lr_history, marker='o')
  30. plt.xlabel('Epoch')
  31. plt.ylabel('Learning Rate')
  32. plt.title('Learning Rate Schedule')
  33. plt.grid(True)
  34. plt.show()

参数:
milestones: 一个包含多个 epoch 的列表,在这些 epoch 时学习率会乘以 gamma。
gamma: 学习率衰减因子。

学习率变化曲线:

使用场景:
适用于需要在训练中进行多次学习率调整的任务,例如warmup训练或者某些特定数据集。

推荐程度:推荐,不过得把握好衰减点。

四、ExponentialLR

  1. ExponentialLR 的**每个 epoch **将学习率按固定的指数衰减因子 gamma 进行调整。相比于 StepLR,它的衰减更平滑,适合需要持续减小学习率的任务。

示例:

  1. import torch
  2. import torch.optim as optim
  3. from torch.optim.lr_scheduler import ExponentialLR
  4. import matplotlib.pyplot as plt
  5. # 创建一个简单的模型
  6. class SimpleModel(torch.nn.Module):
  7. def __init__(self):
  8. super(SimpleModel, self).__init__()
  9. self.fc = torch.nn.Linear(10, 1)
  10. def forward(self, x):
  11. return self.fc(x)
  12. # 初始化模型、优化器和学习率调度器
  13. model = SimpleModel()
  14. optimizer = optim.SGD(model.parameters(), lr=0.1) # 初始学习率为 0.1
  15. # ExponentialLR 学习率调度器
  16. scheduler = ExponentialLR(optimizer, gamma=0.5) # 学习率衰减因子 gamma = 0.5
  17. # 模拟一个训练过程
  18. num_epochs = 10
  19. num_batches = 10 # 每轮训练的批次数
  20. lr_history = []
  21. for epoch in range(num_epochs):
  22. print(f"\nEpoch {epoch + 1}/{num_epochs}")
  23. for batch in range(num_batches):
  24. # 模拟前向传递
  25. inputs = torch.randn(64, 10) # 批次大小 64,特征维度 10
  26. targets = torch.randn(64, 1)
  27. outputs = model(inputs)
  28. loss = torch.nn.functional.mse_loss(outputs, targets)
  29. # 反向传播和优化
  30. optimizer.zero_grad()
  31. loss.backward()
  32. optimizer.step()
  33. # 更新学习率
  34. scheduler.step()
  35. # 打印每轮的学习率
  36. current_lr = optimizer.param_groups[0]['lr']
  37. lr_history.append(current_lr)
  38. print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")
  39. # 绘制学习率曲线
  40. plt.figure(figsize=(10, 6))
  41. plt.plot(range(num_epochs), lr_history, marker='o')
  42. plt.xlabel('Epoch')
  43. plt.ylabel('Learning Rate')
  44. plt.title('Learning Rate Schedule')
  45. plt.grid(True)
  46. plt.show()

参数:
gamma: 衰减系数,表示每个 epoch 后学习率乘以的因子。

学习率变化曲线:

使用场景:
常用于循环神经网络(RNN)及其变种(如 LSTM、GRU)。适合没有固定的衰减周期的训练过程。适合处理文本序列或时间序列数据。
推荐程度:推荐,比StepLR更平滑。

五、CosineAnnealingLR

  1. CosineAnnealingLR 利用余弦函数的特点,使学习率在训练过程中按照一个周期性变化的余弦曲线来衰减,即学习率从大到小再到大反复变化。通常用于长时间训练任务,能在训练后期有效避免学习率过快下降。

示例:

  1. import torch
  2. import torch.optim as optim
  3. import matplotlib.pyplot as plt
  4. # 模拟模型和优化器
  5. model = torch.nn.Linear(10, 1)
  6. optimizer = optim.SGD(model.parameters(), lr=0.1)
  7. # 初始化CosineAnnealingLR调度器
  8. scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)
  9. # 存储学习率
  10. lrs = []
  11. # 进行训练
  12. for epoch in range(80):
  13. # 模拟训练步骤
  14. optimizer.step()
  15. scheduler.step()
  16. # 获取当前学习率
  17. current_lr = optimizer.param_groups[0]['lr']
  18. lrs.append(current_lr)
  19. # 打印学习率
  20. print(f'Epoch {epoch + 1}: Learning Rate = {current_lr}')
  21. # 绘制学习率曲线
  22. plt.plot(range(1, 81), lrs, marker='o')
  23. plt.xlabel('Epoch')
  24. plt.ylabel('Learning Rate')
  25. plt.title('Learning Rate Schedule with CosineAnnealingLR')
  26. plt.grid(True)
  27. plt.show()

参数:
T_max: 一个周期内的最大 epoch 数。
eta_min: 最小学习率。

学习率变化曲线:

使用场景:
适用于训练需要长时间进行的大型模型,如 Transformer 模型(BERT, GPT)和计算机视觉任务中的大型 CNN。在图像分类任务中效果显著。

推荐程度:非常推荐,使用的很广泛。

六、ReduceLROnPlateau

  1. ReduceLROnPlateau 是基于验证集表现来调整学习率的一种方法。当模型的验证集指标(如损失)在一段时间内没有改善时,学习率会自动减小。

示例:

  1. import torch
  2. import torch.optim as optim
  3. from torch.optim.lr_scheduler import ReduceLROnPlateau
  4. import matplotlib.pyplot as plt
  5. # 创建一个简单的模型
  6. class SimpleModel(torch.nn.Module):
  7. def __init__(self):
  8. super(SimpleModel, self).__init__()
  9. self.fc = torch.nn.Linear(10, 1)
  10. def forward(self, x):
  11. return self.fc(x)
  12. # 初始化模型、优化器和学习率调度器
  13. model = SimpleModel()
  14. optimizer = optim.SGD(model.parameters(), lr=0.01) # 初始学习率为 0.01
  15. # ReduceLROnPlateau 学习率调度器(基于验证准确度)
  16. scheduler = ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=2, verbose=True)
  17. # ReduceLROnPlateau 学习率调度器(基于验证损失)
  18. # scheduler_loss = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=2, verbose=True)
  19. # 模拟一个训练过程
  20. num_epochs = 20
  21. num_batches = 10 # 每轮训练的批次数
  22. lr_history = []
  23. for epoch in range(num_epochs):
  24. print(f"\nEpoch {epoch + 1}/{num_epochs}")
  25. # 模拟训练阶段
  26. model.train()
  27. for batch in range(num_batches):
  28. # 模拟前向传递
  29. inputs = torch.randn(64, 10) # 批次大小 64,特征维度 10
  30. targets = torch.randn(64, 1)
  31. outputs = model(inputs)
  32. loss = torch.nn.functional.mse_loss(outputs, targets)
  33. # 反向传播和优化
  34. optimizer.zero_grad()
  35. loss.backward()
  36. optimizer.step()
  37. # 模拟验证阶段
  38. model.eval()
  39. with torch.no_grad():
  40. val_inputs = torch.randn(64, 10) # 验证集的批次
  41. val_targets = torch.randn(64, 1)
  42. val_outputs = model(val_inputs)
  43. val_loss = torch.nn.functional.mse_loss(val_outputs, val_targets)
  44. # 计算准确度
  45. val_predictions = torch.round(val_outputs)
  46. accuracy = (val_predictions == val_targets).float().mean().item()
  47. # 更新学习率调度器(基于验证准确度)
  48. scheduler.step(accuracy)
  49. # 更新学习率调度器(基于验证损失)
  50. # scheduler.step(val_loss)
  51. # 打印每轮的学习率
  52. current_lr = optimizer.param_groups[0]['lr']
  53. lr_history.append(current_lr)
  54. print(f"End of Epoch {epoch + 1}: Current Learning Rate (based on accuracy): {current_lr:.6f}")
  55. # 绘制学习率曲线
  56. plt.figure(figsize=(10, 6))
  57. plt.plot(range(num_epochs), lr_history, marker='o')
  58. plt.xlabel('Epoch')
  59. plt.ylabel('Learning Rate')
  60. plt.title('Learning Rate Schedule')
  61. plt.grid(True)
  62. plt.show()

参数:
mode: ‘min’ 或 ‘max’,分别表示目标是最小化或最大化某个指标。
factor: 学习率的衰减因子。
patience: 当指定 epoch 数内指标未改善时,才进行学习率衰减。

学习率变化曲线:

使用场景:
适合在训练过程中可能遇到瓶颈的任务,如复杂的时间序列预测、GAN 训练,以及需要动态调整学习率的场景。

推荐程度:推荐,能根据模型表现自动调整学习率。

七、OneCycleLR

  1. 根据 "1cycle" 策略,先逐步增加学习率,然后在训练的后期快速减小学习率,这种方式能在训练初期提供更快的收敛速度,同时在后期细化模型。

示例:

  1. import torch
  2. import torch.optim as optim
  3. from torch.optim.lr_scheduler import OneCycleLR
  4. import matplotlib.pyplot as plt
  5. # 创建一个简单的模型
  6. class SimpleModel(torch.nn.Module):
  7. def __init__(self):
  8. super(SimpleModel, self).__init__()
  9. self.fc = torch.nn.Linear(10, 1)
  10. def forward(self, x):
  11. return self.fc(x)
  12. # 初始化模型、优化器和学习率调度器
  13. model = SimpleModel()
  14. initial_lr = 0.1
  15. optimizer = optim.SGD(model.parameters(), lr=initial_lr) # 初始学习率为 0.1
  16. # OneCycleLR 学习率调度器
  17. num_epochs = 20
  18. num_batches = 10 # 每轮训练的批次数
  19. max_lr = 0.1 # 最大学习率
  20. scheduler = OneCycleLR(optimizer, max_lr=max_lr, steps_per_epoch=1, epochs=num_epochs)
  21. # 存储学习率的历史
  22. lr_history = []
  23. # 模拟一个训练过程
  24. for epoch in range(num_epochs):
  25. print(f"\nEpoch {epoch + 1}/{num_epochs}")
  26. for batch in range(num_batches):
  27. # 模拟前向传递
  28. inputs = torch.randn(64, 10) # 批次大小 64,特征维度 10
  29. targets = torch.randn(64, 1)
  30. outputs = model(inputs)
  31. loss = torch.nn.functional.mse_loss(outputs, targets)
  32. # 反向传播和优化
  33. optimizer.zero_grad()
  34. loss.backward()
  35. optimizer.step()
  36. # 更新学习率
  37. scheduler.step()
  38. # 记录学习率
  39. current_lr = optimizer.param_groups[0]['lr']
  40. lr_history.append(current_lr)
  41. print(f"End of Epoch {epoch + 1}: Current Learning Rate: {current_lr:.6f}")
  42. # 绘制学习率曲线
  43. plt.figure(figsize=(20, 6))
  44. plt.plot(lr_history, marker='o')
  45. plt.xlabel('Iteration')
  46. plt.ylabel('Learning Rate')
  47. plt.title('Learning Rate Schedule with OneCycleLR')
  48. plt.grid(True)
  49. plt.show()

参数:

  1. max_lr (float or list): 每个参数组在周期内的最高学习率。
  2. total_steps (int): 循环的总步数。注意,如果这里是None,那么必须通过提供epochsstep_per_epoch的值来推断它。
  3. steps_per_epoch (int): 每个epoch要训练的步数。如果total_stepsNone,则与epoch一起用来推断循环中的总步数。
  4. epochs:需要训练多少个时代。

学习率变化曲线:

使用场景:
适合从头开始训练的大型模型,尤其是 ResNet、Transformer 等,需要高效训练的情况下。

推荐程度:推荐,能平衡训练的前期和后期需求。

  1. 第一部分先介绍到这里,关注不迷路(*^▽^*)
  2. 第二部分链接:https://blog.csdn.net/xian0710830114/article/details/141096768

关注订阅号了解更多精品文章

交流探讨、商务合作请加微信


本文转载自: https://blog.csdn.net/xian0710830114/article/details/141075091
版权归原作者 小殊小殊 所有, 如有侵权,请联系我们删除。

“图解Pytorch学习率衰减策略(一)”的评论:

还没有评论