小土堆Pytorch笔记P23、24

编程基础很弱,需要机器学习,学习记录,按自己理解写的,希望以后能学懂吧,要是有大神看到还请赐教。

损失函数与反向传播

1.损失函数:

计算实际输出和目标计算之间的差距,衡量网络的预测效果越小越好。比如说损失函数较大,它会计算梯度然后调整权重使损失函数降低,即预测与实际之间的差距缩小。

为更新输出提供依据。(反向传播)梯度下降。

注意损失函数的input和target

loss_function需要根据问题去选取,在使用时要注意输入是什么输出是什么。

import torch
from torch.nn import L1Loss
from torch import nn

inputs = torch.tensor([1, 2, 3], dtype=float)
targets = torch.tensor([1, 2, 5], dtype=float)

inputs = torch.reshape(inputs, (1, 1, 1, 3))
targets = torch.reshape(targets, (1, 1, 1, 3))

#
loss = L1Loss()
result = loss(inputs, targets)
print(result)

# MSE
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs, targets)
print(result_mse)

# 交叉熵 常用于分类问题
x = torch.tensor([0.1, 0.2, 0.3])
y = torch.tensor([1])
x = torch.reshape(x, (1, 3))
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x, y)
print(result_cross)

如何在之前的神经网络中使用

# 如何在神经网络中用到Loss Function
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader

cifar_path = "D:\\Scientific_Research\\Pycharmproject\\Biji\\dataset"
dataset = torchvision.datasets.CIFAR10(root=cifar_path, train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=1)


class Lizi(nn.Module):
    def __init__(self):
        super(Lizi, 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(64 * 4 * 4, 64),
            Linear(64, 10)
        )

    def forward(self, input):
        output = self.model1(input)
        return output


loss = nn.CrossEntropyLoss()
lizi = Lizi()
for data in dataloader:
    imgs, targets = data
    outputs = lizi(imgs)
    # print(outputs)
    # print(targets)
    result_loss = loss(outputs, targets)
    print(result_loss)

反向传播:

在以上代码加一点然后debug:

# 如何在神经网络中用到Loss Function
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader

cifar_path = "D:\\Scientific_Research\\Pycharmproject\\Biji\\dataset"
dataset = torchvision.datasets.CIFAR10(root=cifar_path, train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=1)


class Lizi(nn.Module):
    def __init__(self):
        super(Lizi, 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(64 * 4 * 4, 64),
            Linear(64, 10)
        )

    def forward(self, input):
        output = self.model1(input)
        return output


loss = nn.CrossEntropyLoss()
lizi = Lizi()
for data in dataloader:
    imgs, targets = data
    outputs = lizi(imgs)
    # print(outputs)
    # print(targets)
    result_loss = loss(outputs, targets)
    print(result_loss)
#如何进行反向传播
    result_loss.backward()
    print("ok")

断点打在这里,可以发现在反向传播前,这里是没有梯度的。

再往下运行,发现计算了梯度。

优化器,就是根据这些梯度对神经网络中的这些参数进行更新,使得对整体的loss进行降低的效果。

优化器(一)

之前讲了,使用损失函数时,可以调用损失函数的backward进行反向传播可以求出每个需要调节的参数的梯度,有了这个梯度,就可以用优化器对梯度进行调增。

先构造优化器:

有了优化器后,调用优化器的step方法。

调用step时,会根据backward得到的参数对以上步骤进行重新计算,神经网络中的参数会进行一定调整。调整完后会再次进行循环,因此要将之前的梯度清零。

#优化套路

先定义一个优化器,然后梯度清零,调用反向传播,再调用优化器调优。

代码:

# 24 优化器
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader

cifar_path = "D:\\Scientific_Research\\Pycharmproject\\Biji\\dataset"
dataset = torchvision.datasets.CIFAR10(root=cifar_path, train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=1)


class Lizi(nn.Module):
    def __init__(self):
        super(Lizi, 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(64 * 4 * 4, 64),
            Linear(64, 10)
        )

    def forward(self, input):
        output = self.model1(input)
        return output


loss = nn.CrossEntropyLoss()
lizi = Lizi()
# 此处开始设置优化器
optim=torch.optim.SGD(lizi.parameters(),lr=0.01)
#依次从dataloader中取数据
for data in dataloader:
    imgs, targets = data
    outputs = lizi(imgs)#将数据送入网络中
    result_loss = loss(outputs, targets)#计算损失
    #将每个参数的对应梯度调为0
    optim.zero_grad()#这句就是调为0
    result_loss.backward()#反向传播,此句得到每个可以调节的参数对应梯度
    #接着调用优化器
    optim.step()
    print(result_loss)

Debug一下:

会发现梯度发生了变化。

运行一下看看loss效果:

 

以上代码相当于只看了一遍数据集,也就是只进行了一轮的学习,那么在这个循环外面再嵌套一层循环,运行20次epoch。

# 此处开始设置优化器
optim=torch.optim.SGD(lizi.parameters(),lr=0.01)
#依次从dataloader中取数据
#分epoch进行循环
for epoch in range(20):
    #每一轮loss是多少
    running_los=0.0
    for data in dataloader:
        imgs, targets = data
        outputs = lizi(imgs)#将数据送入网络中
        result_loss = loss(outputs, targets)#计算损失
        #将每个参数的对应梯度调为0
        optim.zero_grad()#这句就是调为0
        result_loss.backward()#反向传播,此句得到每个可以调节的参数对应梯度
        #接着调用优化器
        optim.step()
        running_los = running_los+result_loss
    print(running_los)

最开始减小了,然后增大了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值