首页 > 其他分享 >3. PyTorch主要组成模块(2)

3. PyTorch主要组成模块(2)

时间:2022-08-21 23:11:51浏览次数:72  
标签:weight float 默认 PyTorch lr 模块 1e 参数 组成

3.8 Pytorch优化器()

  优化器是根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值,使得模型输出更加接近真实标签。

3.9.1 Pytorch提供的优化器

  • torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)

  • 功能:实现平均随机梯度下降算法。

     参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float, 可选) – 学习率(默认:1e-2)
    • lambd (float, 可选) – 衰减项(默认:1e-4)
    • alpha (float, 可选) – eta更新的指数(默认:0.75)
    • t0 (float, 可选) – 指明在哪一次开始平均化(默认:1e6)
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0) -- 预防过拟合(沐神)
  • torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)

  功能:实现Adagrad算法,Adagrad适用于数据稀疏或者分布不平衡的数据集

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float, 可选) – 学习率(默认: 1e-2)
    • lr_decay (float, 可选) – 学习率衰减(默认: 0)
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

  优点:它可以自动调节学习率,不需要人为调节

  缺点:仍依赖于人工设置一个全局学习率,随着迭代次数增多,学习率会越来越小,最终会趋近于0

  • torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)

  功能:实现Adadelta算法,是Adagard的改进版,对学习率进行自适应约束,但是进行了计算上的简化,加速效果不错,训练速度快

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • rho (float, 可选) – 用于计算平方梯度的运行平均值的系数(默认:0.9)
    • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-6)
    • lr (float, 可选) – 在delta被应用到参数更新之前对它缩放的系数(默认:1.0)
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

  优点:避免在训练后期,学习率过小;初期和中期,加速效果不错,训练速度快

  缺点:还是需要自己手动指定初始学习率,初始梯度很大的话,会导致整个训练过程的学习率一直很小,在模型训练的后期,模型会反复地在局部最小值附近抖动,从而导致学习时间变长

  • torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)

  功能:实现Adam算法。

  原理:将Momentum算法和RMSProp算法结合起来使用的一种算法,既用动量来累积梯度,又使得收敛速度更快同时使得波动的幅度更小,并进行了偏差修正

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float, 可选) – 学习率(默认:1e-3)
    • betas (Tuple[floatfloat], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999)
    • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

  优点:

    1、对目标函数没有平稳要求,即loss function可以随着时间变化

    2、参数的更新不受梯度的伸缩变换影响

    3、更新步长和梯度大小无关,只和alpha、beta_1、beta_2有关系。并且由它们决定步长的理论上限

    4、更新的步长能够被限制在大致的范围内(初始学习率)

    5、能较好的处理噪音样本,能天然地实现步长退火过程(自动调整学习率)

    6、很适合应用于大规模的数据及参数的场景、不稳定目标函数、梯度稀疏或梯度存在很大噪声的问题 

  • torch.optim.AdamW(paramslr=0.001betas=(0.9, 0.999)eps=1e-08weight_decay=0.01amsgrad=False*maximize=Falseforeach=Nonecapturable=False)

  功能:Adam的进化版,是目前训练神经网络最快的方式

  参数:

    • 参数(可迭代) – 可迭代参数以优化或指示定义参数组

    • lr(浮点数可选)– 学习速率(默认值:1e-3)

    • betas(元组[浮点数,浮点数]可选)–用于计算梯度及其平方的运行平均值的系数(默认值:(0.9,0.999))

    • eps(浮点数可选)– 添加到分母以提高数值稳定性的术语(默认值:1e-8)

    • weight_decay(浮点数可选)– 权重衰减系数(默认值:1e-2)

    • amsgrad(布尔值可选)–是否使用此算法的AMSGrad变体(默认:False)

    • 最大化(布尔值可选)–根据目标最大化参数,而不是最小化(默认值:False)

    • foreach(布尔值可选)– 是否使用优化器的 foreach 实现(默认值:无)

    • 可捕获(布尔值可选)– 此实例在 CUDA 图中捕获是否安全。传递 True 可能会损害未绘制的性能,因此,如果您不打算以图形捕获此实例,请将其保留为 False(默认值:False)

  优点:比Adam收敛得更快

  缺点:只有fastai使用,缺乏广泛的框架,而且也具有很大的争议性

  • torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)

  功能:实现Adamax算法,Adam的改进版,对Adam增加了一个学习率上限的概念,是Adam的一种基于无穷范数的变种。

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float, 可选) – 学习率(默认:2e-3)
    • betas (Tuple[floatfloat], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数
    • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

  优点:对学习率的上限提供了一个更简单的范围

  • torch.optim.SparseAdam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)

  功能:实现适用于稀疏张量的 Adam 算法的“阉割版”。

  参数:

    • 参数(可迭代) – 可迭代参数以优化或指示定义参数组
    • lr(浮点数可选)– 学习速率(默认值:1e-3)
    • betas(元组[浮点数,浮点数]可选)–用于计算梯度及其平方的运行平均值的系数(默认值:(0.9,0.999))
    • eps(浮点数可选)– 添加到分母以提高数值稳定性的术语(默认值:1e-8)

  优点:相当于Adam的稀疏张量专用版本

  • torch.optim.LBFGS(params, lr=1, max_iter=20, max_eval=None, tolerance_grad=1e-05, tolerance_change=1e-09, history_size=100, line_search_fn=None)

  功能:实现L-BFGS算法。是一种在牛顿法基础上提出的一种求解函数根的算法,简单来说,L-BFGS和梯度下降、SGD干的同样的事情,但大多数情况下收敛速度更快

     L-BFGS是对BFGS的改进,特点就是节省内存。是解无约束非线性规划问题最常用的方法

  参数:

    • lr (float) – 学习率(默认:1)
    • max_iter (int) – 每一步优化的最大迭代次数(默认:20))
    • max_eval (int) – 每一步优化的最大函数评价次数(默认:max * 1.25)
    • tolerance_grad (float) – 一阶最优的终止容忍度(默认:1e-5)
    • tolerance_change (float) – 在函数值/参数变化量上的终止容忍度(默认:1e-9)
    • history_size (int) – 更新历史的大小(默认:100)

  优点:收敛速度快、内存开销少,是解无约束非线性规划问题最常用的方法

  缺点:使用条件严苛 

  • torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))

  原理:

    1、首先为各权重变化赋一个初始值,设定权重变化加速因子与减速因子。

    2、在网络前馈迭代中当连续误差梯度符号不变时,采用加速策略,加快训练速度;当连续误差梯度符号变化时,采用减速策略,以期稳定收敛。

    3、网络结合当前误差梯度符号与变化步长实现BP,同时,为了避免网络学习发生振荡或下溢,算法要求设定权重变化的上下限

  功能:实现弹性反向传播算法。

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float, 可选) – 学习率(默认:1e-2)
    • etas (Tuple[floatfloat], 可选) – 一对(etaminus,etaplis), 它们分别是乘法的增加和减小的因子(默认:0.5,1.2)
    • step_sizes (Tuple[floatfloat], 可选) – 允许的一对最小和最大的步长(默认:1e-6,50)

  缺点:优化方法适用于full-batch,不适用于mini-batch,因此基本上没什么用

  • torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)

  功能:实现RMSprop算法。RProp的改进版,也是Adagard的改进版

  思想:梯度震动较大的项,在下降时,减小其下降速度;对于震动幅度小的项,在下降时,加速其下降速度

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float, 可选) – 学习率(默认:1e-2)
    • momentum (float, 可选) – 动量因子(默认:0)
    • alpha (float, 可选) – 平滑常数(默认:0.99)
    • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
    • centered (bool, 可选) – 如果为True,计算中心化的RMSProp,并且用它的方差预测值对梯度进行归一化
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

  优点:可缓解Adagrad学习率下降较快的问题,并且引入均方根(分母),可以减少摆动,适合处理非平稳目标,对于RNN效果很好

  缺点:依然依赖于全局学习率 

  • torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)

  功能:实现随机梯度下降算法(momentum可选)。

  参数:

    • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
    • lr (float) – 学习率
    • momentum (float, 可选) – 动量因子(默认:0)
    • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认:0)
    • dampening (float, 可选) – 动量的抑制因子(默认:0)
    • nesterov (bool, 可选) – 使用Nesterov动量(默认:False)

  优点:①使用mini-batch的时候,可以收敛得很快

  缺点:①在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确

             ②不能解决局部最优解的问题

  若使用动量( momentum不为0可加快收敛速度,有一定摆脱局部最优的能力,一定程度上缓解了没有动量的时候的问题)

 

  上述优化算法均继承于Optimizer:

