Pytorch深度学习-----损失函数(L1Loss、MSELoss、CrossEntropyLoss)

系列文章目录

PyTorch深度学习——Anaconda和PyTorch安装
Pytorch深度学习-----数据模块Dataset类
Pytorch深度学习------TensorBoard的使用
Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Compose,RandomCrop)
Pytorch深度学习------torchvision中dataset数据集的使用(CIFAR10)
Pytorch深度学习-----DataLoader的用法
Pytorch深度学习-----神经网络的基本骨架-nn.Module的使用
Pytorch深度学习-----神经网络的卷积操作
Pytorch深度学习-----神经网络之卷积层用法详解
Pytorch深度学习-----神经网络之池化层用法详解及其最大池化的使用
Pytorch深度学习-----神经网络之非线性激活的使用(ReLu、Sigmoid)
Pytorch深度学习-----神经网络之线性层用法
Pytorch深度学习-----神经网络之Sequential的详细使用及实战详解


文章目录

  • 系列文章目录
  • 一、损失函数是什么?
    • 1.常见的损失函数及其解释
    • 2.实战
      • 2.1. 范数损失L1 Loss
      • 2.2. 均方误差损失MSE Loss
      • 2.3. 交叉熵损失CrossEntropyLoss
    • 3.在神经网络模型中使用交叉熵损失函数


一、损失函数是什么?

在PyTorch深度学习中,损失函数(Loss Function)是一个用于计算模型预测输出和实际输出之间的误差的函数。它用于衡量模型的性能,并通过反向传播算法更新模型的权重和参数,以减小预测输出和实际输出之间的误差

1.常见的损失函数及其解释

均方误差损失(MSE Loss): MSE Loss是一种常用于回归问题的损失函数。它计算预测输出和实际输出之间的均方误差,即预测值与实际值之差的平方的平均值。MSE Loss对于数据的高斯分布假设较为合理,适用于预测连续变量的任务。

交叉熵损失(Cross-Entropy Loss): 交叉熵损失是一种常用于分类问题的损失函数。它衡量的是两个概率分布之间的差异。在PyTorch中,可以使用torch.nn.CrossEntropyLoss来实现交叉熵损失。这个类结合了LogSoftmax和NLLLoss(负对数似然损失)两个操作,使得模型在训练时更加高效。交叉熵损失对于数据的伯努利分布假设较为合理,适用于分类任务。

L1范数损失(L1 Loss): L1 Loss计算预测输出和实际输出之间的绝对值差值的平均值。相比MSE Loss,L1 Loss对异常值不敏感,因此在处理存在异常值的数据集时可能更加适合。L1 Loss也被称为Mean Absolute Error (MAE)。

Softmax交叉熵损失(Softmax Cross-Entropy Loss): Softmax交叉熵损失是用于多分类任务的损失函数。它首先将模型的输出通过Softmax函数转换成概率分布,然后计算该分布与实际分布之间的交叉熵损失。这个损失函数可以用于解决多分类问题。

官网中关于损失函数(部分)如下图所示
在这里插入图片描述

2.实战

2.1. 范数损失L1 Loss

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

参数解释:

size_average(可选,默认为 None):这是一个布尔值或整数,用于指定是否对所有输入批次的输出进行平均。如果设置为 True,则对所有输入批次的输出进行平均。如果设置为整数 n,则对前 n 个输入批次的输出进行平均。如果设置为 None,则根据 reduce 参数的值决定是否进行平均。

reduce(可选,默认为 None):这是一个布尔值,用于指定是否对输入批次的输出进行减少。如果设置为 True,则对输入批次的输出进行减少,返回一个标量。如果设置为 False,则返回每个输入批次的输出的张量。如果 size_average 和 reduce 都为 None,则根据 reduction 参数的值决定是否进行减少和平均。

reduction(可选,默认为 ‘mean’):这是一个字符串,用于指定如何对输入批次的输出进行减少。可选的值有 ‘mean’、‘sum’ 和 ‘none’。如果设置为 ‘mean’,则对输入批次的输出进行平均。如果设置为 ‘sum’,则对输入批次的输出求和。如果设置为 ‘none’,则不进行减少,返回每个输入批次的输出的张量。

