pytorch学习(7)——神经网络优化器torch.optim

1 optim 优化器

PyTorch神经网络优化器(optimizer)通过调整神经网络的参数(weight和bias)来最小化损失函数(Loss)。

学习链接:

https://pytorch.org/docs/stable/optim.html

1.1 优化器基类

使用时必须构造一个优化器对象,它将保存当前状态,并将根据计算的梯度(grad)更新参数。

调用优化器的step方法。

CLASS torch.optim.Optimizer(params, defaults)

  • Optimizer - 优化器的优化算法。
  • params (iterable) -- torch的迭代器。张量s或dict s,指定应该优化什么张量。
  • defaults -- (dict): 包含优化选项默认值的字典(在参数组没有指定优化选项时使用)。每个Optimizer算法都有其独特的设置字典。
算法(Optimizer) 说明
Adadelta 采用Adadelta算法。
Adagrad 采用Adagrad算法。
Adam 采用Adam算法。
AdamW 采用AdamW算法。
SparseAdam 采用适合稀疏张量的Adam算法的惰性版本。
Adamax 采用Adamax算法(Adam基于无穷范数的变种)。
ASGD 采用平均随机梯度下降。
LBFGS 采用L-BFGS算法,深受minFunc的启发。
NAdam 采用NAdam 算法。
RAdam 采用RAdam 算法。
RMSprop 采用RMSprop 算法。
Rprop 采用有弹性的反向传播算法。
SGD 采用随机梯度下降算法。

1.1.1 SGD 随机梯度下降算法

CLASS torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False, *, maximize=False, foreach=None, differentiable=False)

  • params (iterable) -- iterable参数优化或字典定义参数组。
  • lr (float) -- 学习率,需要用户输入。
  • momentum (float, optional) -- 动量系数(默认值为0)。
  • weight_decay (float, optional) -- 权重衰减(L2惩罚) (默认值为0)
  • dampening (float, optional) -- 动量阻尼(默认值为0)。
  • nesterov (bool, optional) -- 使能Nesterov动量(默认值为False)。
    【Nesterov动量(Nesterov Momentum)是一种基于动量法的优化算法,用于加速神经网络的训练过程。它在随机梯度下降(SGD)的基础上进行改进,通过考虑参数更新前的动量信息来调整参数更新的方向。】
  • maximize (bool, optional) -- 根据目标最大化参数,而不是最小化参数(默认值为False)。
  • foreach (bool, optional) -- 是否使用foreach优化器的实现。如果用户未指定(foreach为None),我们将尝试在CUDA上的for循环实现上使用foreach,因为CUDA通常性能更高(默认值:None)。
  • differentiable (bool, optional) -- 是否在训练中的优化器步骤中发生autograd。否则,step()函数在torch.no_grad()上下文中运行。设置为True会影响性能,所以如果你不打算通过这个实例运行autograd,请保留False(默认值为False)。

学习速率(lr)的取值,如果太大,则模型很不稳定;如果太小,学习速度非常缓慢。因此一般先设置较大的学习速率,然后降低学习速率。

python代码如下:

python 复制代码
import torchvision
import torch
from torch import nn, optim
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential,CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
                                       train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=False)

dataloader = DataLoader(dataset, batch_size=1)

class MYNN(nn.Module):
    def __init__(self):
        super(MYNN, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2, stride=1),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

loss = CrossEntropyLoss()
mynn = MYNN()
opitm = optim.SGD(mynn.parameters(), lr=0.01)        # 优化器

for data in dataloader:
    imgs, targets = data
    outputs = mynn(imgs)
    result_loss = loss(outputs, targets)
    # print(outputs)          # 神经网络输出
    # print(targets)          # 目标
    # print(result_loss)      # 损失函数-交叉熵计算结果

    opitm.zero_grad()       # 梯度清零,设置断点
    result_loss.backward()  # 反向传播,求出每个节点的梯度,设置断点
    opitm.step()            # 对神经网络模型的参数进行调优,设置断点

设置断点,进入程序Debug:

(1)不断运行程序,能够观察到卷积层0的bias梯度变化:mynn -> Protected Attributes -> _modules -> 'model1' -> Protected Attributes -> _modules -> '0' -> bias-> grad

(2)能观察到卷积层0的weight梯度变化:mynn -> Protected Attributes -> _modules -> 'model1' -> Protected Attributes -> _modules -> '0' -> weight -> grad

(3)能观察到bias的变化:mynn -> Protected Attributes -> _modules -> 'model1' -> Protected Attributes -> _modules -> '0' -> bias-> data

(4)能观察到weight的变化:mynn -> Protected Attributes -> _modules -> 'model1' -> Protected Attributes -> _modules -> '0' -> weight-> data

(5)结论:运行opitm.zero_grad()后,清空weight和bias的梯度grad;运行result_loss.backward()后,计算得到新的weight和bias的梯度grad;运行opitm.step()后,调整weight和bias的值。

1.1.2 优化器多次循环

修改以上python代码,增加多次循环,观察总体损失值改变。

python 复制代码
import torchvision
import torch
from torch import nn, optim
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential,CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
                                       train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=False)

dataloader = DataLoader(dataset, batch_size=1)

class MYNN(nn.Module):
    def __init__(self):
        super(MYNN, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2, stride=1),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2, stride=1),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

loss = CrossEntropyLoss()
mynn = MYNN()
opitm = optim.SGD(mynn.parameters(), lr=0.01)        # 优化器

for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        outputs = mynn(imgs)
        result_loss = loss(outputs, targets)
        # print(outputs)          # 神经网络输出
        # print(targets)          # 目标
        # print(result_loss)      # 损失函数-交叉熵计算结果
        opitm.zero_grad()       # 梯度清零
        result_loss.backward()  # 反向传播,求出每个节点的梯度
        opitm.step()            # 对神经网络模型的参数进行调优

        running_loss = running_loss + result_loss#.data

    print(running_loss)

运行结果:

c 复制代码
tensor(18746.2012, grad_fn=<AddBackward0>)
tensor(16136.0107, grad_fn=<AddBackward0>)
tensor(15499.3203, grad_fn=<AddBackward0>)
tensor(nan, grad_fn=<AddBackward0>)
tensor(nan, grad_fn=<AddBackward0>)
tensor(nan, grad_fn=<AddBackward0>)

可以发现running_loss在一开始不断降低,但是以下的nan暂时不知道是什么原因。

相关推荐
怀旧6661 小时前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
infiniteWei2 小时前
【Lucene】原理学习路线
学习·搜索引擎·全文检索·lucene
follycat2 小时前
[极客大挑战 2019]PHP 1
开发语言·学习·网络安全·php
weixin_518285053 小时前
深度学习笔记11-神经网络
笔记·深度学习·神经网络
并不会6 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
龙鸣丿6 小时前
Linux基础学习笔记
linux·笔记·学习
Nu11PointerException8 小时前
JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
笔记·学习
sp_fyf_202411 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
多吃轻食11 小时前
大模型微调技术 --> 脉络
人工智能·深度学习·神经网络·自然语言处理·embedding
@小博的博客12 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习