21.损失函数与反向传播

损失函数与反向传播

损失函数

损失函数(Loss Function)是用来度量模型预测值与真实标签之间差异的函数。它接受模型的输出和真实标签作为输入,并输出一个数值,该数值表示模型预测的错误程度或差异程度。损失函数通常被设计成非负的,当模型预测值与真实标签完全一致时,损失函数达到最小值。

损失函数大致可以分成两类:回归(Regression)和分类(Classification)。

常见的损失函数:

交叉熵损失函数(Cross-Entropy Loss):
用于多分类任务,特别是在类别互斥的情况下;

均方误差损失函数(Mean Squared Error Loss):
用于回归任务;
计算模型输入与真实标签之间的平方差;

平均绝对误差损失函数(Mean Absolute Error Loss):
用于回归任务;
计算模型输出与真实标签之间的绝对差;

反向传播

反向传播(Backpropagation):反向传播是深度学习中的一种核心算法,用于计算损失函数对模型每一个参数的梯度。在优化模型参数(例如使用梯度下降算法)的过程中,我们需要知道模型每一项参数的梯度方向,以此来更新参数。

反向传播算法工作流程如下:

前向传播(Forward Pass):数据沿着从输入层至输出层的方向进行传播,经过每一层的操作,最终在输出层产生预测值。
损失计算:根据模型的预测值和真实值,使用损失函数计算损失。
反向传播(Backward Pass):根据链式法则(Chain Rule),从输出层开始,沿着网络的结构向反方向(输入层方向)回传,计算损失函数对每一层参数的梯度。

反向传播能够有效地计算损失函数关于每一个参数的梯度,结合优化算法(如SGD,Adam等),这使得我们可以通过梯度下降法更新模型的参数,进而训练我们的模型。(上面说的训练的目标就是找到一组参数可以最小化损失函数,这里更新参数就是为了这个目的)

总结

torch.nn 里的 loss function 衡量误差,在使用过程中根据需求使用,注意输入形状和输出形状即可

loss 衡量实际神经网络输出 output 与真实想要结果 target 的差距,越小越好

作用:

  1. 计算实际输出和目标之间的差距
  2. 为我们更新输出提供一定的依据(反向传播):给每一个卷积核中的参数提供了梯度 grad,采用反向传播时,每一个要更新的参数都会计算出对应的梯度,优化过程中根据梯度对参数进行优化,最终达到整个 loss 进行降低的目的

梯度下降法:

image-20240808163055532

1. L1LOSS

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

input:(N,*) N是batch_size,即有多少个数据;*可以是任意维度

CLASS torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')

小例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码

import torch
from torch.nn import L1Loss
 
# 实际数据或网络默认情况下就是float类型,不写测试案例的话一般不需要加dtype
inputs = torch.tensor([1,2,3],dtype=torch.float32)   # 计算时要求数据类型为浮点数,不能是整型的long
targets = torch.tensor([1,2,5],dtype=torch.float32)
 
inputs = torch.reshape(inputs,(1,1,1,3))   # 1 batch_size, 1 channel, 1行3列
targets = torch.reshape(targets,(1,1,1,3))
 
#L1Loss默认求均值的方式
loss = L1Loss()
#L1Loss改成求和的方式
#loss = L1Loss(reduction='sum')
result = loss(inputs,targets)
print(result)

image-20240813235344346

运行结果:

tensor(0.6667)

L1Loss可以选择计算的方式,修改成求和的方式:

修改上述代码中的一句即可

loss = L1Loss(reduction='sum')

运行结果:

tensor(2.)

2.MSELOSS(均方误差)

input:(N,*) N是batch_size,即有多少个数据;*可以是任意维度

CLASS torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加如下几行代码:

from torch import nn

#MSELOSS(均方误差)
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs, targets)
print(result_mse)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果:

tensor(1.3333)

上述代码的例子:

6

3. CROSSENTROPYLOSS(交叉熵)

适用于训练分类问题,有C个类别

**例:**三分类问题,person,dog,cat

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(公式中的 log 可以按 ln 算)

这里的output不是概率,是评估分数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加如下代码:

#CROSSENTROPYLOSS(交叉熵)
x = torch.tensor([0.1,0.2,0.3])
y = torch.tensor([1])
x = torch.reshape(x,(1,3))#把x变成交叉熵要求的input格式(N,C)N为batch_size,C为类别数
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x,y)
print(result_cross)

image-20240814002437691

结果:

tensor(1.1019)

4.如何在之前写的神经网络中用到 Loss Function(损失函数)

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

dataset = torchvision.datasets.CIFAR10("./dataset", 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为input
        x = self.model1(x)
        return x

loss = nn.CrossEntropyLoss()

tudui = Tudui()

for data in dataloader:
    imgs, targets = data  # imgs为输入,放入神经网络中
    outputs = tudui(imgs)  # outputs为输入通过神经网络得到的输出,targets为实际输出
    result_loss = loss(outputs, targets)
    print(result_loss)  # 神经网络输出与真实输出的误差

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.backward 反向传播

计算出每一个节点参数的梯度

在上述代码result_loss = loss(outputs, targets)后加一行:

result_loss.backward()  # backward反向传播,是对计算出来的result_loss,而不是对loss

在这一句代码前打上断点(运行到该行代码的前一行,该行不运行),debug 后:
image-20240814005237143

tudui ——> model 1 ——> Protected Attributes ——> _modules ——> ‘0’ ——> bias / weight——> grad(是None)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击Step into My Code,运行完该行后,可以发现刚刚的None有值了(损失函数一定要经过 .backward() 后才能反向传播,才能有每个需要调节的参数的grad的值)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一节:选择合适的优化器,利用梯度对网络中的参数进行优化更新,以达到整个 loss最低的目的

one)

[外链图片转存中…(img-o6bLsm5T-1724861861970)]

点击Step into My Code,运行完该行后,可以发现刚刚的None有值了(损失函数一定要经过 .backward() 后才能反向传播,才能有每个需要调节的参数的grad的值)

[外链图片转存中…(img-KvOrYXrm-1724861861970)]

下一节:选择合适的优化器,利用梯度对网络中的参数进行优化更新,以达到整个 loss最低的目的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值