pytorch学习(b站小土堆学习)

news2025/4/3 1:54:04

1 环境配置

参考链接

2. dir 和 help函数

dir():用于查看某一模块函数的方法
help(): 用于查看某方法的使用方法
在这里插入图片描述

3. dataset类实战

利用Image对象打开图片,利用os模块的地址拼接组成图片路径
当我们用方括号访问元素对象时,实际上是调用了这个对象的__getitem__方法

from torch.utils.data import Dataset
from PIL import Image
import os

class MyData(Dataset):

    # 初始化,根目录的相对地址和标签label
    def __init__(self,root_dir,label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(self.root_dir,self.label_dir) # 拼接获得路径
        self.img_path = os.listdir(self.path) # 将对应路径下的元素名转换为列表

    # 当我们用方括号访问元素对象时,实际上是调用了这个对象的__getitem__方法
    def __getitem__(self, index): # 传入下标,获取对应图片
        img_name = self.img_path[index] # 从元素名的列表获取需要的元素名
        # 拼接所需图片的路径
        img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
        img = Image.open(img_item_path) # 根据路径获得图片对象
        label = self.label_dir
        return img,label

    def __len__(self): # 获取类中元素的数量
        return len(self.img_path)

root_dir = "E:\\pythonProject\\dataset\\hymenoptera_data\\train"
ants_label_dir = "ants"
bees_label_dir = "bees"
ants_dataset = MyData(root_dir,ants_label_dir)
bees_dataset = MyData(root_dir,bees_label_dir)

# 整体数据集可以使用两个数据集相加
train_dataset = ants_dataset + bees_dataset


然后可以数据集图片对象进行操作
在这里插入图片描述

4.TensorBoard的使用(一)

创建SummaryWriter实例,并生成一个图像,保存与当前路径下的 ”logs”文件夹中
SummaryWriter是PyTorch中的一个工具,用于将模型训练过程中的日志保存到TensorBoard中。可以通过使用SummaryWriter的add_scalar()方法来保存损失函数、准确率等标量信息,使用add_histogram()方法来保存权重、梯度等张量信息,使用add_image()方法来保存图像信息等。

from torch.utils.tensorboard import SummaryWriter

# 传入某一文件夹的路径,默认为当前路径下的文件夹
writer = SummaryWriter("logs")
for i in range(10000):
    # 参数1:tag(图表的名称/label) , 参数2:y轴的数值,参数3:x轴的数值
    writer.add_scalar("y = x", i ,i)
writer.close()

在对应虚拟环境的终端启动TensorBoard: logdir = 保存对应图像的文件夹名;port为打开的端口号
在这里插入图片描述
结果:
在这里插入图片描述

5. Tensorboard的使用(二)

使用numpy格式,添加文件图片。
numpy格式有两种:opencv打开文件和使用numpy直接格式转换

from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import  Image

# 传入某一文件夹的路径,默认为当前路径下的文件夹
writer = SummaryWriter("logs")
img_path = "dataset/hymenoptera_data/train/bees/16838648_415acd9e3f.jpg"
img = Image.open(img_path)  # img 为PIL的jpeg类型
img_array = np.array(img)  # 将img转换为numpy类型
# numpy的类型的方法二 是用opencv打开

# global—step 为步骤顺序,dataformats 为 数据格式
writer.add_image("test",img_array,1,dataformats='HWC')

for i in range(100):
    # 参数1:tag(图表的名称/label) , 参数2:y轴的数值,参数3:x轴的数值
    writer.add_scalar("y = x", i ,i)
writer.close()

在这里插入图片描述

6. Transfroms的使用(一)

![(https://i-blog.csdnimg.cn/direct/17e2ec49e97347349eba5e1d2b429e3c.png)

from torchvision import transforms
from PIL import Image

# transforms如何使用(python)
img_path = "dataset/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path) # 打开文件,得到一个图片类的实例

# 获取一个ToTensor实例
tensor_trans = transforms.ToTensor()
# 由于存在__call__方法,调用该实例,调用该方法
# 由图片实例转换为 tensor类型
tensor_img = tensor_trans(img)

print(tensor_img)

结果:
在这里插入图片描述

注: call 是 Python 中一个魔术方法(magic method),它用于定义对象的函数调用行为。换句话说,当你尝试调用一个具有 call 方法的对象时,Python 会自动调用该方法。

ToTensor类的__call__方法:
在这里插入图片描述

7. Transforms的使用(二)

将图片转换为tensor对象,再将该对象利用tensorboard的SummaryWriter打开。

from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Image

# transforms如何使用(python)
img_path = "dataset/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path) # 打开文件,得到一个图片类的实例

# 获取一个ToTensor实例
tensor_trans = transforms.ToTensor()
# 由于存在__call__方法,调用该实例,调用该方法
# 由图片实例转换为 tensor类型
tensor_img = tensor_trans(img)

writer = SummaryWriter("logs")
# 参数 :  self, tag, img_tensor, global_step=None, walltime=None, dataformats="CHW"
writer.add_image("Tensor_img",tensor_img) # 保存图像信息

writer.close()

启动tensorboard:
在这里插入图片描述
结果:
在这里插入图片描述

8.常见的Transform(一)

from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

writer = SummaryWriter("logs")
img = Image.open("images/123.jpg")

# ToTensor,转换后张量的范围均为0-1
trans_totensor = transforms.ToTensor()  # 创建ToTensor实例
img_tensor = trans_totensor(img) #调用内置__call__方法
writer.add_image("ToTensor",img_tensor)

# normalize 归一化
# 创建Normalize实例 ,输入分别为 均值 和 标准差
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = trans_norm(img_tensor)  # 其父类具有__call__方法,img_norm为tensor类型
writer.add_image("normalize", img_norm)
writer.close()

归一化会改变tensor的数据的范围,img_tensor中的值为[0,1] ,而使用标准差与均值均为0.5的归一化后,其值的范围变为[-1,1]。若标准差与均值改变,则范围也会改变

在这里插入图片描述
运行结果:在这里插入图片描述

9. 常见的Transform(二)

(1)Resize

from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

writer = SummaryWriter("logs")
img = Image.open("images/321.jpg")

# ToTensor,转换后张量的范围均为0-1
trans_totensor = transforms.ToTensor()  # 创建ToTensor实例
img_tensor = trans_totensor(img) #调用内置__call__方法
writer.add_image("ToTensor",img_tensor)

# normalize 归一化
# 创建Normalize实例 ,输入分别为 均值 和 标准差
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = trans_norm(img_tensor)  # 其父类具有__call__方法,img_norm为tensor类型
writer.add_image("normalize", img_norm)
writer.close()

# Resize
trans_resize = transforms.Resize([256,256]) # 传入要缩放的长和宽的列表
img_resize = trans_resize(img) # 传入一个PIL数据类型,返回值也为PIL类型
img_resize_tensor = trans_totensor(img_resize)  # 转换为tensor类型
writer.add_image("Resize",img_resize_tensor,0)

# Resize 写法2,使用compose,传入transform的列表,表示要进行的transform的操作
trans_resize2 = transforms.Resize(256)  # 等比缩放
trans_compose = transforms.Compose([trans_resize2,trans_totensor]) # 先改变大小,再转换为tensor
img_resize_tensor2 = trans_compose(img)
writer.add_image("Resize",img_resize_tensor2,1)

运行结果:
在这里插入图片描述
在这里插入图片描述
(2) RandomCrop:随即裁剪

# RandomCrop 随机裁剪,如果输入一个值n,则会减为x*x;若输入两个值,则裁剪为x*y
trans_randowcrop = transforms.RandomCrop(256)
trans_compose2 = transforms.Compose([trans_randowcrop,trans_totensor])
for i in range(10): # 随机裁剪十次
    img_randomcrop = trans_compose2(img)
    writer.add_image("RandomCrop",img_randomcrop,i)

writer.close()

运行结果:
在这里插入图片描述

10. torchvision中的数据集使用

数据集常用的参数:
在这里插入图片描述

import torchvision
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

# 自定义使用的transform
dataset_transforms = transforms.Compose([
    transforms.ToTensor() # 转化为tensor
])

# 数据集的路径,是否为训练数据集,使用的transform ,是否需要下载
train_set = torchvision.datasets.CIFAR10("./dataset1",train=True,transform=dataset_transforms,download=True)
test_set = torchvision.datasets.CIFAR10("./dataset1",train=False,transform=dataset_transforms,download=True)

writer = SummaryWriter("logs")
for i in range(10):
    img, target = test_set[i] # img为图片的tensor类型
    writer.add_image("test_set",img, i)
writer.close()

运行结果:
在这里插入图片描述

11. DataLoader的使用

在这里插入图片描述

import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

test_set = torchvision.datasets.CIFAR10("./dataset1",train=False,transform=transforms.ToTensor(),download=True)

# batch_size: 批大小, shuffle表示是否打乱(一个epoch打乱一次),num_workers表示多进程数(0表示主进程进行)
# drop_last表示当数据总数与批大小不成比例,剩余不够一批的数据是否舍弃
test_loader = DataLoader(test_set,batch_size=64,shuffle=True,num_workers=0,drop_last=False)

writer = SummaryWriter("dataload")

for epoch in range(2):  # epoch的数量设置为2
    step = 0
    for data in test_loader:
        imgs, targets = data  # imgs 是batch(一批)的图片张量
        # 注意是add_images 不是 add_image
        writer.add_images(f"Epoch:{epoch}",imgs, step)
        step += 1

writer.close()

运行结果:
在这里插入图片描述


12. nn.Module的基本使用

import torch
from torch import nn
class Test(nn.Module):
    def __init__(self):
        super().__init__()

    # 正向传播
    def forward(self, x):
        out = x + 1
        return out

test = Test()
x = torch.tensor(2.0)
# 使用实例传参会调用__call__函数,在nn.Module下会自动调用forward方法
print(test(x)) # 输出3

13. 神经网路-卷积层

卷积层stride默认为1.而后面池化层的stride默认为窗口长/宽。而卷积层的滤波器的初始值是随机值(在一定初始化方法下的随机,例如:Kaiming初始化和Xavier初始化

卷积层作用: 从输入数据中提取特征,形成特征图
池化层作用: 对特征图进行降维处理
在这里插入图片描述
在这里插入图片描述

import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

class MyConv(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv2 = nn.Conv2d(3,6,3)

    def forward(self, x):
        # 使用一个2d卷积,输入通道数为3,输出通道数为6,滤波器为3*3
        x = self.conv2(x)
        return x


test_data = torchvision.datasets.CIFAR10("./dataset1",train=False,
                                         transform=torchvision.transforms.ToTensor(),download=True)
dataLoader1 = DataLoader(test_data,batch_size=64)
writer = SummaryWriter("logs")

myconv = MyConv()

step = 0
for data in dataLoader1:
    imgs, targets = data  # img.shape = 64,3,32,32
    writer.add_images("imgs",imgs,step)
    out = myconv(imgs)  # out.shape = 64,6,30,30,不能直接被识别为图像
    # 因此化为两个三通道图片
    out = torch.reshape(out,(-1,3,30,30))
    writer.add_images("out",out,step)
    step += 1

writer.close()

结果:
在这里插入图片描述

14. 最大池化层的使用

在这里插入图片描述

import torchvision.datasets
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter


class MyMaxpool(nn.Module):
    def __init__(self):
        super().__init__()
        # ceil_mode表示是否保存 当池化窗口不满时,窗口中的最大值
        self.maxpool = nn.MaxPool2d(3,ceil_mode=True)

    def forward(self, x):
        x = self.maxpool(x)
        return x

test_data = torchvision.datasets.CIFAR10("./dataset1",train=False,
                                         transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(test_data, batch_size=64)
writer = SummaryWriter("logs_maxpool")

mymaxpool = MyMaxpool()

step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("imgs",imgs, step)
    out = mymaxpool(imgs)
    writer.add_images("out",out,step)
    step += 1

writer.close()

执行结果:
在这里插入图片描述


15. 非线性激活

非线性变换的目的: 为网络引入非线性特征

激活函数作用: 将神经网络的线性模型变为非线性的

ReLU中,inplace的用法
在这里插入图片描述


ReLU与Sigmold的简单使用

import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter


class MyRelu(nn.Module):
    def __init__(self):
        super().__init__()
        # inplace 表示是否用输入的变量接收输出;若为false,则input不变,存在返回值output
        self.relu = ReLU(inplace=False)
        self.sigmoid = Sigmoid()

    def forward(self, x):
        x = self.sigmoid(x)
        return x;

writer = SummaryWriter("logs_relu")
test_data = torchvision.datasets.CIFAR10("./dataset1",train=False,
                                         transform=torchvision.transforms.ToTensor(),download=True)
dataLoader1 = DataLoader(test_data,batch_size=64)

myrelu = MyRelu()

step = 0
for data in dataLoader1:
    imgs, targets = data
    writer.add_images("imgs",imgs,step)
    out = myrelu(imgs)
    writer.add_images("out",out,step)

writer.close()

运行结果:
在这里插入图片描述

16. 线性层及其他层的介绍

线性层,也就等同于全连接层,将一个多维数据拉伸映射为一维

在这里插入图片描述

17. 搭建小实战Sequential的使用

在这里插入图片描述
需要分别计算每个卷积核的padding和stride(卷积后H,W不变,一般padding=(5卷积核宽度-1)的一半),利用公式计算,dilation默认为1。
在这里插入图片描述

import torch
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear


class MySeq(nn.Module):
    def __init__(self):
        super().__init__()
        self.module = Sequential(
            # 卷积过后尺寸不变, padding = (kernel_size - 1) / 2
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),  # 目前为64*4*4,需flatten成线性的
            Flatten(), # => 1024
            Linear(1024,64), # 1024=>64
            Linear(64,10),# 64=> 10
        )

    def forward(self, x):
        x = self.module(x)
        return x

myseq = MySeq()
x = torch.ones((64,3,32,32)) # 训练后 batch_size 不变
print(myseq(x).shape)

在这里插入图片描述

18. 损失函数和反向传播

交叉熵:
在这里插入图片描述

在这里插入图片描述

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

dataset = torchvision.datasets.CIFAR10("dataset1",False,
                                       torchvision.transforms.ToTensor(),download=True)

class MySeq(nn.Module):
    def __init__(self):
        super().__init__()
        self.module = Sequential(
            # 卷积过后尺寸不变, padding = (kernel_size - 1) / 2
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),  # 目前为64*4*4,需flatten成线性的
            Flatten(), # => 1024
            Linear(1024,64), # 1024=>64
            Linear(64,10),# 64=> 10
        )

    def forward(self, x):
        x = self.module(x)
        return x

dataloader = DataLoader(dataset,batch_size=1)

loss = nn.CrossEntropyLoss()  # 交叉熵损失函数
myseq = MySeq()

for data in dataloader:
    imgs, targets = data
    outputs = myseq(imgs)
    result_loss = loss(outputs,targets)
    result_loss.backward() # 反向传播

# loss样例
x = torch.tensor([0.1,0.2,0.3])
x = torch.reshape(x,(1,3))
target = torch.tensor([1])
print(loss(x,target))

运行结果: 与预想一致
在这里插入图片描述

19. 优化器

优化器的作用:
PyTorch的优化器在深度学习模型的训练过程中起着至关重要的作用。它们的主要功能是根据计算得到的梯度信息来更新模型的参数,以最小化损失函数。以下是PyTorch优化器的主要作用:

  • 参数更新:优化器负责根据计算得到的梯度信息更新模型的参数(包括权值)。梯度表示了损失函数关于每个参数的变化率,通过将梯度与学习率相乘,优化器可以决定参数在每个训练步骤中的更新幅度。
  • 学习率调整:优化器还可以控制学习率的调整。学习率决定了参数更新的步长,过大或过小的学习率都可能导致训练不稳定或收敛速度缓慢。一些优化器提供了自适应调整学习率的功能,根据训练进程或其他因素自动调整学习率的大小。
  • 参数优化算法:优化器实现了不同的参数优化算法,如随机梯度下降(SGD)、Adam、Adagrad、RMSprop等。这些算法在计算参数更新时使用不同的策略和规则,以提高训练效果和收敛速度。
  • 动量:一些优化器支持动量的概念,通过引入动量项来加速参数更新。动量可以帮助优化器在参数空间中更快地搜索,并有助于克服局部最小值的困境。

总而言之,PyTorch的优化器在深度学习模型的训练中起着关键的作用,负责根据梯度信息更新模型参数、调整学习率,并利用不同的优化算法和技术来提高训练效果和收敛速度。选择合适的优化器要根据具体的问题和模型特性进行调整和实验

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

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

dataset = torchvision.datasets.CIFAR10("dataset1",False,
                                       torchvision.transforms.ToTensor(),download=True)

class MySeq(nn.Module):
    def __init__(self):
        super().__init__()
        self.module = Sequential(
            # 卷积过后尺寸不变, padding = (kernel_size - 1) / 2
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),  # 目前为64*4*4,需flatten成线性的
            Flatten(), # => 1024
            Linear(1024,64), # 1024=>64
            Linear(64,10),# 64=> 10
        )

    def forward(self, x):
        x = self.module(x)
        return x

dataloader = DataLoader(dataset,batch_size=1)

loss = nn.CrossEntropyLoss()  # 交叉熵损失函数
myseq = MySeq()

optim = SGD(myseq.parameters(), lr=0.01)

for epoch in range(20):
    epoch_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        outputs = myseq(imgs)
        result_loss = loss(outputs,targets)
        optim.zero_grad() # 将梯度清零
        result_loss.backward() # 反向传播,获取梯度
        optim.step() # 利用优化器优化参数
        epoch_loss = epoch_loss + result_loss
    print(epoch_loss) # 输出一个epoch总的损失率

在这里插入图片描述

20. 现用模型的使用及修改

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

from torch import nn
from torchvision.models import vgg16

vgg16_false = vgg16()
# 迁移学习
# 1. 在最后添加一个线性层,将1024=》10
# vgg16_false.classifier.add_module('add_linear',nn.Linear(1000,10))
print(vgg16_false)
# 2. 修改最后一个线性层
vgg16_false.classifier[6] = nn.Linear(4096,10)
print(vgg16_false)

21. 模型保存和模型加载

模型保存

import torch
import torchvision.models

vgg16 = torchvision.models.vgg16()

# 保存方式1:保存整个模型(不推荐)
torch.save(vgg16,"vgg16_method1.pth")

# 保存方式2:仅保存参数(官方推荐)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")

模型加载

import torch
import torchvision

# 加载保存方式1,整个模型
model = torch.load("vgg16_method1.pth")
# print(model)

# 加载保存方式2,导入参数
# torch.load("vgg16_method2.pth") 导入模型的参数
vgg16_2 = torchvision.models.vgg16()
vgg16_2.load_state_dict(torch.load("vgg16_method2.pth"))
print(vgg16_2)

运行结果:
在这里插入图片描述

22. 完整的模型训练套路(一)

训练的代码:

import torchvision.datasets
from torch.nn import CrossEntropyLoss
from torch.optim import SGD
from torch.utils.data import DataLoader
from torchvision import transforms

from model import MyModel

dataset_train = torchvision.datasets.CIFAR10("dataset1",True,transforms.ToTensor(),
                                             download=True)
dataset_test = torchvision.datasets.CIFAR10("dataset1",False,transforms.ToTensor(),
                                            download=True)
train_dataloader = DataLoader(dataset_train,batch_size=64)
test_dataloader = DataLoader(dataset_test,batch_size=64)

# length长度
train_length = len(dataset_train)
test_length = len(dataset_test)
print(f"训练集的长度:{train_length}")
print(f"测试集的长度:{test_length}")

# 创建网络模型
myModel = MyModel()

# 损失函数
loss_func = CrossEntropyLoss()

# 优化器
learning_rate = 1e-2
optimizer = SGD(myModel.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 记录训练的总次数(训练一个batch算一次)
total_train_num = 0
# 记录测试的总次数
total_test_num = 0
# 训练的轮次
epoch = 10

for i in range(10):
    print(f"-----第{i+1}轮训练开始-----")
    for data in train_dataloader:
        imgs, targets = data
        outputs = myModel(imgs)
        loss = loss_func(outputs, targets)  # 输入预测结果和真实结果,得到损失率

        # 优化器优化模型
        optimizer.zero_grad() # 将梯度清零
        loss.backward()  # 反向传播计算梯度
        optimizer.step() # 利用优化器优化参数

        total_train_num = total_train_num + 1
        print(f"训练次数:{total_train_num}, ;loss:{loss.item()}")

model.py

from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear


class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.module = Sequential(
            # 卷积过后尺寸不变, padding = (kernel_size - 1) / 2
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),  # 目前为64*4*4,需flatten成线性的
            Flatten(), # => 1024
            Linear(1024,64), # 1024=>64
            Linear(64,10),# 64=> 10
        )

    def forward(self, x):
        x = self.module(x)
        return x

运行结果:
在这里插入图片描述

23.完整的模型训练套路(二)

with: 上下文管理器,with语句可以自动管理上下文资源,不论是什么原因跳出with块都能确保文件可以正确的关闭 ,以此来达到释放资源的目的。

with torch.no_grad() : 是一个用于临时禁用梯度计算的上下文管理器。

add_scalar: add_scalar() 用于展示标量,数

train()和eval() : 只针对某些层有用,例如drop_out层
在这里插入图片描述

代码:

import torch
import torchvision.datasets
from torch.nn import CrossEntropyLoss
from torch.optim import SGD
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

from model import MyModel

dataset_train = torchvision.datasets.CIFAR10("dataset1",True,transforms.ToTensor(),
                                             download=True)
dataset_test = torchvision.datasets.CIFAR10("dataset1",False,transforms.ToTensor(),
                                            download=True)
train_dataloader = DataLoader(dataset_train,batch_size=64)
test_dataloader = DataLoader(dataset_test,batch_size=64)

# length长度
train_length = len(dataset_train)
test_length = len(dataset_test)
print(f"训练集的长度:{train_length}")
print(f"测试集的长度:{test_length}")

# 创建网络模型
myModel = MyModel()

# 损失函数
loss_func = CrossEntropyLoss()

# 优化器
learning_rate = 1e-2
optimizer = SGD(myModel.parameters(), lr=learning_rate)

# 设置tensorboard可视化
writer = SummaryWriter("logs")

# 设置训练网络的一些参数
# 记录训练的总次数(训练一个batch算一次)
total_train_num = 0
# 记录测试的总次数
total_test_num = 0
# 训练的轮次
epoch = 10

for i in range(10):
    print(f"-----第{i+1}轮训练开始-----")
    # 训练步骤开始
    myModel.train()
    for data in train_dataloader:
        imgs, targets = data
        outputs = myModel(imgs)
        loss = loss_func(outputs, targets)  # 输入预测结果和真实结果,得到损失率

        # 优化器优化模型
        optimizer.zero_grad() # 将梯度清零
        loss.backward()  # 反向传播计算梯度
        optimizer.step() # 利用优化器优化参数

        total_train_num = total_train_num + 1
        if total_train_num % 100 == 0:
            print(f"训练次数:{total_train_num}, ;loss:{loss.item()}")


    # 测试步骤开始
    myModel.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            outputs = myModel(imgs)
            loss = loss_func(outputs, targets)
            total_test_loss = total_test_loss + loss.item() # 计算一epoch中的总损失
            # argmax中 0 表示列比较  1 表示行比较  => 最后得到一行
            accuracy = (outputs.argmax(1) == targets).sum() # 准确个数 为 输出与目标相等数量的总和
            total_accuracy = total_accuracy + accuracy # 计算本轮总命中数

    print(f"整体测试集上的loss:{total_test_loss}")
    print(f"整体测试集上的准确率:{total_accuracy/test_length}")
    writer.add_scalar("test_loss",total_test_loss,i+1)
    writer.add_scalar("test_accuracy", total_accuracy/test_length, i+1)

    # 保存模型
    torch.save(myModel,f"MyModel_{i+1}.pth")
    print("模型已保存")

writer.close()


运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

24. 利用GPU训练(一)

使用方法1:
在这里插入图片描述

# 创建网络模型
myModel = MyModel()
if torch.cuda.is_available():
    myModel = myModel.cuda()

# 损失函数
loss_func = CrossEntropyLoss()
if torch.cuda.is_available():
    loss_func = loss_func.cuda()

imgs, targets = data
if torch.cuda.is_available():
    imgs = imgs.cuda()
    targets = targets.cuda()

不使用GUP的时间:
在这里插入图片描述
使用GPU的时间:
在这里插入图片描述

使用GPU的方法二:
在这里插入图片描述

# 单显卡中cuda:0 == cuda
# device = torch.device("cuda")  写法1
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 常用写法
# 创建网络模型
myModel = MyModel()
myModel = myModel.to(device)

# 损失函数
loss_func = CrossEntropyLoss()
loss_func.to(device)
imgs, targets = data
imgs = imgs.to(device)
targets = targets.to(device)

运行结果:
在这里插入图片描述

25. 完整的模型验证套路

测试的图片:
在这里插入图片描述

import torch
import torchvision.transforms
from PIL import Image
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear


class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.module = Sequential(
            # 卷积过后尺寸不变, padding = (kernel_size - 1) / 2
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),  # 目前为64*4*4,需flatten成线性的
            Flatten(), # => 1024
            Linear(1024,64), # 1024=>64
            Linear(64,10),# 64=> 10
        )

    def forward(self, x):
        x = self.module(x)
        return x

image = Image.open("images/img_1.png")
print(image)
image = image.convert('RGB')  # 将图片转为三通道
# 裁剪为32*32,再转换为Tensor类型
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
                                           torchvision.transforms.ToTensor()])
