sunpongber

优化器(一)

PyTorch官网

前面提到了反向传播,当使用损失函数时,可以调用损失函数的backward,就可以得到反向传播
它可以求解出每一个需要调节的参数,这个参数对应的梯度,有了这个梯度,就可以利用优化器,让这个优化器根据这个梯度对参数进行调整,达到整体误差降低的目的

torch.optim

import torch.optim
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="P19_nn_maxpool/dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)

dataLoader = DataLoader(dataset, batch_size=1)

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

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

        return x

loss = nn.CrossEntropyLoss()

NN_squential = nn_squential()

optim = torch.optim.SGD(NN_squential.parameters(), lr=0.01)

for data in dataLoader:
    imgs, targets = data
    outputs = NN_squential(imgs)
    result_loss = loss(outputs, targets)
    optim.zero_grad() # 把每一个节点对应的梯度清理因为上一次的梯度对这次的梯度没用
    result_loss.backward() # 得到了每一个可以调节参数对应的梯度
    optim.step() # 调用优化器对每个参数进行调优

debug

NN_squential -> 受保护的特性 -> _modules -> 'model1' -> 受保护的特性 -> _modules -> '0' -> weight -> grad

optim.zero_grad()
result_loss.backward()

每次都会计算出一个新的梯度(grad)

optim.step()会对data优化

依次循环往复,让最终的loss变小

print(result_loss)

返回:

Files already downloaded and verified
tensor(2.2757, grad_fn=<NllLossBackward0>)
...

每一个节点上loss的一个变化,感觉loss好像没有变小,为什么呢?
DataLoader就是对我们这个数据,现在相当于这个网络模型只在数据上都只看了一遍
现在看到这些数据对下一次看到这些数据的预测的影响不是很大,一般情况下都需要对数据进行好几轮的学习

在循环外套一层循环,epoch就会从0一直运行到20

for epoch in range(20):
    running_loss = 0.0
    for data in dataLoader:
        imgs, targets = data
        outputs = NN_squential(imgs)
        result_loss = loss(outputs, targets)
        optim.zero_grad() # 把每一个节点对应的梯度清理因为上一次的梯度对这次的梯度没用
        result_loss.backward() # 得到了每一个可以调节参数对应的梯度
        optim.step() # 调用优化器对每个参数进行调优
        running_loss = running_loss + result_loss
    print(running_loss)

在每一轮开始之前,把loss设置为0,在这一轮学习的过程中,计算出的每一个数据的loss都加上去,running_loss就相当于每一轮学习的过程中,在这一轮所有的数据上的整体loss的总和

返回:

Files already downloaded and verified
tensor(18817.4648, grad_fn=<AddBackward0>)
tensor(16212.9375, grad_fn=<AddBackward0>)
tensor(15470.7930, grad_fn=<AddBackward0>)
...

可以看到,第一轮整体的神经网络在所有的数据中误差值和,第二轮的...,第三轮的...
可以看到,通过这种方式,优化器对模型参乎不断进行优化,每一轮上的loss都在不断减小\

这就是优化器的使用,也相当于模型的训练,在这个过程中就在不断地训练模型,在实际的训练模型过程中,最外层的循环都是成百上千或者上万的

原始资料地址:
优化器(一)
如有侵权联系删除 仅供学习交流使用