当前位置: 首页 > news >正文

浅学 Pytorch

(一)Dataset

Dataset 是一个抽象类,用于表示数据集。它封装了数据的加载和预处理逻辑,使得数据的读取和处理更加灵活和易于管理。在PyTorch中,torch.utils.data.Dataset 是一个基类,用户可以继承并实现自己的数据集。

import os
from torch.utils.data import Dataset
from PIL import Imageclass CustomDataset(Dataset):def __init__(self, root_dir, label_dir):self.root_dir = root_dirself.label_dir = label_dirself.path = os.path.join(self.root_dir, self.label_dir)self.img_path = os.listdir(self.path)def __len__(self):return len(self.img_path)def __getitem__(self, idx):img_name = self.img_path[idx]img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)img = Image.open(img_item_path)label = self.label_dirreturn img, labelroot_dir = 's-data/train'
ants_label_dir = 'ants_img'
bees_label_dir = 'bees_img'
ants_dataset = CustomDataset(root_dir, ants_label_dir)
bees_dataset = CustomDataset(root_dir, bees_label_dir)img, label = bees_dataset[0]
img.show()

(二)TensorBoard

TensorBoard 是一个强大的可视化工具,它主要用于可视化和分析神经网络的训练过程,包括损失和准确率的变化、模型结构、图像数据、激活值等。

from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Imagewriter = SummaryWriter('logs')
img_path = 's-data/train/bees_img/16838648_415acd9e3f.jpg'
img_PIL = Image.open(img_path)
img_array = np.array(img_PIL)
# global_step 表示写入的步数(类似索引)
writer.add_image('test', img_array, 2, dataformats='HWC')for i in range(100):writer.add_scalar('y=2x', 3 * i, i)writer.close()

运行:

tensorboard --logdir=logs  --port=6007

(三)常见的 Transforms

1. ToTensor

它将形状为 (H, W, C) 且像素值在 [0, 255] 范围的 PIL 图像或 NumPy 数组转换为形状为 (C, H, W) 且像素值在 [0.0, 1.0] 范围的PyTorch张量。

from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter('logs')
img = Image.open('data/train/bees/17209602_fe5a5a746f.jpg')trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image('ToTensor', img_tensor)writer.close()

在这里插入图片描述

2. Normalize

标准化的目的是使数据的各个特征具有相似的尺度,从而提高模型的训练效率和稳定性。用于标准化张量图像(tensor image)的每个通道。该变换接受两个参数:均值(mean)和标准差(std),并使用以下公式进行标准化:
output[channel] = (input[channel] - mean[channel]) / std[channel]

from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter('logs')
img = Image.open('data/train/bees/17209602_fe5a5a746f.jpg')trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
writer.add_image('Normalize', img_norm, 1)writer.close()

在这里插入图片描述

3. Resize

用于将输入的PIL图像调整到模型所需的固定尺寸。
接受目标尺寸作为参数,可以是一个整数或一个二元元组:

  • 二元元组:如果提供一个二元元组,例如 (height, width),Resize 将图像调整为指定的高度和宽度。
  • 整数:如果提供一个整数,Resize 将保持图像的长宽比不变,并将图像的较短边调整为该整数长度,较长边则根据原始比例自动调整。
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter('logs')
img = Image.open('data/train/bees/17209602_fe5a5a746f.jpg')trans_resize = transforms.Resize((300, 300))
trans_resize2 = transforms.Resize(500)
img_resize = trans_resize(img)
img_resize2 = trans_resize2(img)
writer.add_image('Resize', trans_totensor(img_resize), 1)
writer.add_image('Resize', trans_totensor(img_resize2), 2)writer.close()

4. RandomCrop、CenterCrop

RandomCrop 可以从输入图像中随机裁剪出一个指定大小的区域。
CenterCrop 可以 从图像中心裁剪出指定大小的区域。

trans_random = transforms.RandomCrop(200)
img_random = trans_random(img)
writer.add_image('RandomCrop', trans_totensor(img_random), 1)trans_center = transforms.CenterCrop(200)
img_center = trans_center(img)
writer.add_image('CenterCrop', trans_totensor(img_center), 1)

5. ToPILImage

用于将 tensor 张量或 NumPy 数组转换为 PIL 图像。

trans_pil = transforms.ToPILImage()
img_pil = trans_pil(img_tensor)
print(type(img_pil))  # <class 'PIL.Image.Image'>

6. Compose

