资讯详情

【Pytorch神经网络理论篇】 10 优化器模块+退化学习率

1 优化模块的作用

1.1 反向传播的核心思想

反向传播的意义在于告诉模型我们需要修改权重到什么值可以得到最佳解决方案,在探索适当权重的过程中,正向传播结果和实际标签目标值错误,反向传播通过错误传递给权重,要求权重适当调整以实现适当的输出,最终使预测结果和标签目标值误差最小,以上

1.2 优化器简介

获得正结构和损失函数后,通过优化器模块中的优化函数优化学习参数。其内部原理主要是通过梯度下降来实现的

1.2.1 优化器和梯度下降

优化器是指通过算法帮助模型在训练过程中更快更好地将参数调整到位,梯度下降主要在损失函数求解出损失值时,它利用梯度下降的方向为前进方向,沿着梯度下降的方向求解最小值,帮助模型找到最小的那个损失值,从而可以反向推算出学习参数的权重,达到优化的目的。

1.3 优化器的类型

1.3.1 批量梯度下降

主要特点:根据函数结果更新梯度,通过遍历所有数据集计算损失函数。

缺点:每次都要遍历全部数据集,计算开销大,计算慢,不支持在线学习。

1.3.2 随机梯度下降

主要特点:每次检查一个数据,计算损失函数,并要求梯度更新函数

缺点:计算速度快,收敛性差,最优点附近容易摆动,两个参数可能相互抵消,函数波动剧烈。

1.3.3 小批量梯度下降(折中)

主要特点:将数据集分成几批,根据批次实现更新参数。一组数据共同决定梯度的反向。梯度下降方向不易偏离,随机性降低,计算量小。

缺点:————————

2 优化器

2.1常见的优化器

2.1.1 Adam

学习率为3e-4

2.1.2 Ranger

基于RAdam与Lookhead在优化器的基础上,兼顾两者的优势和综合性能,使其精度高,收敛速度快,使用方便,无需手动参考。

  • RAdam:带整流器的Adam,自适应学习率可以利用潜在散度动态打开或管理。
  • Lookhead:通过迭代更新两组权重,提前观察另一个优化器生成的序列,然后选择探索方向。

2.1.3 AMSGrad

在Adam在优化器的基础上,采用二阶冲量,在计算机视觉模型上表现更好

2.1.4 Adamax

在具有词向量的自然语言处理模型中表现得更好

2.2如何选择优化器

2.2.1 手动准确调整模型

一般先使用Adam优化器训练模型在模型不能进一步收敛后使用SGD手动调整优化器的学习率,进一步提高模型性能。

2.2.2 模型自动精确调整

一般以Adam优化器是最常用的,在收敛速度和模型训练精度等方面都有很好的效果,对学习率设置比较宽松,使用方便。

2.3使用优化器

2.3.1 调用优化器的方法

优化器工作时,首先计算梯度(根据损失值偏导参数),然后沿梯度方向计算距离(由学习率决定),将差作为变化值更新到原参数。

import torch ### Adam()是优化方法  #model.parameters():调用待优化的权重参数模型parameters(),输入返回值 #lr:学习率越大,收敛越快! optimizer = torch.optim.Adam(model.parameters(),lr = lreaning_rate)

2.3.2 检查优化器的参数结构

Pytorch每个优化器类都有param_groups该属性包括每个待优化权重的配置参数,是列表对象

list(optimizer.param_group[0].keys()) #返回: ['params','lr','eps','weight_deacy','amsgrad'] #返回: 权重参数、学习率、权重参数、是否使用二阶冲量的方法 ### 权重参数的衰减率weight_deacy指在训练过程中使用模型L2郑泽华的衰减参数,L2正则化是防止过拟合的一种方法

3 退化学习率

3.1 退化学习率简介

退化学习率/学习率下降,即在训练开始时,使用较大的学习率加速,训练后使用较小的学习率提高精度。

3.1.1 学习率下降 实现手动代码

