Pytorch基础应用

1.数据加载

1.1 读取文本文件

  • 方法一:使用 open() 函数和 read() 方法
# 打开文件并读取全部内容
file_path = 'example.txt'  # 替换为你的文件路径
with open(file_path, 'r') as file:content = file.read()print(content)
  • 方法二:逐行读取文件内容
# 逐行读取文件内容
file_path = 'example.txt'  # 替换为你的文件路径
with open(file_path, 'r') as file:for line in file:print(line.strip())  # strip() 方法用于去除行末尾的换行符
  • 方法三:指定编码读取文件内容(如果文本文件不是UTF-8编码)
# 指定编码读取文件内容
file_path = 'example.txt'  # 替换为你的文件路径
with open(file_path, 'r', encoding='utf-8') as file:content = file.read()print(content)
  • 方法四:一次读取多行内容
# 一次读取多行内容
file_path = 'example.txt'  # 替换为你的文件路径
with open(file_path, 'r') as file:lines = file.readlines()for line in lines:print(line.strip())  # strip() 方法用于去除行末尾的换行符

1.2 读取图片

  • 使用Pillow(PIL)库

安装了Pillow库:pip install Pillow

from PIL import Image# 打开图片文件
img = Image.open('example.jpg')  # 替换成你的图片文件路径# 显示图片信息
print("图片格式:", img.format)
print("图片大小:", img.size)
print("图片模式:", img.mode)# 显示图片
img.show()# 转换为numpy数组(如果需要在其他库中处理图像)
import numpy as np
img_array = np.array(img)
  • 使用OpenCV库
    安装OpenCV库:pip install opencv-python
import cv2# 读取图片
img = cv2.imread('example.jpg')  # 替换成你的图片文件路径# 显示图片信息
print("图片尺寸:", img.shape)  # 高度、宽度、通道数(rgb默认是3)
print("像素值范围:", img.dtype)  # 数据类型(像素值类型)# 可选:显示图片(OpenCV中显示图像的方法)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()# 可选:将BGR格式转换为RGB格式
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 可选:保存图片
cv2.imwrite('output.jpg', img)
  • 应用
# 继承Dataset类
class MyData(Dataset):# 初始化def __init__(self, root_dir, image_dir, label_dir):# root_dir 训练目录地址self.root_dir = root_dir# 图片地址self.image_dir = image_dir# label_dir 标签地址self.label_dir = label_dir# 训练样本地址self.path = os.path.join(self.root_dir, self.image_dir)# 将所有样本地址(名称)变成一个列表self.img_path = os.listdir(self.path)# 读取图片,并且对应label# idx 图片下标def __getitem__(self, idx):# 图片名称img_name = self.img_path[idx]# 图片路径img_item_path = os.path.join(self.path, img_name)# 获取图片img = Image.open(img_item_path)# 打开文件并读取全部内容(文件存取对应样本的标签)file_path = os.path.join(self.root_dir, self.label_dir, img_name.split('.jpg')[0])with open(file_path + ".txt", 'r') as file:label = file.read()# 获取标签return img, label# 训练样本长度def __len__(self):return len(self.img_path)root_dir = "hymenoptera_data/train"
ants_image_dir = "ants_image"
ants_label_dir = "ants_label"
bees_image_dir = "bees_image"
bees_label_dir = "bees_label"
ants_dataset = MyData(root_dir, ants_image_dir, ants_label_dir)
img, label = ants_dataset[0]  # 返回数据集第一个样本的图片和标签
img.show()  # 展示图片
bees_dataset = MyData(root_dir, bees_image_dir, bees_label_dir)
import cv2
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Imageimg_path = "dataset/train/ants_image/0013035.jpg"
# 打开图片
img = Image.open(img_path)# 利用cv2打开图片,直接是ndarray格式
img_cv2 = cv2.imread(img_path)print(img_cv2)write = SummaryWriter('logs')# 创建一个ToTensor的对象(PIL Image or ndarray to tensor)
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
print(tensor_img)

1.3 数据可视化(TensorBoard)

SummaryWriter 是 TensorBoard 的日志编写器,用于创建可视化和跟踪模型训练过程中的指标和结果。它通常用于记录模型的训练损失、准确率、权重分布、梯度分布等信息,方便后续在 TensorBoard 中进行可视化分析。

import torch
from torch.utils.tensorboard import SummaryWriter# 创建一个 SummaryWriter 对象,指定保存日志的路径
writer = SummaryWriter('logs')# 示例:记录模型的训练过程中的损失值和准确率
for step in range(100):# 模拟训练过程中的损失值和准确率loss = 0.4 * (100 - step) + torch.rand(1).item()accuracy = 0.6 * (step / 100) + torch.rand(1).item()# 将损失值和准确率写入日志writer.add_scalar('Loss/train', loss, step)writer.add_scalar('Accuracy/train', accuracy, step)# 关闭 SummaryWriter
writer.close()

首先,我们导入了需要的库,包括 PyTorch 和 SummaryWriter。
然后,创建了一个 SummaryWriter 对象,并指定了保存日志的路径 ‘logs’。
在模拟的训练过程中,我们循环了 100 步,每一步模拟生成一个损失值和准确率。
使用 writer.add_scalar 方法将每一步的损失值和准确率写入日志。这些信息将被保存在指定的日志路径中,以便后续在 TensorBoard 中进行查看和分析。
最后,使用 writer.close() 关闭 SummaryWriter,确保日志写入完成并正确保存。

  • SummaryWriter 对象的 add_scalar 方法用于向 TensorBoard 日志中添加标量数据,例如损失值、准确率等。这些标量数据通常用于跟踪模型训练过程中的指标变化。

add_scalar 方法的参数说明:add_scalar(tag, scalar_value, global_step=None, walltime=None)
tag (str):用于标识数据的名称,将作为 TensorBoard 中的图表的名称显示。
scalar_value (float):要记录的标量数据,通常是一个数值。
global_step (int, optional):可选参数,表示记录数据的全局步骤数。主要用于绘制图表时在 x 轴上显示步骤数,方便对训练过程进行时间序列分析。
walltime (float, optional):可选参数,表示记录数据的时间戳。默认情况下,使用当前时间戳。

  • add_image 函数用于向 TensorBoard 日志中添加图像数据,这对于监视模型输入、输出或中间层的可视化非常有用。

add_image 方法的参数说明:add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')
tag (str):用于标识图像的名称,将作为 TensorBoard 中图像的名称显示。
img_tensor (Tensor or numpy.array):要记录的图像数据,可以是 PyTorch 的 Tensor 对象或者 numpy 数组。如果是 numpy 数组,会自动转换为 Tensor。
global_step (int, optional):可选参数,表示记录数据的全局步骤数。主要用于在 TensorBoard 中按时间显示图像。
walltime (float, optional):可选参数,表示记录数据的时间戳。默认情况下,使用当前时间戳。
dataformats (str, optional):可选参数,指定图像的数据格式。默认为 ‘CHW’,即通道-高度-宽度的顺序。