它将一系列图像变换按顺序应用于输入图像,形成一个统一的变换流水线。

from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter('logs')
img = Image.open('data/train/bees/17209602_fe5a5a746f.jpg')transform = transforms.Compose([transforms.Resize((300, 300)),transforms.CenterCrop(200), transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])
img_compose = transform(img)
writer.add_image('Compose', img_compose, 2)writer.close()

7. ColorJitter

随机更改图像的亮度、对比度、饱和度和色调。

trans_color = transforms.ColorJitter(brightness=1, contrast=1, saturation=1, hue=0.5)
img_color = trans_color(img)
writer.add_image('ColorJitter', trans_totensor(img_color), 1)

8. Grayscale

将图像转换为灰度。默认是1

trans_gray = transforms.Grayscale(3)
img_gray = trans_gray(img)
writer.add_image('Grayscale', trans_totensor(img_gray), 1)

(四)DataLoader

用于加载和批量处理数据集。它提供了常见的数据操作功能,如批量加载、数据洗牌、并行数据加载等,从而简化了数据预处理和模型训练流程。
dataloader = DataLoader(dataset, batch_size=64, shuffle=True, num_workers=4)

  • batch_size:每个批次的数据量大小。比如batch_size=64 表示每次从数据集中取 64 个样本。
  • shuffle:在每个 epoch 结束后,是否对数据进行洗牌。shuffle=True 可以打乱数据的顺序,有助于提高模型的泛化能力。
  • num_workers:用于数据加载的子进程数。比如 num_workers=4 表示使用 4 个子进程加载数据。增加 num_workers 数量可以加速数据加载过程,尤其是在数据预处理复杂或数据集较大时。
  • drop_last:如果数据集大小不能被批量大小整除,drop_last=True 则会丢弃最后一个不完整的批次。
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWritertest_data = torchvision.datasets.CIFAR10(root='./CIFA10', train=False, download=True,transform=torchvision.transforms.ToTensor())test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=True)writer = SummaryWriter('CIFA-logs')step = 0
for data in test_loader:imgs, targets = datawriter.add_images('testdata_loader', imgs, step)step = step + 1writer.close()

在这里插入图片描述

(五)神经网络

1. 基本骨架 — nn.Module的使用

在 PyTorch 中,nn.Module 是构建神经网络的基础类。所有的神经网络模块都应继承自 nn.Module,并实现 forward 方法。在该类中,定义了网络的层以及前向传播的方式。

  • 继承 nn.Module:定义一个类来表示你的神经网络,并使它继承 nn.Module。
  • 定义网络层:在 __init__ 方法中定义网络的各个层,并使用 nn.Module 的子模块(如 nn.Linear,nn.Conv2d 等)。
  • 实现前向传播:在 forward 方法中定义输入数据如何通过网络层计算输出。这是网络前向传播的逻辑。
import torch
from torch import nnclass Module(nn.Module):def __init__(self):super().__init__()def forward(self, input):output = input + 1return outputx = torch.tensor(1.0)
model = Module()
output = model(x)
print(output)  # tensor(2.)

2. 卷积操作 — nn.functional.conv

torch.nn.functional.conv 是 PyTorch 中用于直接调用卷积操作的函数。它有多个变体,如 conv1d、conv2d、conv3d,分别对应一维、二维和三维卷积。与 nn.Conv2d 等模块化接口不同,nn.functional.conv 需要手动指定所有的参数,包括权重和偏置,因此更灵活,但也需要更多手动管理。

  • input:输入张量,形状为(minibatch, in_channels, iH, iW),其中minibatch是批量大小,in_channels是输入通道数,iHiW是输入的高度和宽度。
  • weight:卷积核的权重张量,形状为(out_channels, in_channels/groups, kH, kW),其中out_channels是输出通道数,in_channels/groups是每组的输入通道数,kHkW是卷积核的高度和宽度。
  • bias:偏置项,形状为(out_channels)
  • stride:卷积操作的步幅,默认值为1。可以是一个整数或一个元组(sH, sW)
  • padding:输入的填充大小,默认值为0。可以是一个整数或一个元组(padH, padW),用于控制输出的空间维度。
  • dilation:卷积核元素之间的间距,默认值为1。可以是一个整数或一个元组(dH, dW)
  • groups:控制输入和输出的连接方式,默认值为1。groups=1表示标准卷积,groups=in_channels表示深度卷积,每个输入通道有一个单独的滤波器。

