持续创作,加快生长!这是我参加「日新计划 10 月更文应战」的第5天,点击检查活动概况

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)

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

2.3.2 检查优化器的参数结构

Pytorch中的每个优化器类中均有param_groups特点,该特点包含每个待优化权重的装备参数,是一个列表目标

list(optimizer.param_group[0].keys())
#回来: ['params','lr','eps','weight_deacy','amsgrad']
#回来: ['优化器要效果的权重参数','学习率','','权重参数的衰减率','是否运用二阶冲量的办法']
### 权重参数的衰减率weight_deacy是指模型在练习过程中运用L2郑泽华的衰减参数,L2正则化是一种避免过拟合的办法

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

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)  # 获取第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 = [] # 学习率列表:用来承受每一步的学习率
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: # 每五十步将学习率 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()

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

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

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)  # 获取第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.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()

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

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

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

  • 等距离调整学习率StepLR():每练习指定步数,学习率调整为 lr = lrgamma (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。

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

  • 多距离调整学习率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 时,学习率设置为初始值。

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

  • 余弦退火函数调整学习率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。
    

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

  • 依据目标调整学习率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 时,学习率设置为初始值。

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

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()

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

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

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()

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

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

上述代码 参数Threshold_mode有两种取值:

‘rel’: 在参数mode为max时,假如监控值超越best(1+threshold),则触发规矩;在参数mode为min时,假如监控值低于best(1 – threshold),则触发规矩。【best为练习过程中的前史最好值】

‘abs’: 在参数mode为max时,假如监控值超越best + threshold,则触发规矩;在参数mode为min时,假如监控值低于best – threshold,则触发规矩。【best为练习过程中的前史最好值】