import sklearn.datasets import torch import numpy as np import matplotlib.pyplot as plt from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary  # 准备数据 np.random.seed(0)  # 随机种子的设置 X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据 arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第一组数据索引 arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第二组数据索引 plt.title("moons data")  # 设置可视化标题 plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker=' ', label='data1')  # 显示第一组数据索引 plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引 plt.legend()  # 显示图例 plt.show()  # 构建网络模型 model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例模型 模型最终结果的输入数据的维度、隐藏节点的数量和分类数 optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 反向传播时使用  # 训练模型 xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式 yt = torch.from_numpy(Y).type(torch.LongTensor) epochs = 1000 #训练次数 losses = [] # 损失值列表:用于接受每一步的损失值 lr_list = [] # 学习率列表:用于接受每一步的学习率 for i in range(epochs):     loss = model.getloss(xt,yt)     losses.append(loss.item()) # 保存中间状态的损失值     optimizer.zero_grad() # 清空以前的梯度     loss.backward() # 反向传播损失值     optimizer.step() # 更新参数     if i % 50 == 0: # 每50步学习一次 lr X 0.99         for p in optimizer.param_groups:             p['lr'] = p['lr'] * 0.99     lr_list.append(optimizer.state_dict()['param_groups[0]lr']) # 可视化学习率 plt.plot(range(epochs),lr_list,color='r') plt.show()

3.2 使用lr_scheduler接口退化学习率

在Ptorch的optim在模块中,包装各种实现退化学习率的方法lr_scheduler接口中

3.2.1使用lr_scheduler接口退化学习率 代码实现

import sklearn.datasets import torch import numpy as np import matplotlib.pyplot as plt from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary  # 准备数据 np.random.seed(0)  # 随机种子的设置 X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据 arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第一组数据索引 arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第二组数据索引 plt.title("moons data")  # 设置可视化标题 plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker=' ', label='data1')  # 显示第组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()

# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用

# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
scheduler = torch.optim.lr_scheduler.StepLR(optimizer,step_size=50,gamma=0.99) # 设置退化学习率,每50步乘以0.99
for i in range(epochs):
    loss = model.getloss(xt,yt)
    losses.append(loss.item()) # 保存中间状态的损失值
    optimizer.zero_grad() # 清空之前的梯度
    loss.backward() # 反向传播损失值
    optimizer.step() # 更新参数
    scheduler.step() # 调用退化学习率对象
    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

 3.2.2 lr_scheduler接口中的退化学习率种类

  • 等间隔调整学习率StepLR():每训练指定步数,学习率调整为 lr = lr×gamma (gamma为手动设置的退化率参数)。
#optimizer (Optimizer) – 包装的优化器。
#step_size (int) – 学习率衰减间隔,例如若为 30,则会在 30、 60、 90…个 epoch 时,将学习率调整为 lr * gamma。
#gamma (float) – 学习率衰减的乘积因子。
#last_epoch (int) – 最后一个epoch的指数。这个变量用来指示学习率是否需要调整。当last_epoch 符合设定的间隔时,就会对学习率进行调整。当为-1 时,学习率设置为初始值。
class torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)
#调整倍数为gamma 倍,调整间隔为step_size。当last_epoch = -1时,将初始lr设置为lr。
  • 多间隔调整学习率MultiStepLR():按照指定的步数来调整学习率。调整方式也是lr= lr x gamma。
  • 指数衰减调整学习率ExponentialLR():每训练一步,学习率呈指数型衰减,即学习率调整为lr=lr ∗ gamma^epoch (step为训练步数)。
class torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=-1)
#根据epoch数和gamma调整学习率,每个epoch都在改变,调整公式:lr∗gamma^epoch。

# 参数:
## optimizer (Optimizer) – 包装的优化器。
## gamma (float) – 学习率衰减的乘积因子。
## last_epoch (int) – 最后一个epoch的指数。这个变量用来指示学习率是否需要调整。当last_epoch 符合设定的间隔时,就会对学习率进行调整。当为-1 时,学习率设置为初始值。
  • 余弦退火函数调整学习率CosineAnnealingLR():余弦退火指的就是按照弦函数的曲线进行衰减,每训练一步,学习率呈余弦函数型衰减。
    torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1)
    # 参数:
    ## T_max(int) – 一次学习率周期的迭代次数,即 T_max 个 epoch 之后重新设置学习率。
    ## eta_min(float) – 最小学习率,即在一个周期中,学习率最小会下降到 eta_min,默认值为 0。
  • 根据指标调整学习率ReduceLROnPlateau:当某指标(loss或accuracy)在最近几次训练中均没有变化(下降或升高超过给定阈值)时,调整学习率。
  • 自定义调整学习率LambdaLR:将每个参数组的学习速率设置为初始的lr乘以一个给定的函数。
class torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1)
#参数:
##optimizer (Optimizer) – 包装的优化器。
##lr_lambda (function or list) – 一个函数来计算一个乘法因子给定一个整数参数的epoch,或列表等功能,为每个组optimizer.param_groups。
##last_epoch (int) – 最后一个epoch的指数。这个变量用来指示学习率是否需要调整。当last_epoch 符合设定的间隔时,就会对学习率进行调整。当为-1 时,学习率设置为初始值。