启动命令:tensorboard --logdir 文件路径

1.4 Transforms

transforms.py 文件通常是指用于进行数据预处理和数据增强的模块。这个模块通常用于处理图像数据,包括但不限于加载、转换、裁剪、标准化等操作,以便将数据准备好用于模型的训练或评估。

常见的 transforms.py 功能包括:

  • 数据加载和预处理:
    读取图像数据并转换为 PyTorch 的 Tensor 格式。
    对图像进行大小调整、裁剪、旋转、镜像翻转等操作。
    将图像数据标准化为特定的均值和标准差。
  • 数据增强:
    随机裁剪和大小调整,以增加训练数据的多样性。
    随机水平或垂直翻转图像。
    添加噪声或扭曲以增加数据的多样性。
  • 转换为 Tensor:
    将 PIL 图像或 numpy 数组转换为 PyTorch 的 Tensor 格式。
    对图像数据进行归一化,例如将像素值缩放到 [0, 1] 或 [-1, 1] 之间。
  • 组合多个转换操作:
    将多个转换操作组合成一个流水线,可以顺序应用到图像数据上。
  • 实时数据增强:
    在每次训练迭代中实时生成增强后的数据,而不是预先对所有数据进行转换。
import torch
from torchvision import transforms
from PIL import Image# 示例图像路径
img_path = 'example.jpg'# 定义数据转换
data_transform = transforms.Compose([transforms.Resize((256, 256)),      # 调整图像大小为 256x256 像素transforms.RandomCrop(224),         # 随机裁剪为 224x224 像素transforms.RandomHorizontalFlip(),  # 随机水平翻转图像transforms.ToTensor(),              # 将图像转换为 Tensor,并归一化至 [0, 1]transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 标准化
])# 加载并预处理图像
img = Image.open(img_path)
img_transformed = data_transform(img)# 打印转换后的图像形状和数据类型
print("Transformed image shape:", img_transformed.shape)
print("Transformed image data type:", img_transformed.dtype)

1.首先,导入了必要的库和模块,包括 PyTorch 的 transforms 模块、PIL 库中的 Image。
定义了一个 transforms.Compose 对象 data_transform,它是一个包含多个转换操作的列表,按顺序应用到输入数据上。
2.示例中的转换操作包括将图像调整为指定大小、随机裁剪为 224x224 像素、随机水平翻转、转换为 PyTorch 的 Tensor 对象,并进行归一化。
3.加载示例图像,并将 data_transform 应用到图像上,得到转换后的图像数据 img_transformed。
4.最后,打印转换后的图像形状和数据类型,以确保转换操作正确应用。

transforms.Normalize(mean, std, inplace=False)

Normalize 类用于对图像数据进行标准化操作。标准化是一种常见的数据预处理步骤,通常用于将数据缩放到一个较小的范围,以便于模型训练的稳定性和收敛速度。在图像处理中,Normalize 类主要用于将图像的每个通道进行均值和标准差的归一化处理

  1. mean:用于归一化的均值。可以是一个列表或元组,每个元素分别对应于图像的每个通道的均值。例如 [mean_channel1, mean_channel2, mean_channel3]。
  2. std:用于归一化的标准差。同样是一个列表或元组,每个元素对应于图像的每个通道的标准差。例如 [std_channel1, std_channel2, std_channel3]。
  3. inplace:是否原地操作。默认为 False,表示会返回一个新的标准化后的图像。如果设置为 True,则会直接修改输入的 Tensor。

Compose类
transforms.Compose(transforms)
transforms:一个由 torchvision.transforms 中的转换操作组成的列表或序列,每个操作会依次应用到输入数据上。

1.5 torchvision.datasets

PyTorch 中用于加载和处理常见视觉数据集的模块。这个模块提供了对多种经典数据集的访问接口,包括图像分类、物体检测、语义分割等任务常用的数据集。

  • 数据集加载:
    torchvision.datasets 提供了方便的接口,可以直接从互联网下载和加载常用的数据集,例如 MNIST、CIFAR-10、ImageNet 等。
  • 数据预处理:
    支持在加载数据集时进行数据预处理,例如图像大小调整、裁剪、翻转、归一化等操作,这些操作可以通过 transforms 模块进行定义和组合。
  • 数据集管理:
    提供了便捷的方法来管理和访问数据集,例如对数据集进行随机访问、按照批次加载数据等,以支持机器学习模型的训练和评估。
  • 多样的数据集支持:
    支持多种类型的数据集,包括但不限于分类数据集(如 MNIST、CIFAR-10)、检测数据集(如 COCO)、语义分割数据集(如 Pascal VOC)等,适用于不同的视觉任务。
# 以CIFAR-10为例
import torchvision.transforms as transforms
import torchvision.datasets as datasets# 定义数据预处理
transform = transforms.Compose([transforms.Resize(224),transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])# 加载数据集
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)# 获取数据集中的样本数量
print("Training dataset size:", len(train_dataset))
print("Test dataset size:", len(test_dataset))# 使用 DataLoader 加载数据
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)

使用 datasets.CIFAR10 加载 CIFAR-10 数据集
指定了数据集存储的根目录 root、是否为训练集 train=True、是否下载数据集 download=True、以及预处理管道 transform。
datasets.CIFAR10 返回一个 torch.utils.data.Dataset 对象,可以像常规 Python 的列表一样进行索引和切片操作。

1.6 DataLoader

DataLoader 是 PyTorch 中用于批量加载数据的重要工具

  • 数据加载:
    DataLoader 可以加载 Dataset 对象中的数据,并将其组织成小批量。这些数据可以是图像、文本、数值数据等。
  • 批量处理:
    DataLoader 支持对数据进行批处理,即一次性加载和处理多个样本。这样可以提高训练效率,尤其是在 GPU 计算的情况下。
  • 数据打乱:
    通过设置 shuffle=True 参数,DataLoader 可以在每个 epoch 开始时对数据进行打乱,这有助于增加数据的随机性,防止模型陷入局部极值。
  • 多进程加载:
    DataLoader 支持使用多个子进程来并行加载数据,这可以显著提升数据加载速度,特别是在数据集很大时。
  • 数据采样:
    可以使用 sampler 参数来指定数据的采样方法,例如随机采样、顺序采样等。默认情况下,使用的是 SequentialSampler,即顺序采样。
  • 数据批处理方式:
    可以设置 batch_size 参数指定每个小批量的样本数目。
  • 自定义数据加载:
    可以通过设置 collate_fn 参数来指定如何将样本数据拼接成小批量,通常情况下,PyTorch 提供了默认的拼接方式,但是有时候用户可能需要根据自己的需求来自定义拼接过程。
  • 数据传输到 GPU:
    当数据加载到 DataLoader 后,可以方便地将其传输到 GPU 上进行计算,这样可以利用 GPU 的并行计算能力加速模型训练。

