目录
-
- 一、前言
- 二、Pytorch中自动调整学习率的几种方式
-
- 2.1 ExponentialLR-指数衰减方式
- 2.2 ExponentialLR方式对网络训练的影响
- 2.3 MultiStepLR-按给定间隔调整学习率
- 2.4 MultiStepLR调整学习率对网络训练的影响
- 2.5 -CosineAnnealingLR-余弦周期调整学习率
- 2.6 CosineAnnealingLR调整学习率对网络训练的影响
- 2.7 -ReduceLRonPlateau-监控某种特定的指标(如,校验损失)
- 2.8 ReduceLRonPlateau调整学习率对网络训练的影响
- 2.9 LambdaLR-自定义函数调整学习率
- 2.10 LambdaLR学习率调整结果展示
- 2.11 StepLR学习率调整结果展示
- 2.12 StepLR学习率调整结果展示
- 三、参考链接
一、前言
学习率要在收敛和收敛速度中做出权衡,合适的学习率能以最快速度逼近最优解同时使得损失不断下降。在复杂网络中,固定的学习率一般无法得到网络的最优解,动态调整学习率或对模型不同部分设置不同的学习率已成为一种训练模型的趋势趋势。
二、Pytorch中自动调整学习率的几种方式
2.1 ExponentialLR-指数衰减方式
torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma,last_epoch=-1)
其中,optimizer为指定的优化器, γ \gamma γ为指数的底数,通常将 γ \gamma γ设置为接近于1的数。
学习率更新公式如下所示:
l r n e w = l r i n i t ∗ γ e p o c h lr_{new}=lr_{init}*\gamma^{epoch} lrnew=lrinit∗γepoch 其中, l r i n i t lr_{init} lrinit为初始学习率, l r n e w lr_new lrnew为更新后的学习率, e p o c h epoch epoch为当前训练迭代次数。
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torch.optim.lr_scheduler import ExponentialLR
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
plt.rcParams['font.sans-serif'] = 'SimHei' # 显示中文
plt.rcParams['axes.unicode_minus'] = False # 显示负号
SEED = 40 # 设置随机种子,使得每次运行时产生的随机数一致
# 构建网络
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.linear = nn.Linear(50, 100)
self.leakrelu = nn.LeakyReLU(0.001)
self.linear1 = nn.Linear(100, 50)
# 前向传播
def forward(self, input):
x = self.leakrelu(self.linear(input))
output = self.leakrelu(self.linear1(x))
return output
lr = [] # 保存每个epoch的学习率
epochTrainLoss = [] # 保存每个epoch的训练损失
epochValLoss = [] # 保存每个epoch的校验损失
maxepoch = 50
torch.manual_seed(SEED)
if torch.cuda.is_available():
torch.cuda.manual_seed(SEED)
# 产生训练所需数据
input_train = torch.randn(10, 50) # 训练输入数据
target_train = torch.randn(10, 50) # 训练标签
input_val = torch.randn(10, 50) # 校验输入数据
target_val = torch.randn(10, 50) # 校验所用标签
net = Net() # 初始化网络
optimizer = torch.optim.Adam(net.parameters(), lr=0.01) # 初始化优化器-Adam
scheduler = ExponentialLR(optimizer, gamma=0.9) # 以指数方式调整学习率
loss_fn = torch.nn.MSELoss() # 初始化损失函数
loss_fn.to(DEVICE)
# 训练模型
for epoch in range(maxepoch):
lr.append(scheduler.get_last_lr()[0])
print(epoch, scheduler.get_last_lr()[0])
# 将训和校验数据和模型加载到device中
net = net.to(DEVICE)
input_train = input_train.to(DEVICE)
target_train = target_train.to(DEVICE)
input_val = input_val.to(DEVICE)
target_val = target_val.to(DEVICE)
net.train() # 进入训练模式
net.zero_grad() # 将上一次训练保存的梯度清零
output = net(input_train) # 将输入数据输入到模型中
trainLoss = loss_fn(output, target_train) # 计算训练损失
trainLoss.backward() # 反向传播
epochTrainLoss.append(trainLoss.cpu().detach().numpy())
optimizer.step() # 更新模型参数
scheduler.step() # 更新学习率
net.eval() # 进入测试模式
with torch.no_grad(): # 不考虑梯度
output_val = net(input_val)
valLoss = loss_fn(output_val, target_val) # 校验损失
epochValLoss.append(valLoss.cpu().detach().numpy())
print("epoch = %02d trainLoss = %.4f valLoss = %.4f" % (epoch, trainLoss, valLoss))
# 绘制学习率变化曲线图
plt.figure()
x = list(range(maxepoch))
plt.plot(x, lr)
plt.xlabel('epochs')
plt.ylabel('lr')
plt.show()
# 绘制损失曲线图
plt.figure()
plt.plot(x, epochTrainLoss)
plt.plot(x, epochValLoss)
plt.legend(['trainLoss','valLoss'])
plt.xlabel('epochs')
plt.ylabel('Loss')
plt.show()
2.2 ExponentialLR方式对网络训练的影响
(1) 学习率按照ExponentialLR方式衰减,初始参数如下所示:
1) 初始学习率 l r i n i t = 0.1 lr_{init}=0.1 lrinit=0.1
2) ExponentialLR参数 γ = 0.9 \gamma=0.9 γ=0.9
(2) 学习率为固定常数
1) 初始学习率 l r i n i t = 0.01 lr_{init}=0.01 lrinit=0.01
2) ExponentialLR参数 γ = 1 \gamma=1 γ=1
2.3 MultiStepLR-按给定间隔调整学习率
torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones,gamma,last_epoch=-1)
其中,optimizer为指定的优化器,milestones为指定衰减区间, γ \gamma γ为指数的底数,通常将 γ \gamma γ设置为接近于1的数。当 m i l e s t o n e s = [ x 1 , x 2 ] milestones=[x_{1}, x_{2}] milestones=[x1,

本文详细介绍了PyTorch中动态调整学习率的多种策略,包括指数衰减(ExponentialLR)、多步调整(MultiStepLR)、余弦周期调整(CosineAnnealingLR)和监控指标调整(ReduceLRonPlateau)。通过实例展示了这些策略如何影响网络训练过程,如学习率变化曲线和损失曲线。同时,文章还提到了自定义函数调整学习率(LambdaLR)的方法及其效果。
最低0.47元/天 解锁文章
8803

被折叠的 条评论
为什么被折叠?