image = transform(image)
print(image.shape) # 3,32,32

# 加载训练好的模型
# 当在cpu上运行gpu上训练的模型时,需添加map_location参数
model = torch.load("MyModel_30_gpu.pth",map_location="cpu")
print(model)

# 输入应为 B C H W 四维
image = torch.reshape(image,(1,3,32,32))
model.eval()
with torch.no_grad():
    output = model(image)
print(output)
print(output.argmax(1))

运行结果:
在这里插入图片描述

索引与分类的对应关系:
在这里插入图片描述
可知识别正确

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

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

相关文章

【最新】探索CFD的未来:从OpenFOAM到深度学习,全面解析计算流体力学的顶级资源与前沿技术

计算流体力学(CFD)作为现代工程与科学研究的核心工具,正以前所未有的速度迈向智能化与多物理场耦合的新时代。本文全面梳理了在线学习CFD的顶级资源,涵盖了从传统数值模拟到深度学习驱动的物理信息模型的广泛领域,旨在为研究者、工程师和学生提供一站式参考指南。内容分为…

算法专题一:双指针算法(下)

书接上回 5.有效三角形个数 力扣&#xff1a; 有效三角形的个数 在做这道题前我们先讲一个数学知识&#xff1a;已知 a < b < c ,此时 ab>c 可以得出 有效三角形。 所以&#xff0c;我们做这道题时&#xff0c;可以不使用暴力算法。 可以优化为先排序&#xff…

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包&#xff08;内有教程&#xff09; 刷机教程简单说明&#xff1a; 1、把下载好的刷机包&#xff0c;U盘里建立一个upgrade文件夹&#xff0c;固件放入此文件夹里&#xff0c;放入U盘中&#xff0c;注意升级包为压缩包不要对…