class Optimizer(object):
    def __init__(self, params, defaults):        
        self.defaults = defaults
        self.state = defaultdict(dict)
        self.param_groups = []

  Optimizer有三个属性:

  • defaults:存储的是优化器的超参数
{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}
  • state:参数的缓存
defaultdict(<class 'dict'>, {tensor([[ 0.3864, -0.0131],
        [-0.1911, -0.4511]], requires_grad=True): {'momentum_buffer': tensor([[0.0052, 0.0052],
        [0.0052, 0.0052]])}})
  • param_groups:管理的参数组,是一个list,其中每个元素是一个字典,顺序是params,lr,momentum,dampening,weight_decay,nesterov
[{'params': [tensor([[-0.1022, -1.6890],[-1.5116, -1.7846]], requires_grad=True)], 'lr': 1, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}]

  Optimizer其他方法:

  • zero_grad():清空所管理参数的梯度,PyTorch的特性是张量的梯度不自动清零,因此每次反向传播后都需要清空梯度。

  • step():执行一步梯度更新,参数更新
  • add_param_group():添加参数组

  • load_state_dict() :加载状态参数字典,可以用来进行模型的断点续训练,继续上次的参数进行训练

  • state_dict():获取优化器当前状态信息字典

3.9.2 实际操作

import os
import torch