计算公式:
即平均绝对误差
在这里插入图片描述
代码实践

import torch
# 实例化
criterion1 = torch.nn.L1Loss()
criterion2 = torch.nn.L1Loss(reduction="sum")
# 实际输出值
output = torch.tensor([1.0, 2.0, 3.0])
# 目标值
target = torch.tensor([2.0, 2.0, 2.0])
# 平均值损失值
loss = criterion1(output, target)
print(loss)  # 输出:tensor(0.6667)
# 误差和
loss1 = criterion2(output,target)
print(loss1) # tensor(2.)

即( (2-1)+(2-2)+(3-2))/3=2/3=0.6667

2.2. 均方误差损失MSE Loss

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

参数解释
size_average(可选,默认为 None):这是一个布尔值或整数,用于指定是否对所有输入批次的输出进行平均。如果设置为 True,则对所有输入批次的输出进行平均。如果设置为整数 n,则对前 n 个输入批次的输出进行平均。如果设置为 None,则根据 reduce 参数的值决定是否进行平均。

reduce(可选,默认为 None):这是一个布尔值,用于指定是否对输入批次的输出进行减少。如果设置为 True,则对输入批次的输出进行减少,返回一个标量。如果设置为 False,则返回每个输入批次的输出的张量。如果 size_average 和 reduce 都为 None,则根据 reduction 参数的值决定是否进行减少和平均。

reduction(可选,默认为 ‘mean’):这是一个字符串,用于指定如何对输入批次的输出进行减少。可选的值有 ‘mean’、‘sum’ 和 ‘none’。如果设置为 ‘mean’,则对输入批次的输出进行平均。如果设置为 ‘sum’,则对输入批次的输出求和。如果设置为 ‘none’,则不进行减少,返回每个输入批次的输出的张量。

公式

在这里插入图片描述

代码实践

import torch
# 实例化
criterion1 = torch.nn.MSELoss()
criterion2 = torch.nn.MSELoss(reduction="sum")
# 实际输出值
output = torch.tensor([1.0, 2.0, 5.0])
# 目标值
target = torch.tensor([2.0, 2.0, 2.0])
# 平方值损失值
loss = criterion1(output, target)
print(loss)  # 输出:tensor(3.3333)
# 误差和
loss1 = criterion2(output,target)
print(loss1) # tensor(10.)

即:((2-1)2+(2-2)2+(5-2)2)/3=10/3=3.333
若reduction="sum"即取差值的平方和。

2.3. 交叉熵损失CrossEntropyLoss

torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean', label_smoothing=0.0)

参数解释

weight:一个可选的 tensor,用于对每个类别的损失进行加权。这个张量的轴应该与输出的张量轴匹配,且长度等于类别的数量。如果未提供,则使用均匀权重。

size_average:一个可选参数,决定如何计算批处理中损失函数的平均值。如果设置为 True,则对每个样本的损失进行平均。如果设置为 False,则返回每个样本的损失。如果未提供,则根据损失函数是否具有 reduce 属性来决定。

ignore_index:一个可选参数,指定应忽略哪些标签。默认情况下,忽略标签为 -100 的元素。

reduce:一个可选参数,决定是否对批处理中的损失进行汇总。如果设置为 True,则对批处理中的损失进行汇总。如果设置为 False,则返回每个样本的损失。如果未提供,则根据损失函数是否具有 reduce 属性来决定。

reduction:一个可选参数,用于指定如何对批处理中的损失进行汇总。默认情况下,对损失进行平均。其他可能的值包括 ‘mean’、‘sum’ 和 ‘none’。

label_smoothing:一个可选参数,指定标签平滑的强度。默认情况下,不进行标签平滑。该参数的值应该在 0 到 1 之间。

公式
在这里插入图片描述
其中log是以e为底,exp是指数函数
注意的点:
交叉熵损失函数在PyTorch中的输入要求如下:

输入x的形状为(batch_size, num_classes)或(num_classes,)。其中,batch_size代表批量大小,num_classes代表类别数量。
输入y的形状为(batch_size,),其中每个元素是对应样本的目标标签的索引值。