T11 TensorFlow入门实战——优化器对比实验

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習紀錄博客&#x1f356; 原作者&#xff1a;K同学啊 | 接輔導、項目定制 一、前期准备 1. 导入数据 # Import the required libraries import pathlib import matplotlib.pyplot as plt import tensorflow as t…

2023年3月全国计算机等级考试真题(二级C语言)

&#x1f600; 第1题 下列叙述中错误的是 A. 向量是线性结构 B. 非空线性结构中只有一个结点没有前件 C. 非空线性结构中只有一个结点没有后件 D. 只有一个根结点和一个叶子结点的结构必定是线性结构 概念澄清 首先&#xff0c;我们需要明确几个关键概念&#xf…

在MFC中使用Qt(四):使用属性表(Property Sheet)实现自动化Qt编译流程

前言 首先回顾下前面文章介绍的&#xff1a; 在MFC中使用Qt&#xff08;一&#xff09;&#xff1a;玩腻了MFC&#xff0c;试试在MFC中使用Qt&#xff01;&#xff08;手动配置编译Qt&#xff09; 在MFC中使用Qt&#xff08;二&#xff09;&#xff1a;实现Qt文件的自动编译流…

Python-八股总结

目录 1 python 垃圾处理机制2 yield3 python 多继承&#xff0c;两个父类有同名方法怎么办&#xff1f;4 python 多线程/多进程/协程4.1 多线程与GIL全局解释器锁4.2 多进程4.3 协程 5 乐观锁/悲观锁6 基本数据结构**1. 列表&#xff08;List&#xff09;****2. 元组&#xff0…