`在这里插入图片描述

import torch
import torch.nn.functional as F# 输入 5x5 图像
input = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]])# 卷积核
kernel = torch.tensor([[1, 2, 1],[0, 1, 0],[2, 1, 0]])# input – input tensor of shape(batch_size, in_channels, 𝑖𝐻, 𝑖𝑊)
# 转成四维张量
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))output = F.conv2d(input, kernel, stride=1)
print(output)output2 = F.conv2d(input, kernel, padding=1)
print(output2)

在这里插入图片描述

3. 卷积层 — nn.Conv2d

在 PyTorch 中,卷积层可以通过 torch.nn.Conv 模块实现。根据不同的卷积类型,PyTorch 提供了多个类,包括 nn.Conv1d、nn.Conv2d 和nn.Conv3d,分别用于一维、二维和三维卷积操作。最常用的是 nn.Conv2d,用于处理二维图像数据。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils import tensorboard
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10('./CIFA10', train=False, download=True,transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = Conv2d(3, 3, 3, 1, 0)def forward(self, x):x = self.conv1(x)return xcnn = CNN()writer = tensorboard.SummaryWriter('CIFA-logs')
step = 0
for data in dataloader:imgs, targets = dataoutput = cnn(imgs)writer.add_images('input', imgs, step)writer.add_images('output', output, step)step += 1writer.close()

在这里插入图片描述

4. 池化层 — 最大池化 nn.MaxPool2d 的使用

nn.MaxPool2d 是 PyTorch 中的一个池化层,用于在卷积神经网络(CNN)中执行二维的最大池化操作。最大池化的目的是通过取局部窗口的最大值来减小特征图的尺寸,从而减少计算量、参数数量和过拟合的风险,同时保留重要的特征信息。

  • kernel_size:窗口的大小,可以是单个整数(表示高度和宽度相同)或元组(分别指定高度和宽度)。
  • stride:步幅,指定窗口移动的步长。可以是单个整数或元组。默认情况下等于 kernel_size。
  • padding:填充,指定在输入张量的边缘填充的大小。默认值为 0。
  • dilaton:控制窗口中元素的间距。默认值为 1。
  • ceil_mode:为 True 时数据不够就取,为 False 数据不够就丢弃。

在这里插入图片描述

import torch
from torch import nn
from torch.nn import MaxPool2dinput = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]])input = torch.reshape(input, (1, 5, 5))class MaxPool(nn.Module):def __init__(self):super(MaxPool, self).__init__()self.maxpool1 = MaxPool2d(3, ceil_mode=True)self.maxpool2 = MaxPool2d(3, ceil_mode=False)def forward(self, x):output1 = self.maxpool1(x)output2 = self.maxpool2(x)return output1, output2model = MaxPool()
output1, output2 = model(input)
print(output1)
print(output2)

在这里插入图片描述

import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils import tensorboard
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10('CIFA10', train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64)class MaxPool(nn.Module):def __init__(self):super(MaxPool, self).__init__()self.maxpool = MaxPool2d(3, ceil_mode=True)def forward(self, x):output = self.maxpool(x)return outputmodel = MaxPool()
writer = tensorboard.SummaryWriter('CIFA-logs')
step = 0
for data in dataloader:imgs, targets = datawriter.add_images('input', imgs, step)output = model(imgs)writer.add_images('maxpool_output', output, step)step += 1writer.close()

在这里插入图片描述

5. 非线性激活函数

用于在神经网络中引入非线性特性。它们的作用是在输入数据经过线性变换后,施加一个非线性的映射,从而使得神经网络能够学习到复杂的模式和特征。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import torch
import torchvision
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils import tensorboard
from torch.utils.data import DataLoaderinput = torch.tensor([[1, -0.5],[-1, 3]])dataset = torchvision.datasets.CIFAR10('CIFA10', train=False, download=True,transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)class Model(nn.Module):def __init__(self):super(Model, self).__init__()self.relu = ReLU()self.sigmoid = Sigmoid()def forward(self, x):output1 = self.relu(x)output2 = self.sigmoid(x)return output1, output2model = Model()
output1, output2 = model(input)
print(output1)
print(output2)writer = tensorboard.SummaryWriter('CIFA-logs')
step = 0
for data in dataloader:imgs, targets = datawriter.add_images('非线性-input', imgs, step)ouput1 = model(imgs)[0]writer.add_images('relu', ouput1, step)output2 = model(imgs)[1]writer.add_images('sigmoid', output2, step)step += 1writer.close()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6. 线性层 — nn.linear

nn.Linear 是 PyTorch 中用于实现线性变换的层,通常用于全连接神经网络(也称为前馈神经网络)的隐藏层和输出层。它执行的操作是对输入数据进行线性变换,即输入向量乘以权重矩阵并加上偏置项。

import torch
from torch import nn
from torch.nn import Linearclass LinearLayer(nn.Module):def __init__(self):super(LinearLayer, self).__init__()self.linear = Linear(4, 3, bias=True)# 随机初始化print('weights:', self.linear.weight)print('Bias:', self.linear.bias)def forward(self, x):return self.linear(x)model = LinearLayer()
input = torch.tensor([[1.0, 2.0, 3.0, 4.0]])
output = model(input)
print(output)

在这里插入图片描述

7. 搭建小实战和Sequential的使用

在这里插入图片描述

import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils import tensorboardclass CIFAR(nn.Module):def __init__(self):super(CIFAR, self).__init__()# self.conv1 = Conv2d(3, 32, 5, padding=2)# self.maxpool1 = MaxPool2d(2)# self.conv2 = Conv2d(32, 32, 5, padding=2)# self.maxpool2 = MaxPool2d(2)# self.conv3 = Conv2d(32, 64, 5, padding=2)# self.maxpool3 = MaxPool2d(2)# # 它的作用是将多维的输入数据展平成一维。通常在卷积神经网络(CNN)中使用,用于将卷积层或池化层的输出转换为全连接层的输入格式。# self.flatten = Flatten()# # 全连接层# self.linear1 = Linear(64 * 4 * 4, 64)# self.linear2 = Linear(64, 10)# 第二种写法:self.model = 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(64 * 4 * 4, 64),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)x = self.model(x)return xcifar = CIFAR()
print(cifar)input = torch.ones((64, 3, 32, 32))
output = cifar(input)
print(output.shape)writer = tensorboard.SummaryWriter("CIFA-logs")
writer.add_graph(cifar, input)
writer.close()

在这里插入图片描述

在这里插入图片描述

8. 损失函数与反向传播

损失函数是一个函数,用于衡量模型的预测输出与实际目标之间的差距。它的值越小,表示模型的预测越接近真实值。损失函数的选择取决于具体的任务类型,如回归、分类等。

L1Loss(也称为 绝对值损失 或 平均绝对误差,MAE):它用于测量预测值和真实值之间的差异,通过计算预测值与真实值之差的绝对值来量化这种差异。
在这里插入图片描述
MSELoss(Mean Squared Error Loss,均方误差损失):特别是在回归任务中。它通过计算预测值和真实值之间差异的平方来量化预测误差,并取所有样本误差的平均值。
在这里插入图片描述
CrossEntropyLoss(交叉熵损失): 是深度学习中常用于分类任务的一种损失函数。它结合了 softmax 激活函数和负对数似然损失,用于衡量模型的预测概率分布与真实标签分布之间的差异。
在这里插入图片描述

import torch
from torch.nn import L1Loss, MSELoss, CrossEntropyLossinputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)# L1Loss
loss_fn1 = L1Loss()  # 默认是mean,求均值损失
res1 = loss_fn1(inputs, targets)
print(res1)  # tensor(0.6667)loss_fn2 = L1Loss(reduction='sum')
res2 = loss_fn2(inputs, targets)
print(res2)  # tensor(2.)# MSELoss
loss_fn3 = MSELoss()
res3 = loss_fn3(inputs, targets)
print(res3)  # tensor(1.3333)loss_fn4 = MSELoss(reduction='sum')
res4 = loss_fn4(inputs, targets)
print(res4)  # tensor(4.)# CrossEntropyLoss
loss_fn5 = CrossEntropyLoss()
# 未经过 softmax 的原始分数(logits)
# CrossEntropyLoss 自动将 y_pred 经过 softmax 后计算负对数似然损失,因此不需要手动应用 softmax 函数
y_pred = torch.tensor([[2.0, 1.0, 0.1]])
y_true = torch.tensor([0])
res5 = loss_fn5(y_pred, y_true)
print(res5)  # tensor(0.4170)

反向传播(Backpropagation)是神经网络训练过程中用于计算和更新模型参数的算法。它基于梯度下降的思想,通过计算损失函数关于模型参数的梯度来更新参数,使损失函数的值最小化。
在这里插入图片描述

(六)优化器

torch.optim 是 PyTorch 中用于实现各种优化算法的模块。优化器的作用是更新模型参数,以最小化损失函数。它们基于梯度下降法,但每种优化器有不同的更新策略。

1. SGD (随机梯度下降)

基本的优化算法,逐步更新参数。支持动量项来加速收敛。

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential, CrossEntropyLoss
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10('CIFA10', train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64)class CIFAR(nn.Module):def __init__(self):super(CIFAR, self).__init__()self.model = 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(64 * 4 * 4, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xloss = CrossEntropyLoss()
cifar = CIFAR()
optimizer = torch.optim.SGD(cifar.parameters(), lr=0.001)
for epoch in range(20):running_loss = 0for data in dataloader:imgs, targets = dataoutputs = cifar(imgs)res = loss(outputs, targets)optimizer.zero_grad()res.backward()optimizer.step()running_loss += resprint(running_loss)

在这里插入图片描述

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

import torchvision
from torch import nn
from torchvision.models import VGG16_Weights, vgg16vgg16_false = vgg16(weights=None)
vgg16_true = vgg16(weights=VGG16_Weights.DEFAULT)train_data = torchvision.datasets.CIFAR10('CIFA10', train=True, download=True,transform=torchvision.transforms.ToTensor())# 添加一个线性层
vgg16_true.classifier.add_module('7', nn.Linear(1000, 10))
print(vgg16_true)
# 修改一个线性层
vgg16_true.classifier[6] = nn.Linear(4096, 10)
print(vgg16_true)

(八)模型的保存与读取

1. 保存整个模型

import torch
import torchvisionvgg16 = torchvision.models.vgg16(weights=torchvision.models.VGG16_Weights.DEFAULT)
# 保存方式1(保存模型结构 + 参数)
torch.save(vgg16, 'vgg16.pth')
import torchmodel = torch.load('vgg16.pth')
print(model)

2. 保存模型的参数(推荐)

import torch
import torch.nn as nnclass Model(nn.Module):def __init__(self):super(Model, self).__init__()self.fc = nn.Linear(10, 1)def forward(self, x):return self.fc(x)model = Model()
torch.save(model.state_dict(), 'myModel_path')  # 假设保存的是已经训练好的参数model = Model()  # 重新实例化(参数是随机初始化的)
model.load_state_dict(torch.load('myModel_path'))  # 将训练好的参数加载进来
print(model)

(九)完整的模型训练套路

model:

import torch
from torch import nnclass CIFAR_Net(nn.Module):def __init__(self):super(CIFAR_Net, self).__init__()self.model = nn.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(64 * 4 * 4, 64),nn.Linear(64, 10))def forward(self, x):return self.model(x)if __name__ == '__main__':cifar = CIFAR_Net()input = torch.ones((64, 3, 32, 32))output = cifar(input)print(output.shape)
import torch
import torchvision
from torch.nn import CrossEntropyLoss
from torch.utils import tensorboard
from torch.utils.data import DataLoader
from model import *# 准备数据集
train_data = torchvision.datasets.CIFAR10('CIFA10', train=True, download=True,transform=torchvision.transforms.ToTensor())test_data = torchvision.datasets.CIFAR10('CIFA10', train=False, download=True,transform=torchvision.transforms.ToTensor())# 数据集大小
train_data_size = len(train_data)
test_data_size = len(test_data)
print(f"train_data_size: {train_data_size}, test_data_size: {test_data_size}")# 加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_loader = DataLoader(test_data, batch_size=64)# 创建网络模型
cifar = CIFAR_Net()# 损失函数
loss_fn = CrossEntropyLoss()# 优化器
learning_rate = 0.01  # 也可以写成 1e-2 = 1 * 10的-2次方
optimizer = torch.optim.SGD(cifar.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 设置训练的次数
total_train_step = 0
# 设置测试的次数
total_test_step = 0
# 设置训练的轮数
epoch = 10writer = tensorboard.SummaryWriter('CIFA-logs')for i in range(epoch):print(f'第{i + 1}轮训练开始')# 训练步骤开始cifar.train()total_train_loss = 0for data in train_dataloader:imgs, targets = dataoutputs = cifar(imgs)loss = loss_fn(outputs, targets)total_train_loss += loss.item()# 反向传播optimizer.zero_grad()loss.backward()# 更新权重optimizer.step()# 记录训练的次数total_train_step += 1if total_train_step % 100 == 0:print(f'第{total_train_step}步训练,loss为{loss.item()}')# 添加到tensorboardwriter.add_scalar('train_loss', loss.item(), total_train_step)print(f'第{i + 1}轮训练结束,loss为{total_train_loss}')# 测试步骤开始cifar.eval()total_test_loss = 0total_accuracy = 0# 上下文管理器,用于在不需要计算梯度的情况下运行PyTorch张量。with torch.no_grad():for data in test_loader:imgs, targets = dataoutputs = cifar(imgs)loss = loss_fn(outputs, targets)total_test_loss += loss.item()accuracy = (outputs.argmax(1) == targets).sum()total_accuracy += accuracy.item()# 记录测试的次数total_test_step += 1if total_test_step % 100 == 0:print(f'第{total_test_step}步测试,loss为{loss.item()}')# 添加到tensorboardwriter.add_scalar('test_loss', loss.item(), total_test_step)print(f'第{i + 1}轮测试结束,loss为{total_test_loss}')print(f'第{i + 1}轮测试结束,accuracy为{total_accuracy / test_data_size}')writer.add_scalar('test_accuracy', total_accuracy / test_data_size, i + 1)torch.save(cifar, f'cifar_{i + 1}.pth')writer.close()

在这里插入图片描述

(十)利用GPU训练

1. 第一种方法

在下方三处加入 cuda()

  • 网络模型
  • 数据(输入、标注)
  • 损失函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 第二种方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(十一)完整的模型验证套路

import torch
import torchvision
from PIL import Imageimg_path = 'imgs/cat5.png'
image = Image.open(img_path)transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),torchvision.transforms.ToTensor()
])
image = transform(image)model = torch.load('cifar_30.pth', weights_only=False, map_location=torch.device('cpu'))image = torch.reshape(image, (1, 3, 32, 32))
model.eval()
with torch.no_grad():output = model(image)idx = output.argmax(dim=1)
classes = ('airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
print(classes[idx])

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++协助完成返回值优化
  • 【python学习】Python中的 `json.dump` 和 `json.dumps` 的区别和用法解析
  • 深度学习入门(一):感知机与输入数据
  • 【吊打面试官系列-Elasticsearch面试题】详细描述一下 Elasticsearch 搜索的过程?
  • 【算法】贪心算法
  • 大话C语言:第36篇 枚举​
  • 【算法速刷(5/100)】LeetCode —— 20.有效的括号
  • Docker基础知识大全
  • 63 epoll服务器 (ET模式)
  • 【Linux】匿名管道|命名管道|pipe|mkfifo|管道原理|通信分类|管道的特征和情况
  • SQL二次注入
  • xtrabackup搭建MySQL 8.0 主从复制
  • Git 如何提交代码
  • 大话C语言:第37篇 联合体
  • 声明式UI语法
  • 10个确保微服务与容器安全的最佳实践
  • Angular2开发踩坑系列-生产环境编译
  • axios 和 cookie 的那些事
  • idea + plantuml 画流程图
  • js 实现textarea输入字数提示
  • Laravel Mix运行时关于es2015报错解决方案
  • Python打包系统简单入门
  • Rancher如何对接Ceph-RBD块存储
  • react-native 安卓真机环境搭建
  • Twitter赢在开放,三年创造奇迹
  • 工作手记之html2canvas使用概述
  • 构建二叉树进行数值数组的去重及优化
  • 关于字符编码你应该知道的事情
  • 基于遗传算法的优化问题求解
  • 今年的LC3大会没了?
  • 每天一个设计模式之命令模式
  • 前端存储 - localStorage
  • 如何编写一个可升级的智能合约
  • 收藏好这篇,别再只说“数据劫持”了
  • 算法之不定期更新(一)(2018-04-12)
  • 提醒我喝水chrome插件开发指南
  • UI设计初学者应该如何入门?
  • ​MySQL主从复制一致性检测
  • ​学习一下,什么是预包装食品?​
  • ‌‌雅诗兰黛、‌‌兰蔻等美妆大品牌的营销策略是什么?
  • #pragma预处理命令
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (C语言)二分查找 超详细
  • (补)B+树一些思想
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (算法)大数的进制转换
  • (微服务实战)预付卡平台支付交易系统卡充值业务流程设计
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)Google的Objective-C编码规范
  • **python多态
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 中 GetProcess 相关方法的性能