# 设置权重,服从正态分布  --> 2 x 2
weight = torch.randn((2, 2), requires_grad=True)
# 设置梯度为全1矩阵  --> 2 x 2
weight.grad=torch.ones((2, 2))
# 输出现有的weight和data
print("The data of weight before step:\n{}".format(weight.data))
print("The grad of weight before step:\n{}".format(weight.grad))
# 实例化优化器
optimizer = torch.optim.SGD([weight], lr=0.1, momentum=0.9)
# 进行一步梯度更新
optimizer.step()
# 查看进行一步后的值,梯度
print("The data of weight after step:\n{}".format(weight.data))
print("The grad of weight after step:\n{}".format(weight.grad))
# 梯度清零
optimizer.zero_grad()
# 检验权重是否为0
print("The grad of weight after optimizer.zero_grad():\n{}".format(weight.grad))
# 输出参数
print("optimizer.params_group is \n{}".format(optimizer.param_groups))
# 查看参数位置,optimizer和weight的位置一样,我觉得这里可以参考Python是基于值管理
print("weight in optimizer:{}\nweight in weight:{}\n".format(id(optimizer.param_groups[0]['params'][0]), id(weight)))
# 添加参数:weight2 weight2 = torch.randn((3, 3), requires_grad=True) optimizer.add_param_group({"params": weight2, 'lr': 0.0001, 'nesterov': True})# 添加参数组 # 查看现有的参数 print("optimizer.param_groups is\n{}".format(optimizer.param_groups)) # 查看当前状态信息 opt_state_dict = optimizer.state_dict() print("state_dict before step:\n", opt_state_dict) # 进行5次step操作 for _ in range(50): optimizer.step() # 输出现有状态信息 print("state_dict after step:\n", optimizer.state_dict()) # 保存参数信息 torch.save(optimizer.state_dict(),os.path.join(r"SavePath", "optimizer_state_dict.pkl")) print("----------done-----------") # 加载参数信息 state_dict = torch.load(r"SavePath + \optimizer_state_dict.pkl") # 需要修改为你自己的路径
optimizer.load_state_dict(state_dict)
print("load state_dict successfully\n{}".format(state_dict))
# 输出最后属性信息 print("\n{}".format(optimizer.defaults)) print("\n{}".format(optimizer.state)) print("\n{}".format(optimizer.param_groups))

  注:

  1. 每个优化器都是一个类,我们一定要进行实例化才能使用:

class Net(nn.Moduel):
    ...
net = Net()
optim = torch.optim.SGD(net.parameters(), lr=lr)
optim.step()

 

  2.optimizer在一个神经网络的epoch中需要实现下面两个步骤:

 

    • 梯度置零

    • 梯度更新

optimizer = torch.optim.SGD(net.parameters(), lr = 1e-3)
for epoch in range(epochs):
    ...
    optimizer.zero_grad() # 梯度清零
    loss = ... # 计算loss
    loss.backward() # loss反向传播
    optimizer.step() # 梯度更新

  3.给网络不同的层赋予不同的优化器参数。

from torch import optim
from torchvision.models import resnet18

net = resnet18()

optimizer = optim.SGD([
    {'params':net.fc.parameters()},#fc的lr使用默认的1e-5
    {'params':net.layer4[0].conv1.parameters(),'lr':1e-2}],lr=1e-5)
# 可以使用param_groups查看属性

标签:weight,float,默认,PyTorch,lr,模块,1e,参数,组成
From: https://www.cnblogs.com/5466a/p/16611186.html

相关文章

  • 3. PyTorch主要组成模块(1)
    3.1构建PyTorch项目的基本配置调用常用的库:importosimportnumpyasnpimporttorchimporttorch.nnasnn#常用的神经网络库fromtorch.utils.dataimport......
  • nginx ngx_http_degradation_module 模块
    ngx_http_degradation_module是一个不错的nginx模块,但是官方文档没有写,主要的场景是在低内存的情形下允许Nginx服务器返回444错误或204错误参考使用 http......
  • STC8H开发(十六): GPIO驱动XL2400无线模块
    目录STC8H开发(一):在Keil5中配置和使用FwLib_STC8封装库(图文详解)STC8H开发(二):在LinuxVSCode中配置和使用FwLib_STC8封装库(图文详解)STC8H开发(三):基于FwLib......
  • Anaconda, PyTorch, CUDA Driver, PyCharm 安装与配置
    1安装Anaconda(2022.05)最新版本https://www.anaconda.com/历史版本https://repo.anaconda.com/archive/打开安装包:nextIAgreeJustMe(影响之后创建虚拟环境的......
  • 深度学习 之 模型部署【4】-libtorch入门 - pytorch部署torchscript 以及 c++ libto
    pytorch部署torchscriptfromtorchvision.modelsimportresnet34importtorch.nn.functionalasFimporttorch.nnasnnimporttorchimportcv2#读取一张图片,......
  • pytorch环境下查看gpu是否可用
    (36条消息)yolov5设置GPU-CSDNpython#输入库importtorch#查看版本print(torch.__version__)#查看gpu是否可用torch.cuda.is_available()#返回设备gpu个数tor......
  • Geometry模块之File IO
    1读取PointCloud首先要明白,该库所支持的点云文件类型都有哪些,官网写的很清楚:文件类型类型描述xyz每一行由[x,y,z]三维坐标构成xyzn每一行由[x,y......
  • SIC 模块FF08MR12W1MA1B11ABPSA1 150A 1200V /FF08MR12W1MA1B11概述
    概述FF08MR12W1MA1B111200VCoolSiC™模块是碳化硅(SiC)MOSFET模块,具有较高的效率和系统灵活性。这些模块采用近阈值电路(NTC)和PressFIT触点技术。该款CoolSiC模块具......
  • NO.4 计算机组成-笔记
    第一章:计算机系统概述1、什么是计算机系统 1、计算机系统=硬件+软件(计算机性能的好坏取决于“软”“硬”件功能的总和) 2、软件分为: ......
  • conda自动安装cpu版本pytorch
    问题描述由于conda自带的源太慢,换成了清华源,结果无论怎么下载都无法使用cuda。检查conda列表发现装的是cpu版本原因网上众说纷纭,例如删掉cpu-only包,但都是瞎猫碰上死耗......