局域网数据同步软件,局域网数据备份的方法

局域网数据备份的方法&#xff1a; 局域网数据备份是确保数据安全性的重要措施&#xff0c;以下是一些常用的局域网数据备份方法&#xff1a; 1.使用NAS设备备份 特点&#xff1a;网络附加存储&#xff08;NAS&#xff09;设备提供了一种便捷的备份方式。 操作&#xff1a;…

座舱与智驾“双轮驱动”,芯擎科技打造智能汽车“芯”标杆

在比亚迪、吉利、奇瑞等各大主机厂打响“全民智驾”的关键时期&#xff0c;以芯擎科技为代表中国芯片厂商开始“放大招”。 2025年3月27日&#xff0c;芯擎科技在南京举办了“擎随芯动、智融万象”生态科技日&#xff0c;重磅发布了“星辰一号”、“星辰一号Lite”&#xff0c…

《新能源汽车 DEEA 平台开发策略》

一、引言 在新能源汽车行业加速向智能化、电动化转型的当下&#xff0c;电子电气架构&#xff08;EEA&#xff09;成为汽车技术创新的关键领域。DEEA 平台作为应对行业变革的重要举措&#xff0c;其开发策略对于提升汽车产品竞争力、满足市场多样化需求意义重大。本策略围绕平台…