即为交叉熵损失函数的输入要求是一个二维张量,第一维是批次大小,第二维是类别数
代码实践

代码如下图所示:

import torch
import torch.nn as nn# 设置三分类问题,假设是人的概率是0.1,狗的概率是0.2,猫的概率是0.3
x = torch.tensor([0.1, 0.2, 0.3])
print(x)
y = torch.tensor([1]) # 设目标标签为1,即0.2狗对应的标签,目标标签张量y
x = torch.reshape(x, (1, 3))  # tensor([[0.1000, 0.2000, 0.3000]]),批次大小为1,分类数3,即为3分类
print(x)
print(y)
# 实例化对象
loss_cross = nn.CrossEntropyLoss()
# 计算结果
result_cross = loss_cross(x, y)
print(result_cross)

3.在神经网络模型中使用交叉熵损失函数

代码如下:

import torch
import torchvision
from torch.utils.data import DataLoader# 准备数据集
dataset = torchvision.datasets.CIFAR10(root="dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
# 数据集加载器
dataloader = DataLoader(dataset, batch_size=1)
"""
输入图像是3通道的32×32的,
先后经过卷积层(5×5的卷积核)、
最大池化层(2×2的池化核)、
卷积层(5×5的卷积核)、
最大池化层(2×2的池化核)、
卷积层(5×5的卷积核)、
最大池化层(2×2的池化核)、
拉直、
全连接层的处理,
最后输出的大小为10
"""
# 搭建神经网络
class Lgl(torch.nn.Module):def __init__(self):super(Lgl, self).__init__()self.conv1 = torch.nn.Conv2d(in_channels=3,out_channels=32,kernel_size=5,padding=2)self.maxpool1 = torch.nn.MaxPool2d(kernel_size=2)self.conv2 = torch.nn.Conv2d(in_channels=32,out_channels=32,kernel_size=5,padding=2)self.maxpool2 = torch.nn.MaxPool2d(kernel_size=2)self.conv3 = torch.nn.Conv2d(in_channels=32,out_channels=64,kernel_size=5,padding=2)self.maxpool3 = torch.nn.MaxPool2d(kernel_size=2)self.flatten = torch.nn.Flatten()self.linear1 = torch.nn.Linear(1024,64)self.linear2 = torch.nn.Linear(64, 10)def forward(self, x):x = self.conv1(x)x = self.maxpool1(x)x = self.conv2(x)x = self.maxpool2(x)x = self.conv3(x)x = self.maxpool3(x)x = self.flatten(x)x = self.linear1(x)x = self.linear2(x)return x
# 实例化
lgl = Lgl()
loss = torch.nn.CrossEntropyLoss()
# 对每一张图片进行CrossEntropyLoss损失函数计算
# 使用损失函数loss计算预测结果和目标标签之间的交叉熵损失
for data in dataloader:imgs, target = dataout = lgl(imgs)result = loss(out, target)print(result)

上述代码解读:

导入所需的库:

torch和torchvision库用于构建和训练神经网络。
DataLoader用于创建数据加载器,用于处理训练数据的批量加载。

准备数据集:

使用torchvision提供的datasets模块加载CIFAR-10数据集。
将数据集转换为张量类型,并准备为输入训练模型的形式。

搭建神经网络模型:

定义一个继承自nn.Module的类Lgl,表示我们的模型。
在构造函数__init__中,使用nn.Conv2d定义了三个卷积层和nn.Linear定义了两个全连接层。
在forward方法中,按顺序将输入数据传递给网络的各个层,通过卷积、池化和线性变换进行特征提取和分类。

实例化模型和损失函数:

创建一个Lgl类的实例lgl作为我们的模型。
创建一个CrossEntropyLoss类的实例loss作为我们的损失函数,用于计算预测结果和目标标签之间的交叉熵损失。

遍历数据集并进行计算:

使用数据加载器dataloader遍历准备好的数据集。
对于每个batch的数据,将输入图像传递给模型lgl进行前向传播计算,得到预测结果。
使用损失函数loss计算预测结果和目标标签之间的交叉熵损失。
打印输出的损失结果。

声明:本篇文章(包括本专栏所有文章),未经许可,谢绝转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/56421.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安全防护,保障企业图文档安全的有效方法

随着企业现在数据量的不断增加和数据泄露事件的频发,图文档的安全性成为了企业必须高度关注的问题。传统的纸质文件存储方式已不适应现代企业的需求,而在线图文档管理成为了更加安全可靠的数字化解决方案。那么在在线图文档管理中,如何采取有…

小研究 - MySQL 数据库下存储过程的综合运用研究

信息系统工程领域对数据安全的要求比较高,MySQL 数据库管理系统普遍应用于各种信息系统应用软件的开发之中,而角色与权限设计不仅关乎数据库中数据保密性的性能高低,也关系到用户使用数据库的最低要求。在对数据库的安全性进行设计时&#xf…

软件工程专业应该学什么?

昨天,我朋友的孩子报考了软件工程专业,问我软件工程到底学啥?所以我给他开列了一个书单。 现在高校开了一堆花名头的专业: 偏技术类:云计算、大数据、人工智能、物联网 偏应用类:电子商务、信息管理 但我个…

AI 绘画Stable Diffusion 研究(六)sd提示词插件

大家好,我是风雨无阻。 今天为大家推荐一款可以有效提升我们使用 Stable Diffusion WebUI 效率的插件, 它就是 prompt-all-in-one, 它不但能直接将 WebUI 中的中文提示词转换为英文,还能一键为关键词加权重,更能建立常…

【网络编程】利用套接字实现一个简单的网络通信(UDP实现聊天室 附上源码)

网络编程套接字 🐛预备知识🦋理解源IP地址和目的IP地址🐌认识端口号🐞 理解 "端口号" 和 "进程ID"🐜简单认识TCP协议🦟简单认识UDP协议🦗 什么是网络字节序 🕷相…

opencv36-形态学操作-膨胀 cv2.dilate()

膨胀操作是形态学中另外一种基本的操作。膨胀操作和腐蚀操作的作用是相反的,膨胀操作能对图像的边界进行扩张。膨胀操作将与当前对象(前景)接触到的背景点合并到当前对象内,从而实现将图像的边界点向外扩张。如果图像内两个对象的…

替换开源LDAP,某科技企业用宁盾目录统一身份,为业务敏捷提供支撑

客户介绍 某高科技企业成立于2015年,是一家深耕于大物流领域的人工智能公司,迄今为止已为全球16个国家和地区,120余家客户打造智能化升级体验,场景覆盖海陆空铁、工厂等货运物流领域。 该公司使用开源LDAP面临的挑战 挑战1 开源…

读取文件和写入文件操作

在java中会涉及到对文件进行读取和写入操作,以下将介绍如何用java对文件进行读取和写入 读取 通过Readr读取字符流文件中的数据 读取字符流文件中的数据表示以字符为单位进行读取 package 文件操作;import java.io.*;/*** Created with IntelliJ IDEA.* Descript…

ubuntu调整路由顺序

Ubuntu系统跳转路由顺序 1、安装ifmetric sudo apt install ifmetric2、查看路由 route -n3、把Iface下面的eth1调到第一位 sudo ifmetric eth1 0命令中eth1是网卡的名称,更改网卡eth1的跃点数(metric值)为0(数值越小&#xf…

Spring Boot集成Mybatis-Plus

Spring Boot集成Mybatis-Plus 1. pom.xml导包 <!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mysql驱动--><dependency><groupId>mysql<…

【排序算法】python之冒泡,选择,插入,快速,归并

参考资料&#xff1a; 《Python实现5大排序算法》《六大排序算法&#xff1a;插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序》 --代码似乎是C语言 ———————— 本文介绍5种常见的排序算法和基于Python实现&#xff1a; 冒泡排序&#xff08;Bubble Sort&am…

【C++】哈希开散列 | unordered系列容器的封装

文章目录 一.开散列1. 开散列的概念2. 开散列结构3. Insert 插入4. Find 查找5. Insert 扩容6. Erase 删除7. 析构函数8. 其它函数接口9. 性能测试 二.封装1. 封装内部结构2. 实现接口 三.代器器1. 迭代器的定义2. 常用接口3. 迭代器4. begin()、end()5. find的改动6. 下标访问…