dataset:
这是必需的参数,指定要加载的数据集 Dataset 对象。
batch_size:
指定每个小批量包含的样本数目。例如,batch_size=64 表示每个小批量包含 64 个样本。训练时常用的批量大小通常是 2 的幂次方,以便能够充分利用 GPU 的并行计算能力。
shuffle:
设置为 True 表示每个 epoch 开始时都会对数据进行重新打乱(随机采样)。这样可以增加数据的随机性,有助于模型更好地学习数据的分布,避免模型陷入局部极值。
sampler:
可选参数,用于指定数据采样策略。默认情况下,如果不指定这个参数,将使用 SequentialSampler,即顺序采样。也可以自定义 Sampler 对象,实现自定义的采样逻辑。
batch_sampler:
可选参数,如果指定了这个参数,则会覆盖 batch_size 和 shuffle 参数。它
num_workers:
表示用于数据加载的子进程数目。可以通过增加子进程数来加速数据加载,特别是当主机有多个 CPU 核心时。通常建议设置为 num_workers > 0
collate_fn:
可选参数,用于指定如何将样本列表拼接成小批量。默认情况下,PyTorch 使用 default_collate 函数来执行标准的张量拼接操作。
pin_memory:
如果设置为 True,则会将加载的数据存储在 CUDA 固定内存中,这样可以加速数据传输到 GPU。在使用 GPU 训练模型时,建议设置为 True。
drop_last:
如果数据集的样本总数不能被 batch_size 整除,设置为 True 将会丢弃最后一个不完整的批次。如果设置为 False,则最后一个批次的样本数目可能会少于 batch_size。

import torch
from torch.utils.data import Dataset, DataLoader# 定义一个简单的数据集类
class MyDataset(Dataset):def __init__(self):self.data = torch.randn(100, 3, 32, 32)  # 假设有 100 个大小为 3x32x32 的张量数据def __len__(self):return len(self.data)def __getitem__(self, idx):return self.data[idx]# 创建数据集实例
dataset = MyDataset()# 创建 DataLoader 实例
batch_size = 16
train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)# 迭代数据集
for batch_idx, batch_data in enumerate(train_loader):inputs = batch_data  # 输入数据targets = batch_data  # 如果有标签,也可以在此处获取# 在这里添加训练代码...

在上述示例中,首先定义了一个简单的数据集类 MyDataset,它生成了包含 100 个大小为 3x32x32 的张量数据。然后,通过 DataLoader 将这个数据集加载为 train_loader,并设置了批量大小为 16,并且打乱了数据顺序。最后,在迭代 train_loader 中的小批量数据时,可以获取到每个小批量的输入数据 inputs,并在训练过程中使用。

2.构建模型

神经网络输入和输出参数数据格式
输入输出的张量,通常是一个四维张量,形状为 (N, C, H, W),其中:
N 表示批处理大小(batch size),
C 表示输入输出通道数(input channels),
H 表示输入输出的高度(input height),
W 表示输入输出的宽度(input width)。

2.1 nn.Module

PyTorch 中的一个核心类,用于构建神经网络模型。

  • 模型组件封装:
    nn.Module 是所有神经网络模型的基类,可以通过继承它来定义自己的神经网络模型。
    它提供了模型组件的封装和管理机制,使得模型的构建和维护更加清晰和结构化。

  • 参数管理:
    模型内部的所有参数(权重和偏置)都由 nn.Module 对象管理。
    通过模型的 parameters() 方法可以轻松地访问和管理所有模型参数,便于参数初始化、优化器更新等操作。

  • 前向传播定义:
    模型的前向传播逻辑都在 forward() 方法中定义。
    重写 forward() 方法可以定义模型的计算图,指定输入数据如何通过各个层进行前向传播,从而计算出输出。

  • 反向传播支持:
    nn.Module 支持自动求导功能,因此可以利用 PyTorch 提供的自动求导机制进行反向传播和梯度计算。
    这使得模型的训练过程可以高效地优化模型参数。

  • 子模块管理:
    nn.Module 支持将多个子模块组合成一个大模型。
    通过在 init 方法中初始化其他 nn.Module 的子类对象,可以构建复杂的神经网络结构,实现模块化设计。

  • 状态管理:
    nn.Module 不仅管理模型参数,还负责管理模型的状态(如 train() 和 eval() 方法控制模型的训练和评估状态)。
    这些状态管理方法在模型训练、验证和测试时非常有用。

  • 设备适配:
    通过 to() 方法,nn.Module 支持简单地将模型移动到 GPU 或者其他计算设备上进行加速计算,提高训练和推理的效率。

class MyModule(nn.Module):def __init__(self):super().__init__()def forward(self, input):output = input + 1return outputmymodule = MyModule()
x = torch.tensor(1.0)
y = mymodule(x)
print(y)

2.2 nn.Conv2d

PyTorch 中用于定义二维卷积层的类。它是 nn.Module 的子类,用于构建卷积神经网络中的卷积操作。
卷积原理
卷积原理
含填充
多卷积核

参数介绍:
nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)

in_channels
表示输入的通道数,对于灰度图像,通道数为 1;对于彩色图像,通道数为 3(分别是红、绿、蓝)。
out_channels:(每个卷积核生成一个特征图作为输出)
表示输出的通道数,也就是卷积核的数量,每个卷积核生成一个特征图作为输出。通常情况下,输出通道数决定了下一层的输入通道数。
kernel_size
卷积核的大小,可以是一个整数或者一个元组(如 (3, 3))。整数表示正方形卷积核的边长,元组则表示非正方形卷积核的形状。
stride
卷积操作的步幅,即卷积核在输入上滑动的步长。可以是一个整数或者一个元组。默认为 1,表示卷积核每次滑动一个像素;
可以设定为大于 1 的整数,以减少输出特征图的尺寸。
padding
输入的每一条边补充 0 的层数。可以是一个整数或一个元组。添加 padding 可以帮助保持特征图大小,避免在卷积过程中信息损失过多。
dilation
空洞卷积的扩展因子,控制卷积核元素之间的间距。默认为 1,表示卷积核内的每个元素之间都是连续的;
大于 1 的值将导致空洞卷积,可以增加感受野。
groups
输入和输出之间连接的组数。默认为 1,表示所有输入通道和输出通道之间都有连接;可以设置为其他值,以实现分组卷积操作。
bias
是否添加偏置。默认为 True,表示在卷积后加上偏置项;如果设置为 False,则卷积层不会有额外的偏置。