从零开始:Windows 系统中 PowerShell 配置 FFmpeg 的详细步骤

在Windows系统中不想每次都 cd 到FFmpeg目录中应用&#xff0c;现在可以通过PowerShell在任意目录下应用了。 PowerShell 基础概念 跨平台脚本工具 PowerShell 是微软开发的命令行外壳和脚本语言&#xff0c;支持 Windows、Linux 和 macOS 系统。其核心优势在于面向对象的操作…

Java-拼图小游戏跟学笔记

阶段项目-01-项目介绍和界面搭建_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV17F411T7Ao?p144 代码 1.主界面分析(组件) JFrame:最外层的窗体 JMenuBar:最上层的菜单 JLabel:管理文字和图片的容器 1.界面 --关闭模式-- DO_NOTHING_ON_CLOSE&#xff1a;当用户…

phpStorm2021.3.3在windows系统上配置Xdebug调试

开始 首先根据PHP的版本下载并安装对应的Xdebug扩展在phpStorm工具中找到设置添加服务添加php web page配置完信息后 首先根据PHP的版本下载并安装对应的Xdebug扩展 我使用的是phpStudy工具&#xff0c;直接在php对应的版本中开启xdebug扩展&#xff0c; 并在php.ini中添加如下…

FALL靶机

下载靶机&#xff0c;可以看到靶机地址 在kali上扫描靶机的端口和目录文件 访问&#xff1a;http://192.168.247.146/test.php&#xff0c;他提示我们参数缺失 我们爆破一下他的参数 使用kali自带的fuzz FUZZ就是插入参数的位置 -w 指定字典文件 wfuzz -u "http://192.…

