11.26学习

本文介绍了损失函数在神经网络中的关键作用,如L1Loss、MSELoss和CrossEntropyLoss的计算,以及如何通过反向传播和优化器(如SGD)进行模型训练。同时涵盖了网络模型的修改、保存与读取方法。
摘要由CSDN通过智能技术生成

(十)损失函数

1.实际值与目标值的差,对于神经网络来说,就是依据损失函数进行训练来减小误差

2.为我们更新输出提供一定依据(反向传播)

较为简单的两种损失函数:L1Loss和MSELoss

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

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

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

loss = L1Loss()#默认差值的平均是loss
#loss = L1Loss(reduction='sum')#以差值的和作为loss,不除以个数
result = loss(targets,inputs)#顺序无所谓
loss_mse = MSELoss()
result_mse = loss_mse(inputs,targets)

print(result)
#tensor(0.6667)=(0+0+2)/3
print(result_mse)
#tensor(1.3333)=(0+0+2^2)/3

CrossEntropyLoss():训练一个分类问题有多个类别

计算公式及实例:

x = torch.tensor([0.1,0.2,0.3])#表示有三类,每一类的概率是0.1,0.2,0.3
y = torch.tensor([2])#代表目标是选择第几类class,代表取第几类对应的gailv
x = torch.reshape(x,(1,3))#1 batchsize ,3 class
loss_cross = CrossEntropyLoss()
result_cross = loss_cross(x,y)
print(result_cross)#tensor(1.0019)

在神经网络中应用loss function

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

dataset = torchvision.datasets.CIFAR10("../data",train=False,transform = torchvision.transforms.ToTensor(),
                                       download=True )
dataloader = DataLoader(dataset,batch_size=1)

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

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

loss = nn.CrossEntropyLoss()
tudui = Tudui()
for data in dataloader:
    imgs,targets = data
    outputs = tudui(imgs)
    result_loss = loss(outputs,targets)#得到的结果就是神经网络输出和真实输出的误差
    print(result_loss)
#其中一个tensor(2.3101, grad_fn=<NllLossBackward0>)

 优化:通过反向传播计算梯度

    result_loss.backward()#对所有的误差反向传播,可以算出每个节点的梯度,选择合适的优化器就可以降低loss

(十一)优化器

官网:torch.optim — PyTorch 2.1 documentation

optim优化器:

必须设置参数:params--模型参数   lr---学习速率

学习速率一般一开始选择较大的学习,后面较小,不能太大因为要保证模型的稳定性,不能太小,因为要保证学习的时间

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

dataset = torchvision.datasets.CIFAR10("../data",train=False,transform = torchvision.transforms.ToTensor(),
                                       download=True )
dataloader = DataLoader(dataset,batch_size=1)

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

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

loss = nn.CrossEntropyLoss()
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters(),lr=0.01)
for epoch in range(20):#进行20轮学习
    running_loss = 0.0
    for data in dataloader:#循环里只是一轮的学习
        imgs,targets = data
        outputs = tudui(imgs)
        result_loss = loss(outputs,targets)
        optim.zero_grad()#再经历下一张图片的循环把每个参数的梯度清为0
        result_loss.backward()#得到每个可调节参数的梯度
        optim.step()#对每个参数进行调优
        running_loss += result_loss#running_loss是一轮学习的loss总和
    print(running_loss)
'''tensor(18761.5312, grad_fn=<AddBackward0>)
tensor(16223.5635, grad_fn=<AddBackward0>)
tensor(15507.4404, grad_fn=<AddBackward0>)
tensor(16075.2520, grad_fn=<AddBackward0>)
tensor(17764.1367, grad_fn=<AddBackward0>)
tensor(20371.1895, grad_fn=<AddBackward0>)
tensor(21939.2676, grad_fn=<AddBackward0>)
tensor(23337.0488, grad_fn=<AddBackward0>)
tensor(24637.6582, grad_fn=<AddBackward0>)
tensor(25039.6445, grad_fn=<AddBackward0>)
tensor(25879.0605, grad_fn=<AddBackward0>)
tensor(26419.8301, grad_fn=<AddBackward0>)
tensor(26879.6621, grad_fn=<AddBackward0>)
tensor(27363.1777, grad_fn=<AddBackward0>)
tensor(28633.2344, grad_fn=<AddBackward0>)
tensor(29611.9082, grad_fn=<AddBackward0>)
tensor(34961.2227, grad_fn=<AddBackward0>)
tensor(nan, grad_fn=<AddBackward0>)
tensor(nan, grad_fn=<AddBackward0>)
tensor(nan, grad_fn=<AddBackward0>)   '''

最终loss是先下降后上升,原因可能是因为学习率过大,出现nan是因为梯度爆炸

(十二)现有网络模型的使用及修改

现有网络模型添加及修改

以vgg训练模型为例

import torchvision
from torch import nn

vgg16_false = torchvision.models.vgg16(weights = None)#网络模型参数是直接复制过来
vgg16_true = torchvision.models.vgg16(weights='DEFAULT')#网络模型参数是训练好的达到一个好的效果

#print(vgg16_true)

train_data = torchvision.datasets.CIFAR10('../data',train=True,transform=torchvision.transforms.ToTensor(),
                                          download=True)
#原本的vgg模型有1000个类别,而CIFAR10只有10个类别,所以需要再多加一个线性层
vgg16_true.classifier.add_module('add_linear', nn.Linear(1000,10))#添加网络模型结构
#加上.classifier就放在这个里了
print(vgg16_true)

print(vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096,10)#对于现有的网络模型进行修改
print(vgg16_false)

 (十三)网络模型的保存与读取

网络模型的保存

#文件1 model_save
import torch
import torchvision

vgg16 = torchvision.models.vgg16(weights = None)
#保存方式1,除了保存网络模型的结构还保存了参数
torch.save(vgg16,"vgg16_method1.pth")

#保存方式2,只保存参数在字典里(推荐,空间小)
torch.save(vgg16.state_dict(),"vgg16_method2.pth")

网络模型的读取

#wenjian2 model_load
import torch
import torchvision

#方式1 -》保存方式1,加载模型
#model = torch.load("vgg16_method1.pth")
#print(model)

#方式2 -》加载模型,加载出来保存的只有字典,如果要恢复网络模型结构:
vgg16 = torchvision.models.vgg16(weights=None)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
#model = torch.load("vgg16_method2.pth")
#print(model)
print(vgg16)

注意两种方式的对应

如果是自建网络模型在读取时用方式一可能会报错,应加上引用:

from 文件名 import *(代表全部引用)

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值