import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterclass MyConv2d(nn.Module):def __init__(self):super(MyConv2d, self).__init__()# 定义卷积层self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)def forward(self, x):outputs = self.conv1(x)return outputstest_data = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(),download=True)
test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=True)
write = SummaryWriter(log_dir='./logs')my_conv = MyConv2d()step = 1
# 遍历数据
for data in test_loader:# 每个批次的图片及便签imgs, targets = dataoutputs = my_conv(imgs)print(imgs.shape)  # torch.Size([64, 3, 32, 32]) 批量64 输入通道3(RGB彩色) 图片大小32*32print(outputs.shape)  # torch.Size([64, 6, 30, 30]) 批量64 输出通道6 图片大小30*30# 根据输入的卷积参数计算卷积后图片大小的方法见官网# https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2dwrite.add_images("imgs", imgs, step)# 由于outputs.shape = [64, 6, 30, 30]   输出通道6  RGB为3 无法构建图像,利用reshape变化格式outputs = torch.reshape(outputs, (-1, 3, 30, 30))  # 不确定的维度用-1自动填充write.add_images("outputs", outputs, step)step += 1
write.close()

卷积后的图像

2.3 MaxPool2d

PyTorch 中用于执行二维最大池化(Max Pooling)操作的类。它通常用于卷积神经网络(CNN)中,用于减少特征图的空间维度,从而减少模型的参数数量,降低过拟合风险,并提高计算效率。
最大池化层原理

在这里插入图片描述

MaxPool2d 的主要参数
kernel_size (int 或 tuple)
池化窗口的大小。可以是一个整数,例如 kernel_size=2,表示窗口的高度和宽度都是 2;也可以是一个长度为 2 的元组 (kernel_height, kernel_width),例如 kernel_size=(2, 2)。
stride (int 或 tuple, optional)
池化操作的步幅。可以是一个整数,例如 stride=2,表示在高度和宽度方向上的步幅都是 2;也可以是一个长度为 2 的元组 (stride_height, stride_width),例如 stride=(2, 2)。默认值是 kernel_size。
padding (int 或 tuple, optional)
输入的每条边补充0的层数。可以是一个整数,例如 padding=1,也可以是一个长度为 2 的元组 (padding_height, padding_width),例如 padding=(1, 1)。默认值是 0,即不填充。
dilation (int 或 tuple, optional)
池化核元素之间的间距。可以是一个整数,例如 dilation=1,也可以是一个长度为 2 的元组 (dilation_height, dilation_width),例如 dilation=(2, 2)。默认值是 1,即没有间距。
return_indices (bool, optional)
如果设置为 True,则返回输出中每个最大值的索引。默认为 False。
ceil_mode (bool, optional)
如果设置为 True,则使用 ceil 而不是 floor 计算输出形状。默认为 False。

import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterdataset = torchvision.datasets.CIFAR10(root='./dataset', train=False,transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)class MyPool(torch.nn.Module):def __init__(self):super(MyPool, self).__init__()self.pool = torch.nn.MaxPool2d(kernel_size=3,ceil_mode=True)def forward(self, x):return self.pool(x)my_pool = MyPool()
write = SummaryWriter(log_dir='./logs')
step = 1
for data in dataloader:imgs, labels = datawrite.add_images("imgs",imgs,step)outputs = my_pool(imgs)write.add_images("MaxPool2d",outputs,step)step += 1
write.close()

最大池化层

2.4 ReLU

ReLU(Rectified Linear Unit)是深度学习中常用的一种激活函数,用于增加神经网络的非线性特性。ReLU 的输出对于负值是零,这意味着在训练过程中,神经元可以学习更加稀疏的表示,从而减少了过拟合的可能性。
在这里插入图片描述

import torch
from torch import nninput = torch.tensor([[1, -0.5],[-5, 8]])
"""
myrelu = nn.ReLU()
output = myrelu(input)
"""
class myReLU(nn.Module):def __init__(self):super(myReLU, self).__init__()self.relu = nn.ReLU()def forward(self, x):return self.relu(x)myrelu = myReLU()
output = myrelu(input)
print(output)

2.5 BatchNorm2d

PyTorch 中用于二维批量归一化操作的类。它在深度学习中广泛用于加速网络训练,并提高模型的收敛速度和稳定性。

  • 计算均值和方差:
    对每个通道,在一个 batch 的所有样本上分别计算均值和方差。
  • 归一化:
    使用计算得到的均值和方差对每个通道的特征图进行归一化,得到标准化的特征图。
  • 缩放和位移:
    引入可学习的参数 gamma(缩放因子)和 beta(位移参数),用于调整归一化后的特征图的分布,增加网络的表达能力。
  • 反向传播时的梯度更新:
    在训练过程中,BatchNorm2d 对归一化后的输出进行缩放和位移,这些参数会随着反向传播更新。

参数
num_features
说明:指定输入数据的特征数或通道数。对于二维卷积来说,通常是输出特征图的通道数。
示例:如果你的卷积层输出通道数是 16,则 num_features 应该设置为 16。
eps
说明:是一个小的数,用于防止除以零的情况。在归一化过程中,会将方差加上 eps,以确保数值稳定性。
示例:一般情况下,不需要手动调整这个值,使用默认值即可。
momentum
说明:用于计算运行均值和方差的动量。在训练过程中,当前的均值和方差会根据 momentum 更新到运行均值和方差中。
示例:通常情况下,使用默认值即可。较大的 momentum 表示更多的历史信息被保留,可以提高归一化的稳定性。
affine
说明:一个布尔值,用于指定是否应该学习 gamma 和 beta 参数。如果设置为 False,则 BatchNorm2d 只执行归一化,不学习额外的缩放和偏移参数。
示例:通常情况下,保持默认值,即学习 gamma 和 beta 参数。
track_running_stats
说明:一个布尔值,指定是否应该追踪运行时的均值和方差。如果设置为 True,则在训练过程中会计算并更新运行时的均值和方差;如果设置为 False,则使用批次内的均值和方差。
示例:通常情况下,保持默认值。但在某些情况下,如在推断时可以设置为 False,以减少内存占用和计算量。

import torch
import torch.nn as nn# 示例:创建一个卷积层,接着一个BatchNorm2d层,然后是ReLU激活函数# 假设输入特征图大小为 (N, C, H, W) = (1, 3, 32, 32)
input_tensor = torch.randn(1, 3, 32, 32)# 定义一个卷积层
conv_layer = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)# 添加BatchNorm2d层
# 注意:BatchNorm2d的num_features参数应该是卷积层输出的通道数,这里是16
batchnorm_layer = nn.BatchNorm2d(16)# 使用ReLU作为激活函数
relu = nn.ReLU()# 将输入通过卷积层、BatchNorm2d层和ReLU激活函数依次传递
output = conv_layer(input_tensor)
output = batchnorm_layer(output)
output = relu(output)
  1. nn.Conv2d 定义了一个卷积层,输入通道数为 3,输出通道数为 16。
  2. nn.BatchNorm2d 创建了一个 BatchNorm2d 层,它的 num_features 参数设置为卷积层输出的通道数(这里是 16)。
  3. nn.ReLU 是一个ReLU激活函数,用于增加网络的非线性特性。
  4. 输入通过卷积层、BatchNorm2d 层和ReLU激活函数的顺序传递,以形成网络的前向传播流程。

