Pytorch中神经网络学习率衰减方法

1. 为什么要衰减

学习率(learning rate, lr)代表梯度下降的步长,与传统智能优化算法(比如粒子群算法)类似,如果搜索步长太大有可能会跳出最优区间,如果搜索步长太小,有可能陷于局部最优值。在神经网络刚开始训练的时候,可以将学习率lr设置的大一点(比如0.01),后面随着训练代数的增加将学习率逐步减小,这样平衡了探索和开发的能力。

2. 衰减方法

参考pytorch官方文档
pytorch官方给我们提供了几个衰减函数:torch.optim.lr_scheduler.StepLR(),torch.optim.lr_scheduler.LambdaLR()torch.optim.lr_scheduler.MultiStepLR(),torch.optim.lr_scheduler.ExponentialLR(),torch.optim.lr_scheduler.CosineAnnealingLR()等,这里讲一下几个常用的,其余的请参考官方文档。

2.1 指数衰减torch.optim.lr_scheduler.ExponentialLR()

代码如下:

import matplotlib.pyplot as plt
from torch.optim import Adam, lr_scheduler
from torch import nn
import torch.nn.functional as F

# 随便定义了一个网络
class Net(nn.Module):
    def __init__(self, input_size, output_size, fc_size):
        super(Net, self).__init__()
        self.input_size = input_size
        self.output_size = output_size
        self.fc_size = fc_size
        self.l1 = nn.Linear(input_size, self.fc_size)
        self.l2 = nn.Linear(self.fc_size, output_size)

    def forward(self, x):
        x = x.view(-1, self.input_size)
        x = F.relu(self.l1(x))
        return self.l2(x)

model = Net(3,3,3)  # 给网络随便输入参数

lr_list = []        # 存储每代的学习率
LR = 0.01           # 定义初始学习率
optimizer = Adam(model.parameters(),lr = LR)  # 定义优化器
scheduler = lr_scheduler.ExponentialLR(optimizer,gamma = 0.7)  # 定义学习率控制器

for epoch in range(40):   # 训练40代
	'''这里用来训练网络'''
    optimizer.step()
    scheduler.step()
    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(40),lr_list,color = 'r')   # 绘制出学习率曲线
plt.show()

讲解一下上面的代码:

  • 必须先定义一个优化器,再定义定义学习率控制器绑定lr;
  • scheduler.step()必须在optimizer.step()后执行;
  • lr_scheduler.ExponentialLR(optimizer,gamma = 0.7)表示每个epoch学习率会乘以0.7,也就是会呈指数下降;
  • lr下降曲线如下图所示:
    Pytorch中神经网络学习率衰减方法_第1张图片

2.2 固定步长衰减torch.optim.lr_scheduler.StepLR()

网络结构和导入的库都与前文一致,其余代码如下:


model = Net(3,3,3)  # 给网络随便输入参数

lr_list = []        # 存储每代的学习率
LR = 0.01           # 定义初始学习率
optimizer = Adam(model.parameters(),lr = LR)  # 定义优化器
scheduler = lr_scheduler.StepLR(optimizer,step_size=5,gamma = 0.7)
# scheduler = lr_scheduler.ExponentialLR(optimizer,gamma = 0.7)  # 定义学习率控制器
for epoch in range(40):   # 训练40代
	'''这里用来训练网络'''
    optimizer.step()
    scheduler.step()
    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(40),lr_list,color = 'r')   # 绘制出学习率曲线
plt.show()

讲解一下上述代码:

  • lr_scheduler.StepLR(optimizer,step_size=5,gamma = 0.7)中,step_size=5代表每5个epoch学习率进行一次衰减,衰减维原来长度的gamma倍;
  • lr下降曲线如下图所示:

Pytorch中神经网络学习率衰减方法_第2张图片

2.3 多步长衰减 torch.optim.lr_scheduler.MultiStepLR()

网络结构和导入的库都与2.1一致,其余代码如下:

optimizer = Adam(model.parameters(),lr = LR)  # 定义优化器
scheduler = lr_scheduler.MultiStepLR(optimizer,
                    milestones=[20, 30, 32, 40, 50], gamma=0.8)
for epoch in range(50):   # 训练40代
    optimizer.step()
    scheduler.step()
    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(50),lr_list,color = 'r')   # 绘制出学习率曲线
plt.show()

讲解一下上述代码:

  • lr_scheduler.MultiStepLR(optimizer, milestones=[20, 30, 32, 40, 50], gamma=0.8)中,milestones代表学习率衰减的时间点,在第20、30、32、40、50代分别衰减维原来长度的gamma倍,一般用于手动调参,相比于固定步长衰减更灵活;
  • lr下降曲线如下图所示:
    Pytorch中神经网络学习率衰减方法_第3张图片

2.4 余弦退火衰减 lr_scheduler.CosineAnnealingLR()

网络结构和导入的库都与2.1一致,其余代码如下:

lr_list = []        # 存储每代的学习率
LR = 0.01           # 定义初始学习率
optimizer = Adam(model.parameters(),lr = LR)  # 定义优化器
scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=10, eta_min=0)

# scheduler = lr_scheduler.ExponentialLR(optimizer,gamma = 0.7)  # 定义学习率控制器
for epoch in range(50):   # 训练40代
    optimizer.step()
    scheduler.step()
    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(50),lr_list,color = 'r')   # 绘制出学习率曲线
plt.show()

讲解一下上述代码:

  • scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=10, eta_min=0)中,T_max=10代表余弦函数的周期为10个epoch,eta_min=0表示余弦函数的最小值的0,最大值是开头定义的LR = 0.01 ;
  • lr下降曲线如下图所示:
    Pytorch中神经网络学习率衰减方法_第4张图片

你可能感兴趣的:(Python学习,机器学习,深度学习,python,神经网络,机器学习)