QT文件操作(QT实操学习3)

1.项目架构 1.UI界面 1.新建文本文档 2.打开文件 3.另存为文件 2.mainwindow.h​ #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QFileDialog> #include <QMessageBox> #include <QDebug> QT_BEGIN_NAMESPACE namespa…

智能粉尘监测解决方案|守护工业安全,杜绝爆炸隐患

在厂房轰鸣的生产线上&#xff0c;一粒微小粉尘的聚集可能成为一场灾难的导火索。如何实现粉尘浓度的精准监控与快速响应&#xff1f;我们为您打造了一套"感知-预警-处置"全闭环的智能安全方案&#xff01; 行业痛点&#xff1a;粉尘管理的生死线 在金属加工、化工…

阿里 FunASR 开源中文语音识别大模型应用示例(准确率比faster-whisper高)

文章目录 Github官网简介模型安装非流式应用示例流式应用示例 Github https://github.com/modelscope/FunASR 官网 https://www.funasr.com/#/ 简介 FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端…

漏洞预警 | Windows 文件资源管理器欺骗漏洞(CVE-2025-24071、CVE-2025-24054)

1漏洞概述 漏洞类型 信息泄露 漏洞等级 高 漏洞编号 CVE-2025-24071、 CVE-2025-24054 漏洞评分 7.5 利用复杂度 中 影响版本 Windows三月更新前版本 利用方式 本地 POC/EXP 已公开 近日&#xff0c;微软发布windows操作系统更新修复漏洞&#xff0c;其中Windo…

redis 缓存命中率降低,该如何解决?

命中率降低 Redis 缓存命中率降低&#xff0c;可能是由于多个因素导致的&#xff0c;比如缓存未命中、缓存污染、缓存淘汰过快等。针对不同情况&#xff0c;可以采取以下优化措施&#xff1a; 1. 分析缓存命中率下降的原因 在优化之前&#xff0c;先使用 Redis 监控工具 分析…

LiteDB 数据存储与检索效率优化的最佳实践指导

一、引言 在当今数字化时代,数据处理和存储变得至关重要。对于小型项目或者嵌入式系统而言,需要一种轻量级、高效且易于使用的数据库解决方案。LiteDB 作为一款嵌入式的 NoSQL 数据库,因其零配置、易于集成等特点,受到了开发者的青睐。然而,若要充分发挥其性能优势,就需…