2.6 Linear

输入参数
in_features(一般需要展平,一维)
如果输入是一个大小为 10 的向量 (in_features=10),那么每个输入样本就有 10 个特征。
out_features
如果希望层的输出是大小为 5 的向量 (out_features=5),那么每个样本的输出就是一个大小为 5 的向量。
bias:
如果设置为 True,则层会学习一个可学习的偏置。如果设置为 False,则层不会学习额外的偏置项。
通常情况下会设置为 True,除非你特别希望从层中去除偏置。

import torch
import torchvision
from torch import nn
from torch.utils.tensorboard import SummaryWriterdataset = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataload = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True,drop_last=True)
class MyLinear(nn.Module):def __init__(self):super(MyLinear, self).__init__()self.linear = nn.Linear(in_features=196608, out_features=10)def forward(self, x):return self.linear(x)mylinear = MyLinear()for data in dataload:imgs, labels = data# [64, 3, 32, 32]->[1,1,1,196608]->[10]print(imgs.shape)# 将图片张量展平(一行) 作为in_featuresoutputs = torch.flatten(imgs)  # 或者outputs = torch.reshape(imgs,(1,1,1,-1))print(outputs.shape)# 传入linear层outputs = mylinear(outputs)print(outputs.shape)

2.7 Sequential

Sequential是一种模型的组织方式,特别适用于那些层按照顺序堆叠的简单模型。
Sequential 有时也指一种按照顺序处理数据的方法或工作流。