3.2.3 多种学习率衰减总结

LambdaLR最为灵活,可以根据需求指定任何策略的学习率变化。它在fne-tune(微调模型的一种方法)中特别有用,不但可以为不同层设置不同的学习率,而且可以为不同层设置不同的学习率调整策略。

3.3 使用lr_scheduler接口实现多种退化学习率

MultiStepLR():在论文中使用较多,简单可控。

ReducelROnPlateau():自动化程度高,参数多。

3.3.1 使用lr_scheduler接口实现MultiStepLR

import sklearn.datasets
import torch
import numpy as np
import matplotlib.pyplot as plt
from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary

# 准备数据
np.random.seed(0)  # 设置随机种子
X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第2组数据索引
plt.title("moons data")  # 设置可视化标题
plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker='+', label='data1')  # 显示第一组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()

# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用

# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones=[200,700,900],gamma=0.99) #在100 700 900 次时,调整学习率

for i in range(epochs):
    loss = model.getloss(xt,yt)
    losses.append(loss.item()) # 保存中间状态的损失值
    optimizer.zero_grad() # 清空之前的梯度
    loss.backward() # 反向传播损失值
    optimizer.step() # 更新参数
    scheduler.step() # 调用退化学习率对象
    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

3.3.2 使用lr_scheduler接口实现ReduceLROnPlateau

import sklearn.datasets
import torch
import numpy as np
import matplotlib.pyplot as plt
from LogicNet_fun import LogicNet, plot_losses, predict, plot_decision_boundary

# 准备数据
np.random.seed(0)  # 设置随机种子
X, Y = sklearn.datasets.make_moons(200, noise=0.2)  # 生成两组半圆形数据
arg = np.squeeze(np.argwhere(Y == 0), axis=1)  # 获取第1组数据索引
arg2 = np.squeeze(np.argwhere(Y == 1), axis=1)  # 获取第2组数据索引
plt.title("moons data")  # 设置可视化标题
plt.scatter(X[arg, 0], X[arg, 1], s=100, c='b', marker='+', label='data1')  # 显示第一组数据索引
plt.scatter(X[arg2, 0], X[arg2, 1], s=40, c='r', marker='o', label='data2')  # 显示第二组数据索引
plt.legend()  # 显示图例
plt.show()

# 搭建网络模型
model = LogicNet(inputdim=2,hiddendim=3,outputdim=2) #实例化模型 输入数据的维度、隐藏节点的数量、模型最终结果的分类数
optimizer = torch.optim.Adam(model.parameters(),lr=0.01) # 定义优化器 在反向传播时使用

# 训练模型
xt = torch.from_numpy(X).type(torch.FloatTensor) #将数据转化为张量形式
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000 #训练次数
losses = [] # 损失值列表:用来接受每一步的损失值
lr_list = [] # 学习率列表:用来接受每一步的学习率
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
    optimizer,
    mode='min', # 要监控模型的最大值or最小值
    factor= 0.5, # 退化学习率参数 gamma
    patience=5, # 不再减少/增加的累计次数
    verbose=True, # 触发规则时是否打印信息
    threshold=0.001, # 监控值触发规则的阈值
    threshold_mode='abs', # 计算触发条件的规则
    cooldown=0, # 触发规则后的停止监控步数,避免lr下降过快
    min_lr=0, # 允许的最小退化学习率
    eps=1e-08 # 当退化学习率小于该值时,停止调整
)

for i in range(epochs):
    loss = model.getloss(xt,yt)
    losses.append(loss.item()) # 保存中间状态的损失值
    scheduler.step(loss.item()) # 调用退化学习率对象,需要传入被监控的值,否则代码出错 【ReduceLROnPlateau()特别的地方】
    optimizer.zero_grad() # 清空之前的梯度
    loss.backward() # 反向传播损失值
    optimizer.step() # 更新参数

    lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
# 学习率可视化
plt.plot(range(epochs),lr_list,color='r')
plt.show()

在参数mode为max时,如果监控值超过best(1+threshold),则触发规则;在参数mode为min时,如果监控值低于best(1 - threshold),则触发规则。【best为训练过程中的历史最好值】

在参数mode为max时,如果监控值超过best + threshold,则触发规则;在参数mode为min时,如果监控值低于best - threshold,则触发规则。【best为训练过程中的历史最好值】

标签: yt一体化液位变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台