一、作用:
1、计算实际输入与目标输出之间的差值
2、为反向传播更新数据提供一个依据(反向传播是一种训练神经网络的算法,主要用计算每个参数对于损失函数的梯度,从而通过梯度下降法来更新网络参数,使得神经网络逐渐适应网络数据)
二、常用的损失函数:
1、L1Loss:
计算方法:
代码实战:
import torch
from torch import nn
input = torch.tensor([1,2,3],dtype=torch.float32)
targets = torch.tensor([1,2,5],dtype=torch.float32)
input = torch.reshape(input,[1,1,1,3]) #模拟实际情况,batch_size为1,通道数为1,长宽分别为1,3
targets = torch.reshape(targets,[1,1,1,3])
# 指定计算方式
# reduction有两种方式:默认为mean,求的是平均值,另一种是sum,求的是和
loss = nn.L1Loss(reduction="sum")
result = loss(input,targets)
print(result)
# 用mean得到的结果是0.6667,即2/3
# 用sum得到的结果是2,即 0+0+2
2、MSELoss:
计算方法:
代码实战:与L1Loss大致相同,不同的是不需要智能计算方式:
import torch
from torch import nn
input = torch.tensor([1,2,3],dtype=torch.float32)
targets = torch.tensor([1,2,5],dtype=torch.float32)
input = torch.reshape(input,[1,1,1,3])
targets = torch.reshape(targets,[1,1,1,3])
loss_mse = nn.MSELoss()
result2 = loss_mse(input,targets)
print(result2)
三、交叉熵:
1、作用:交叉熵CrossEntropyLoss主要应用于分类问题:
2、交叉熵的计算:
与损失函数相同,交叉熵也是越小越好
基于此图片,模拟交叉熵的工作方式,代码如下:
import torch
from torch import nn
x = torch.tensor([0.1,0.2,0.3]) # 创建一个张量,模拟识别出图像的概率
y = torch.tensor([1]) # 命中
# 根据需求改变x
# nn.CrossEntropyLoss有连个参数
# N参数: 形状
# C参数:共有多少类别
x = torch.reshape(x,[1,3])
# 参数x:形状,因为是一维矩阵,因此传入1
# 参数3:因为张量中有三个概率,因此含有三个类别
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x,y)
print(result_cross)
放入真实神经网络模型中(此模型再前几篇文章中有搭建的方法和图例)
from torch import nn
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from torch.utils.data import DataLoader
import torchvision
tensor_trans = transforms.ToTensor()
test_data = torchvision.datasets.CIFAR10(root="./dataloader",train=False,transform=tensor_trans,download=True)
dataloader = DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0,drop_last=False)
# 在神经网络模型中padding需要自己进行根据公式进行计算
class Module(nn.Module):
def __init__(self):
super().__init__()
# 第一次卷积,输出的通道数为下一个图像的输入通道数,padding根据公式自己计算
self.conv1 = nn.Conv2d(in_channels=3,out_channels=32,kernel_size=5,padding=2)
self.maxpool1 = nn.MaxPool2d(kernel_size=2)
self.conv2 = nn.Conv2d(in_channels=32,out_channels=32,kernel_size=5,padding=2)
self.maxpool2 = nn.MaxPool2d(2)
self.conv3 = nn.Conv2d(in_channels=32,out_channels=64,kernel_size=5,padding=2)
self.maxpool3 = nn.MaxPool2d(kernel_size=2)
self.flatten = nn.Flatten()
# 1024计算:图中给出64@4*4,即共64*4*4个输出
self.linear1 = nn.Linear(1024,64)
self.linear2 = nn.Linear(64,10)
def forward(self,imgs):
imgs = self.conv1(imgs)
imgs = self.maxpool1(imgs)
imgs = self.conv2(imgs)
imgs = self.maxpool2(imgs)
imgs = self.conv3(imgs)
imgs = self.maxpool3(imgs)
imgs = self.flatten(imgs)
imgs = self.linear1(imgs)
imgs = self.linear2(imgs)
return imgs
# 检测结果是否正确
# module = Module()
# input = torch.ones([64,3,32,32]) # 利用ones函数设置一个全为1的张量,指定形状为(64,3,32,32),用于测试数据是否正确
# output = module(input)
# print(output.shape)
loss = nn.CrossEntropyLoss()
module = Module()
for data in dataloader:
imgs,targets = data
output = module(imgs)
# result_loss得到的是神经网络输出和真实输出之间的一个误差
result_loss = loss(output,targets)
print(result_loss)
三、反向传播:
反向传播是神经网络模型训练的核心组成部分,它通过计算梯度并将这些信息反向传递回网络,使得网络参数得以更新,从而有效减少预测错误,提高模型性能
(采用的还是上述的神经网络模型做实验)
loss = nn.CrossEntropyLoss()
module = Module()
for data in dataloader:
imgs,targets = data
output = module(imgs)
# result_loss得到的是神经网络输出和真实输出之间的一个误差
result_loss = loss(output,targets)
# 反向传播采用的对象是经过交叉熵计算后的结果进行反向传播
result_loss.baclward()