dataset = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataload = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True, drop_last=True)class MyNet(torch.nn.Module):def __init__(self):super(MyNet, self).__init__()self.conv1 = nn.Conv2d(3, 32, 5, padding=2)self.maxpool1 = nn.MaxPool2d(2)self.conv2 = nn.Conv2d(32, 32, 5, padding=2)self.maxpool2 = nn.MaxPool2d(2)self.conv3 = nn.Conv2d(32, 64, 5, padding=2)self.maxpool3 = nn.MaxPool2d(2)self.flatten = nn.Flatten()self.linear1 = nn.Linear(1024, 64)self.linear2 = 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# 利用Sequential
class MySeq(nn.Module):def __init__(self):super(MySeq, self).__init__()self.model1 = Sequential(nn.Conv2d(3, 32, 5, padding=2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, padding=2),nn.MaxPool2d(2),nn.Conv2d(32, 64, 5, padding=2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(1024, 64),nn.Linear(64, 10))def forward(self, x):x = self.model1(x)return xmynet = MyNet()
myseq = MySeq()
for data in dataload:imgs, labels = dataoutputs = mynet(imgs)outputs2 = myseq(imgs)print("test1:",end="")print(outputs.shape)print("test2:",end="")print(outputs2.shape)

3 损失函数

3.1 MSELoss

均方误差(MSE)损失是机器学习中常用的一种损失函数,特别适用于回归问题。使用MSE作为损失函数的目的是,对较大的误差进行更重的惩罚,而对较小的误差进行轻微的惩罚。通过平方差的方式实现了这一目的。
使用方法

  1. 准备数据:
    确保你有一个包含输入特征(例如房屋面积、股票历史数据等)和对应输出值(例如房价、股票价格等)的数据集。
  2. 定义模型:
    选择适当的机器学习模型,如线性回归、神经网络等,这取决于你的问题和数据。
  3. 选择优化算法:
    选择一个优化算法,比如梯度下降,用于调整模型参数以最小化MSE损失。
  4. 定义损失函数:
    在训练过程中,定义MSE损失函数。在大多数机器学习框架中,这通常是预先定义好的,你只需要选择并使用。
  5. 训练模型:
    将数据输入模型,通过反向传播算法优化模型参数,使得MSE损失逐步减小。
  6. 评估模型:
    在训练过程中和/或之后,使用验证集或测试集评估模型的性能。通常,计算预测值与真实值之间的MSE来衡量模型的准确性。
import torch
import torch.nn as nn
import torch.optim as optim# 假设有数据 X_train, y_train 作为训练集# 定义模型
class LinearRegression(nn.Module):def __init__(self, input_size, output_size):super(LinearRegression, self).__init__()self.linear = nn.Linear(input_size, output_size)def forward(self, x):return self.linear(x)# 设置模型参数
input_size = X_train.shape[1]  # 输入特征的大小
output_size = 1  # 输出为单个数值(房价)model = LinearRegression(input_size, output_size)# 定义损失函数和优化器
criterion = nn.MSELoss()  # 使用均方误差损失
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 使用随机梯度下降优化器# 训练模型
num_epochs = 100
for epoch in range(num_epochs):# 前向传播outputs = model(X_train)loss = criterion(outputs, y_train)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch+1) % 10 == 0:print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')# 模型训练完成,可以进行预测
with torch.no_grad():predicted = model(X_test)test_loss = criterion(predicted, y_test)print(f'Test MSE Loss: {test_loss.item():.4f}')
  • 我们定义了一个简单的线性回归模型。
  • 使用PyTorch中的nn.MSELoss()定义了MSE损失函数。
  • 使用随机梯度下降(SGD)作为优化器,通过反向传播算法来优化模型参数。
  • 训练模型并打印出每个epoch的训练损失。
  • 最后,用测试集评估模型的性能,计算测试集上的MSE损失。

3.2 CrossEntropyLoss

交叉熵损失是深度学习中常用的一种损失函数,特别适用于多类别分类任务。
在这里插入图片描述

参数:
Input: Shape(C)or (N,C)
C =number of classes
N = batch size

reduction:指定损失的计算方式,可以是’mean’(默认)、‘sum’或’none’

import torch
from torch import nn
"""
损失函数:
1.计算实际输出和目标之间的差距
2.为我们更新输出提供一定的依据(反向传播)
"""
input = torch.tensor([1.0, 2.0, 3.0])
target = torch.tensor([3.0, 2.0, 3.0])
# 批量维度 通道维度 宽度维度 高度维度
input = torch.reshape(input, (1, 1, 1, 3))
target = torch.reshape(target, (1, 1, 1, 3))loss = nn.MSELoss(reduction='mean')
result = loss(input, target)
print(result)x = torch.tensor([0.1, 0.2, 0.3])
y = torch.tensor([1])
x= torch.reshape(x, (1, 3)) # 1个样本,3个类别
cross_loss = nn.CrossEntropyLoss()
result = cross_loss(x, y)
print(result)

4 梯度优化

4.1 optim.SGD

PyTorch中用于实现随机梯度下降优化算法的类。

  • SGD是一种基本的优化算法,每次迭代都使用一小批次(batch)的数据来计算梯度和更新模型参数。
  • 它通过计算每个参数的梯度以及学习率来更新模型的权重,以减少损失函数的值。

参数
params:需要优化的参数列表。
lr:学习率,控制每次参数更新的步长大小。
momentum:动量因子,用于加速SGD在相关方向上前进,并减少摆动。
dampening:动量的抑制因子。
weight_decay:权重衰减(L2惩罚),用于对模型参数进行正则化。
nesterov:是否使用Nesterov动量。

import torch
import torchvision
from torch import nn
from torch.nn import Sequential
from torch.utils.tensorboard import SummaryWriterdataset = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataload = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True, drop_last=True)# 利用Sequential
class MyNet(nn.Module):def __init__(self):super(MyNet, self).__init__()self.model1 = Sequential(nn.Conv2d(3, 32, 5, padding=2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, padding=2),nn.MaxPool2d(2),nn.Conv2d(32, 64, 5, padding=2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(1024, 64),nn.Linear(64, 10))def forward(self, x):x = self.model1(x)return xmynet = MyNet()
loss = nn.CrossEntropyLoss()
optim = torch.optim.SGD(mynet.parameters(), lr=0.01)
for epoch in range(20): # 一共训练20次epoch_loss = 0.0 # 每次训练所有样本的损失和for data in dataload: # 训练一次所有数据imgs, targets = dataoutputs = mynet(imgs)res_loss = loss(outputs, targets)########################################optim.zero_grad() # 清空梯度 (多次训练,防止梯度影响)res_loss.backward() # 反向传播计算梯度optim.step()  # 更新参数#######################################epoch_loss += res_loss.item()print("epoch:{}, loss:{}".format(epoch, epoch_loss))

5 模型

5.1 VGG16模型

模型使用步骤

  1. 下载模型权重:如果你第一次运行该代码,PyTorch 会自动下载并缓存预训练模型的权重文件。这些权重通常存储在预定义的位置(通常是 PyTorch 提供的服务器上)。

  2. 加载权重:一旦下载完成,models.vgg16(pretrained=True) 将会加载这些权重并应用于模型的各个层次,包括卷积层和全连接层。这意味着模型会被初始化为在 ImageNet 数据集上训练过的状态,其中包括了学习到的特征权重。

  3. 使用预训练模型:加载后的 vgg16 模型现在可以直接用于特征提取、微调或者其他任务。由于预训练模型已经学习了大量的特征表示,因此在许多视觉任务中,使用这样的预训练模型往往能够显著提升训练效果和泛化能力。

vgg16_true = torchvision.models.vgg16(pretrained=True)
# pretrained=True 参数的作用是告诉PyTorch加载一个预训练好的 VGG16 模型。
vgg16_false = torchvision.models.vgg16(pretrained=False)print(vgg16_true) # VGG16模型的架构# 修改已有模型
# 添加新的模块(获取已有模块的各个部分)
vgg16_true.classifier.add_module("add_module",nn.Linear(1000, 10))
print(vgg16_true)
# 修改新的模块
vgg16_false.classifier[6] = nn.Linear(4096, 10)
print(vgg16_false)

5.2 模型保存与加载

  1. 保存
    torch.save() 是 PyTorch 提供的一个函数,用于将模型、张量或者字典等对象保存到磁盘上的文件中。
torch.save(obj, filepath)
obj: 要保存的对象,可以是模型、张量或者字典等。
filepath: 保存对象的文件路径。
import torch
import torchvisionvgg16 = torchvision.models.vgg16(pretrained=False)
保存方式1  保存模型的结构和参数(整个全保存)
torch.save(vgg16, 'vgg16.pth') #上面的代码将整个模型保存到的文件中。这种方法保存了模型的架构和训练好的权重。

上面的代码将整个 vgg16 模型保存到名为 vgg16.pth 的文件中。这种方法保存了模型的架构和训练好的权重。

只需要保存模型的状态字典(即模型的权重),而不保存整个模型对象的结构。
torch.save(vgg16.state_dict(), 'vgg16_dict.pth')
这段代码将只保存 vgg16 模型的权重到 vgg16_dict.pth 文件中,这样可以节省存储空间并且更加灵活,因为在加载时我们可以根据需要重新构建模型。

  1. 加载
    torch.load() 是 PyTorch 提供的函数,用于从磁盘上加载已保存的模型、张量或字典等对象。
torch.load(filepath)
filepath: 要加载的文件路径,该文件通常是由 torch.save() 函数保存的。
# 加载模型(结构、参数等等)
"""
这段代码会将之前保存的整个vgg16模型加载到变量 model 中。
加载后的模型可以直接用于预测或继续训练,因为它包含了之前保存的所有结构和参数。
"""
model1 = torch.load("vgg16.pth")
print(model1)# 记载状态参数模型
"""
这段代码首先创建了一个与预训练的vgg 模型相同结构的新模型 model,
然后将加载的状态字典 state_dict 复制到这个新模型中。
这种方法适用于当我们需要从文件中加载权重,并且已有对应模型结构的情况。
"""
model2 = torchvision.models.vgg16(pretrained=False)
print(torch.load("vgg16_dict.pth"))  # 只包含权重参数
model2.load_state_dict(torch.load("vgg16_dict.pth"))
print(model2)  # 整个模型

5.3 完整模型训练

准备数据:加载训练数据集,并设置数据加载器(DataLoader)用于批量加载数据。

定义模型:创建或加载需要训练的模型,并选择损失函数(loss function)和优化器(optimizer)。

训练循环:使用循环遍历训练数据集,对模型进行训练,主要包括以下步骤:

  • 将模型设置为训练模式,即调用 model.train()。
  • 遍历每个小批量数据,在每个批量中执行以下操作:
    • 将数据传递给模型,获取模型的输出。
    • 计算损失(loss)。
    • 执行反向传播(backpropagation),计算梯度。
    • 使用优化器更新模型参数。

在每个小批量数据的处理结束后,可能会记录或打印训练过程中的一些指标,如损失值或准确率。

评估模型:在每个 epoch 或一定周期后,使用验证集评估模型性能,通常使用 torch.no_grad() 禁止梯度计算,以减少内存占用。

保存模型:在训练完成后,保存模型的参数或整个模型,以便后续推理或继续训练。
在这里插入图片描述
构建模型

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

训练模型

# 准备数据集
train_data = torchvision.datasets.CIFAR10(root='./dataset', train=True, transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(),download=True)# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)# 搭建神经网络
mynet = MyNet()# 损失函数
loss_fn = nn.CrossEntropyLoss()# 优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(mynet.parameters(), lr=learning_rate)# 训练需要的参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10# 添加TensorBoard
write = SummaryWriter(log_dir='./logs')
# 开始轮数
for ep in range(epoch):print("----------第{}轮训练开始-------------".format(ep + 1))# 训练步骤开始mynet.train()start_time = time.time()for data in train_dataloader:imgs, targets = dataoutputs = mynet(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step += 1# 每训练100次 打印一次数据if total_train_step % 100 == 0:end_time = time.time()write.add_scalar('train_loss', loss.item(), total_train_step)print("训练次数:{}  Loss:{}  Time:{}".format(total_train_step, loss.item(),end_time-start_time))# 测试步骤开始mynet.eval()"""正确率分析(以二分类为例)inputs = [0,1] # 表示输入的类别outputs = torch.tensor([1.0,4.0],[2.0,3.0]) # 表示输出各类别的概率preds = outputs.argmax(1) # 横向求出最大值的下标->[1,1]->预测的类别inputs==preds # 比较输入与预测——>[flase,true]"""total_loss = 0  # 计算每轮测试的梯度和total_accuracy = 0 # 计算每轮测试的正确个数# 测试不需要求梯度(此部分不会求梯度)"""用于在执行代码时临时关闭梯度计算。它的作用主要是在推理阶段或者不需要计算梯度的代码段中,提高代码的运行效率和减少内存消耗"""with torch.no_grad():for data in test_dataloader:imgs, targets = dataoutputs = mynet(imgs)loss = loss_fn(outputs, targets)#  每次预测正确的个数accuracy = (targets==outputs.argmax(1)).sum()total_accuracy += accuracy.item()total_test_step += 1total_loss += loss.item()write.add_scalar('test_loss', total_loss, total_test_step)print("第{}轮整体测试集上的Loss:{}".format(ep + 1, total_loss))write.add_scalar('accuracy_rate', total_accuracy/test_data_size, total_test_step)print("第{}轮整体测试集上的accuracy_rate:{}".format(ep+1, total_accuracy/test_data_size))保存每次训练的模型(结构及训练的参数)torch.save(mynet,"mynet_{}.pth".format(ep))print("模型保存成功")
write.close()

train() 和 eval() 是在深度学习中经常用到的两个方法,它们通常用于切换模型的工作模式,即训练模式和评估模式。

mynet.train()
在训练过程中,我们需要使用 train() 方法来告诉模型开始训练,并启用一些特定于训练的功能,
比如启用 dropout 或者批量归一化的训练模式。

mynet.eval()
在评估或推理阶段,我们使用 eval() 方法告诉模型停止学习,不启用 dropout 或批量归一化的训练模式,以确保输出的一致性和稳定性

  • 停用 dropout 层:在评估时,dropout 层不再丢弃神经元,以保持输出的稳定性。
  • 使用训练时计算的移动平均值来代替批量归一化的计算,以减少测试时间的波动。

区别与使用场景

  • 区别:主要区别在于在训练模式下是否启用了dropout批量归一化的训练行为。训练模式下,模型会保留这些行为以便模型学习;评估模式下,这些行为被停用以保持输出的一致性。
  • 使用场景:在训练阶段,使用train()方法训练模型;在测试、验证或实际应用中,使用 eval() 方法评估模型。

5.4 利用GPU训练模型

在PyTorch中,.cuda()是一个方法,用于将Tensor或模型加载到GPU上进行加速计算。

  1. 将Tensor数据、网络、损失函数移到GPU上
    .cuda()是一个方法,用于将Tensor或模型加载到GPU上进行加速计算。
    通常是对模型、数据、损失函数使用.cuda()
...
...
...
# 搭建神经网络
mynet = MyNet()
# 使用.cuda()首先判断gpu是否可用
if torch.cuda.is_available():mynet.cuda()# 损失函数
loss_fn = nn.CrossEntropyLoss()
if torch.cuda.is_available():loss_fn = loss_fn.cuda()...
...
...
# 开始轮数
for ep in range(epoch):
...
...
...for data in train_dataloader:imgs, targets = dataif torch.cuda.is_available():imgs, targets = imgs.cuda(), targets.cuda()...
...
...
  1. 将Tensor或模型加载到特定设备上
    .to()方法是一个用于Tensor或模型转移到不同设备(如CPU或GPU)的通用方法。它的主要作用是将数据或模型从当前设备移动到目标设备
    .to()方法可以接受一个torch.device对象或一个设备字符串作为参数,从而将Tensor或模型加载到指定的设备上。
device = torch.device('cuda')
...
...
...# 搭建神经网络
mynet = MyNet()
# 转移设备
mynet.to(device)
# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)
...
...
...
# 开始轮数
for ep in range(epoch):print("----------第{}轮训练开始-------------".format(ep + 1))# 训练步骤开始start_time = time.time()for data in train_dataloader:imgs, targets = dataimgs, targets = imgs.to(device), targets.to(device)
...
...
...

5.5 应用模型

使用训练的模型去预测CIFAR10中图片的分类

  1. 加载待预测图片
  2. 修改图片格式为模型规定的格式
  3. 加载模型
  4. 使用模型预测
image_path = "imgs/dog.png"
# 加载图片,并转换为正确格式
image = Image.open(image_path)
'''
用于对图像进行大小调整(resize)。
在计算机视觉任务中,经常需要对输入的图像进行预处理,使其符合模型的输入要求或者统一到相同的尺寸上进行批处理。
Resize 类允许我们按照指定的大小调整图像。
'''
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),torchvision.transforms.ToTensor()])
image = transform(image)
print(image.shape)  # torch.Size([3, 32, 32])# 加载训练好的模型
class MyNet(nn.Module):def __init__(self):super(MyNet, self).__init__()self.model1 = Sequential(nn.Conv2d(3, 32, 5, padding=2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, padding=2),nn.MaxPool2d(2),nn.Conv2d(32, 64, 5, padding=2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(1024, 64),nn.Linear(64, 10))def forward(self, x):x = self.model1(x)return x# 加载模型
'''
mynet.pth在gpu训练的模型需要在cpu进行映射map_location=torch.device('cpu')
否则错误 Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same or input should be a MKLDNN tensor and weight is a dense tensor
'''
model = torch.load("mynet.pth", map_location=torch.device('cpu'))
# 重塑确保 image 的形状符合下游操作或模型的预期形状。这是深度学习工作流中常见的操作,用于标准化张量的形状。
image = torch.reshape(image, (1, 3, 32, 32))
# 评估模式
model.eval()
with torch.no_grad():outputs = model(image)
print(outputs.argmax(dim=1).item())  # 输出概率最大的种类下标
'''   种类坐标对应
{'airplane': 0, 'automobile': 1, 'bird': 2, 'cat': 3, 'deer': 4,'dog': 5, 'frog': 6, 'horse': 7, 'ship': 8, 'truck': 9}
'''

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

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

相关文章

【 FPGA 线下免费体验馆】高端 AMD- xilinx 16 nm UltraScale +系列

在复杂的FPGA 开发的过程中,需要能够满足高速、高精度、多通道等的复杂应用。而一个简单的 FPGA 开发板是不具备这些的,因此需要用更高端,大容量,高速IO的 FPGA 芯片与其他硬件组成一个完整的系统开发。这里就产生了高端 FPGA 开发…

redis服务器同 redis 集群

搭建redis服务器 修改服务运行参数 常用命令常用命令 创建redis集群 准备做集群的主机,不允许存储数据、不允许设置连接密码 配置服务器: 1、在任意一台redis服务器上都可以执行创建集群的命令。 2、--cluster-replicas 1 给每个master服务器分配1台…

【go】Excelize处理excel表 带合并单元格、自动换行与固定列宽的文件导出

文章目录 1 简介2 相关需求与实现2.1 导出带单元格合并的excel文件2.2 导出增加自动换行和固定列宽的excel文件 1 简介 之前整理过使用Excelize导出原始excel文件与增加数据校验的excel导出。【go】Excelize处理excel表 带数据校验的文件导出 本文整理使用Excelize导出带单元…

汇编教程1

本教程主要教大家如何使用vscode插件编写汇编语言,这样更方便,不用在32位虚拟机中编写汇编语言,后续的汇编实验代码都是使用vscode编写,话不多说,开始教学 安装vscode 如果已经安装过vscode,可以跳过这一…

Python创建Excel表和读取Excel表的基础操作

下载openpyxl第三方库 winr打开命令行输入cmd 这个如果不行可以试试其他方法,在运行Python代码的软件里也有直接下载的地方,可以上网搜索 创建Excel表 示例代码:最后要记得保存,可以加一句提示语句。 import openpyxl lst[100,…

【Apache Doris】周FAQ集锦:第 16 期

【Apache Doris】周FAQ集锦:第 16 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目! 在这个栏目中,每周将筛选社区反馈的热门问题和话题,重点回答并进行深入探讨。旨在为广大用户…

简单工厂、工厂方法与抽象工厂之间的区别

简单工厂、工厂方法与抽象工厂之间的区别 1、简单工厂(Simple Factory)1.1 定义1.2 特点1.3 示例场景 2、工厂方法(Factory Method)2.1 定义2.2 特点2.3 示例场景 3、抽象工厂(Abstract Factory)3.1 定义3.…

【JavaEE-多线程背景-线程等待-线程的六种状态-线程安全问题-详解】

🌈个人主页:SKY-30 ⛅个人推荐:基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构,刷题刻不容缓:点击一起刷题 🌙心灵鸡汤:总有人要赢,为什么不能是我呢 &…

C语言实现冒泡排序

冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。 遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元…

数据包的跨层封装

首先,我们先简单地分析一下数据包的组成结构: 如图 数据包简略地分为以下几层: 二层:封装MAC地址(数据链路层) 三层:封装IP地址 — 表明源IP和目标IP,主要用于路由器之间的信息转发…

【人工智能】Transformers之Pipeline(三):文本转音频(text-to-audio/text-to-speech)

​​​​​​​ 一、引言 pipeline(管道)是huggingface transformers库中一种极简方式使用大模型推理的抽象,将所有大模型分为音频(Audio)、计算机视觉(Computer vision)、自然语言处理&#x…

挖矿宝藏之硬盘分区

目录 一、硬盘分区的相关知识 二、主分区、活动分区、扩展分区、逻辑盘和盘符 三、硬盘分区原因 1.减少硬盘空间的浪费 2.便于文件的分类管理 3.有利于病毒的防治 四、硬盘分区的原则 1.方便性 2.实用性 3.安全性 五、利用Diskpart进行分区 1.命令行工具Diskpart …

ARM体系结构和接口技术(五)封装RCC和GPIO库

文章目录 一、RCC(一)思路1. 找到时钟基地址2. 找到总线的地址偏移(1)AHB4总线(2)定义不同GPIO组的使能宏函数(3)APB1总线(4)定义使能宏函数 二、GPIO&#x…

捷配笔记-混合信号PCB布局设计的基本准则是什么?

混合信号PCB设计需要对模拟和数字电路有基本的了解,以最大限度地减少(如果不能防止的话)信号干扰。现代系统由数字域和模拟域均可操作的组件组成,这些组件必须经过精心设计,以确保整个系统的信号完整性。 在混合信号系…

MySQL学习记录 —— 이십이 MySQL服务器文件系统(2)

文章目录 1、日志文件的整体简介2、一般、慢查询日志1、一般查询日志2、慢查询日志FILE格式TABLE格式 3、错误日志4、二进制日志5、日志维护 1、日志文件的整体简介 中继服务器的数据来源于集群中的主服务。每次做一些操作时,把操作保存到重做日志,这样崩…

vscode+wsl2+anaconda环境的配置与使用

目录 下载anaconda Anaconda使用参考 vscodeubuntuanaconda 先用vscode连接本地ubuntu。 如果没有安装wsl2与ubuntu,可点击下面的链接。 问题:wsl install 无法解析服务器 成功记录: 在vscode终端用ubuntu安装anaconda。 创建pytho…

Spring如何管理Mapper

目录 一、背景二、猜测三、源码查看步骤1、创建MapperScannerConfigurer.java2、MapperScan注解3、MapperScannerRegistrar执行registerBeanDefinitions方法4、MapperScannerConfigurer执行postProcessBeanDefinitionRegistry方法5、执行doscan6、设置beanClass7、使用jdk生成代…

万界星空科技电线电缆MES系统实现线缆全流程追溯

MES系统通过高度集成的数据平台,对电线电缆的生产全过程进行实时监控与记录,从原材料入库开始,到生产过程中的各个关键控制点,再到成品出库,每一步操作都被详细记录并可追溯。这种全流程追溯能力主要体现在以下几个方面…

在组件中显示tuku的照片

一、问题 (1)错误:域名前面一定要加http://要不然会报错 (2)在使用 defineModel传值时一定要动态绑定,要不然图片不显示 (3)改完后在商品列表中显示图片信息必须 在显示的图片中取…

Linux入门笔记(指令)

操作系统是什么? 操作系统是一款做软硬件管理的软件。计算机系统自下而上可以大致分为4部分:硬件、操作系统、应用程序和用户。操作系统管理各种计算机硬件,为应用程序提供基础,并且充当计算机硬件与用户之间的中介。重点&#x…