pytroch使用

PyTroch深度学习快速入门教程

笔记总结于B站up主:@我是土堆 的PyTorch教程视频:PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】_哔哩哔哩_bilibili

个人实现的代码地址:file/PyTorch教程代码 · umi-ushio/我的笔记 - 码云 - 开源中国
Transformers教程第六章:必要的Pytorch知识

1. pytorch加载数据 - Dataset - Dataloader

Dataset: 提供一种方式去获取数据及其label

Dataloader: 为后面的网络提供不同的数据形式

显示帮助信息:

help(Dataset)

Dataset??  (在jupyter中有效)

Dataset使用方法:继承后重写

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


class MyDataset(Dataset):

    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.images = os.listdir(self.path)

    def __getitem__(self, index):
        img_path = os.path.join(self.path, self.images[index])
        img = Image.open(img_path)
        return img, self.label_dir

    def __len__(self):
        return len(self.images)


root_dir = "./dataset/train"
ants_label = "ants"
bees_label = "bees"

ants_dataset = MyDataset(root_dir, ants_label)
bees_dataset = MyDataset(root_dir, bees_label)
print("all_dataset:%s" % len(ants_dataset))
print("bees_dataset:%s" % len(bees_dataset))

all_dataset = ants_dataset + bees_dataset
print("all_dataset:%s" % len(all_dataset))

img, label = all_dataset[125]
img.show()
print(label)

2. TensorBoard

  • 简单使用
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter("logs")

writer.add_image()
writer.add_scalar()

writer.close()
  • add_scalar()
for i in range(100):
    writer.add_scalar("x=y", i, i)
  • 打开Tendorboard (在控制台窗口中)
tensorboard --logdir=logs --port=6006

image-20241105150516898

  • add_image()
img_path = "./dataset/train/ants/0013035.jpg"
img_PIL = Image.open(img_path)
img_array = np.array(img_PIL)

writer.add_image("test2", img_array, 1, dataformats="HWC" )

img_path2 = "./dataset/train/ants/9715481_b3cb4114ff.jpg"
img_PIL2 = Image.open(img_path2)
img_array2 = np.array(img_PIL2)
writer.add_image("test2", img_array2, 2, dataformats="HWC" )

image-20241105153105862

3. torchvision中transforms

transform主要用于对一些图片进行变换

image-20241105154142564

  • transforms.ToTensor的使用
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter

from torch练习.TensorBoard使用 import writer

img_path = "./dataset/train/ants/175998972.jpg"
img_PIL = Image.open(img_path)

# 如何使用transforms.ToTensor
trans_tensor = transforms.ToTensor()
img_tensor = trans_tensor(img_PIL)

writer = SummaryWriter("logs")
writer.add_image("test image tensor", img_tensor)
writer.close()

image-20241105161059382

  • Transforms.Normalize使用
img_path = "./dataset/train/ants/175998972.jpg"
img_PIL = Image.open(img_path)

# ToTensor的使用
trans_tensor = transforms.ToTensor()
img_tensor = trans_tensor(img_PIL)

print(img_tensor[0][0][0])
# Normalize的使用 output[channel] = (input[channel] - mean[channel]) / std[channel]
trans_normal = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_normal = trans_normal(img_tensor)
print(img_normal[0][0][0])

writer = SummaryWriter("logs")
writer.add_image("test image Normalize", img_normal)
writer.close()

image-20241106103144878

  • transforms.Resize的使用
img_path = "./dataset/train/ants/175998972.jpg"
img_PIL = Image.open(img_path)

# ToTensor的使用
trans_tensor = transforms.ToTensor()
img_tensor = trans_tensor(img_PIL)

print(img_PIL.size)
# Resize的使用
# imgPIL -> Resize -> imgPIL
trans_resize = transforms.Resize((256, 256))
img_resize = trans_resize(img_PIL)
print(img_resize.size)
img_resize_tensor = trans_tensor(img_resize)

writer = SummaryWriter("logs")
writer.add_image("test image resize", img_resize_tensor)
writer.close()

image-20241106104612105

  • Compose和Resize的使用
img_path = "./dataset/train/ants/175998972.jpg"
img_PIL = Image.open(img_path)

# ToTensor的使用
trans_tensor = transforms.ToTensor()
img_tensor = trans_tensor(img_PIL)
# Compose和Resize的使用,不改变长宽比
trans_resize2 = transforms.Resize(128)
trans_compose = transforms.Compose([trans_resize2, trans_tensor])
img_compose = trans_compose(img_PIL)

writer = SummaryWriter("logs")
writer.add_image("test image compose and resize", img_compose)
writer.close()

image-20241106105900418

  • RandomCrop
img_path = "./dataset/train/bees/85112639_6e860b0469.jpg"
img_PIL = Image.open(img_path)
writer = SummaryWriter("logs")

# ToTensor的使用
trans_tensor = transforms.ToTensor()
img_tensor = trans_tensor(img_PIL)

# RandomCrop
trans_random = transforms.RandomCrop((128, 128))
trans_compose_random = transforms.Compose([trans_random, trans_tensor])
for i in range(10):
    img_compose_random = trans_compose_random(img_PIL)
    writer.add_image("test RandomCrop", img_compose_random, i)

writer.close()

image-20241106111039936

4. torchvision中数据集的使用

  • datasets.CIRAR10
import torchvision

# 会自动下载数据集, root:保存的目录,train:是否是训练数据集, download:是否自动下载
train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, download=True)

print(train_set[0])
img, target = train_set[0]
print(train_set.classes)
print("target=%s, classes=%s" % (target, train_set.classes[target]))
img.show()
  • 将数据集转为Tensor类型
import torchvision

trans_compose = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor(),
])

# 将数据集转为Tensor类型
train_set = torchvision.datasets.CIFAR10(root="./dataset", transform=trans_compose, train=True, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", transform=trans_compose, train=False, download=True)

from torch.utils import tensorboard
writer = tensorboard.SummaryWriter(log_dir='./logs')

for i in range(100):
    img, target = train_set[i]
    writer.add_image('test torchvision.dataset', img, i)

writer.close()

image-20241106135627978

5. Dataloader的使用

Dataloader的作用:将dataset数据集按**batch_size进行划分,分别将图片数据标签数据**进行打包,供后面训练数据进行使用。

  • 将数据打印到控制台
import torchvision
from torch.utils.data import DataLoader
from torchvision.transforms import transforms

test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=transforms.ToTensor())

# 使用Dataloader
# dataset:要操作的数据集
# batch_size:划分的大小
# shuffle:数据集是否重新洗牌
# drop_last: 最后划分后,不满足batch_size大小的数据集是否丢弃
img_dataloader = DataLoader(dataset=test_set, batch_size=4, shuffle=True, drop_last=False)

# 查看dataset中第一个数据
img, target = test_set[0]
print("dataset - img.shape:%s, target:%s" % (img.shape, target))

for datas,targets in img_dataloader:
    print("dataloader - datas.shape:%s, targets:%s" % (datas.shape, targets))

输出结果:

dataset - img.shape:torch.Size([3, 32, 32]), target:3
dataloader - datas.shape:torch.Size([4, 3, 32, 32]), targets:tensor([8, 9, 7, 8])
dataloader - datas.shape:torch.Size([4, 3, 32, 32]), targets:tensor([3, 0, 2, 7])
dataloader - datas.shape:torch.Size([4, 3, 32, 32]), targets:tensor([4, 9, 2, 9])
......
  • 将数据输出到tensorboard
import torchvision
from torch.utils.data import DataLoader
from torchvision.transforms import transforms

test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=transforms.ToTensor())

# 使用Dataloader
# dataset:要操作的数据集
# batch_size:划分的大小
# shuffle:数据集是否重新洗牌
# drop_last: 最后划分后,不满足batch_size大小的数据集是否丢弃
img_dataloader = DataLoader(dataset=test_set, batch_size=128, shuffle=True, drop_last=False)

# 查看dataset中第一个数据
img, target = test_set[0]
print("dataset - img.shape:%s, target:%s" % (img.shape, target))

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("dataloader的使用logs")

count = 0
for datas,targets in img_dataloader:
    writer.add_images("test dataloader1", datas, count)
    count += 1

writer.close()

image-20241107140007912

6. 神经网络的基本骨架 nn.Module的使用

pycharm重写方法快捷键:Ctrl + O, 实现方法快捷键:Ctrl + L

  • 官方文档中的简单使用
import torch.nn as nn
import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 50, 5)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        return F.relu(self.conv2(x))
  • Moduled的简单使用
import torch
import torch.nn as nn

class MyModule(nn.Module):
    def __init__(self,) -> None:
        super().__init__()

    def forward(self, x):
        x = x + 1
        return x

mymodel = MyModule()
result = mymodel(torch.tensor(1))
print("result:%s" % result)

7. torch卷积操作

image-20241109110030708

import torch
import torch.nn.functional as F

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 = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))
print(input.shape)
print(kernel.shape)

output = F.conv2d(input, kernel, stride=1)
print(output)

image-20241109105209472

8. 神经网络 - 卷积层

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

# 加载CIFAR10数据集
dataset = CIFAR10(root="./dataset", train=False, transform=transforms.ToTensor(), download=True)
# 设置batch_size=64的dataloader
dl = DataLoader(dataset, batch_size=64, shuffle=True)

class Tudui(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=3, padding=0, stride=1)

    def forward(self, input):
        return self.conv1(input)

writer = SummaryWriter(log_dir="./logs")
count = 1
tudui = Tudui()
for data in dl:
    imgs, targets = data
    print(imgs.shape)
    output = tudui(imgs)
    print(output.shape)

    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("tudui", output, count)
    count += 1

writer.close()

image-20241115131819599

image-20241115131838286

9. 池化层

池化层意义:保留最大特征,减小数据量

image-20241115135039622

import torch.nn as nn
import torch

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]
], dtype=torch.float32)
input = torch.reshape(input, (-1, 1, 5, 5))
print(input.shape)

class MyMaxPool(nn.Module):
    def __init__(self):
        super().__init__()
        self.maxpool = nn.MaxPool2d(kernel_size=3, ceil_mode=True)

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

mpool = MyMaxPool()
output = mpool(input)
print(output)

image-20241115140642225

  • 对图片进行池化操作
import torch.nn as nn
from torch.utils.tensorboard import SummaryWriter
import torch
from PIL import Image
from torchvision import transforms

class MyMaxPool(nn.Module):
    def __init__(self):
        super().__init__()
        self.maxpool = nn.MaxPool2d(kernel_size=16, ceil_mode=True)

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

mpool = MyMaxPool()
original_img = Image.open("./dataset/mashu.jpg")
tensor_img = transforms.ToTensor()(original_img)
reshape_tensor_img = torch.reshape(tensor_img, (-1, 3, 1024, 1024))
output_img = mpool(reshape_tensor_img)

writer = SummaryWriter("./logs")
writer.add_image("原图片-麻薯", tensor_img)
writer.add_images("最大池化后-麻薯", output_img)
writer.close()

image-20241115142422446

10. 神经网络 - 非线性激活

import torch.nn as nn
import torch

class MyRelu(nn.Module):
    def __init__(self):
        super(MyRelu, self).__init__()
        # inplace是否对原数据进行替换
        self.relu = nn.ReLU(inplace=False)

    def forward(self, x):
        return self.relu(x)

input = torch.tensor([
    [1, -0.5],
    [-1, 3]
])
input = input.reshape((-1, 1, 2, 2))
myrelu = MyRelu()
output = myrelu(input)
print(output)

image-20241115144458412

  • Sigmod非线性激活函数对图片进行处理
import torch.nn as nn
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

from torch练习.torchvision中的dataset.nn_maxpool import original_img


class MyRelu(nn.Module):
    def __init__(self):
        super(MyRelu, self).__init__()
        # inplace是否对原数据进行替换
        # self.relu = nn.ReLU(inplace=False)
        self.sigmoid = nn.Sigmoid()

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

myrelu = MyRelu()

original_img = Image.open("./dataset/mashu.jpg")
tensor_img = transforms.ToTensor()(original_img)
tensor_img = tensor_img.reshape(-1, 1, 1024, 1024)
output_img = myrelu(tensor_img)

writer = SummaryWriter("./logs")
writer.add_image("sigmoid 麻薯", output_img[1])
writer.close()

image-20241115145046200

11. 神经网络 - 线性层及其他层介绍

  • Linear 及 torch.flatten() 方法的使用
import torch
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader
from torch.nn import Linear, Module

dataset = torchvision.datasets.CIFAR10(root="./dataset",
                                       train=False,
                                       transform=transforms.ToTensor(),
                                       download=True)
# drop_last:丢弃最后不满足batch_size=64的数据,不使用的话会造成最后一组数据和线性层匹配不上
dataloader = DataLoader(dataset, batch_size=64, shuffle=True, drop_last=True)

class MyLinear(Module):
    def __init__(self):
        super(MyLinear, self).__init__()
        self.linear = Linear(in_features=196608, out_features=10)

    def forward(self, x):
        return self.linear(x)

mylinear = MyLinear()

for data in dataloader:
    imgs, targets = data
    # 这样使用没有问题
    # imgs = imgs.reshape((1, 1, 1, -1))
    # imgs = imgs.reshape((1, -1))
    # 或是使用flatten()方法,将数据摊平成一行
    imgs = torch.flatten(imgs)
    print(imgs.shape)
    x = mylinear(imgs)
    print(x.shape)

image-20241116171357417

12. 神经网络 - 神经网络模型搭建及Sequential()的使用

cifar-10模型结构可视化_cifar10 model structure

  • 没有使用Sequential
from torch.nn import Linear, Module, Flatten, MaxPool2d, Conv2d
import torch

class MyCifarModel(Module):
    def __init__(self):
        super(MyCifarModel, self).__init__()
        self.conv1 = Conv2d(3, 32, 3, padding=2)
        self.pool1 = MaxPool2d(2)
        self.conv2 = Conv2d(32, 32, 5, padding=2)
        self.pool2 = MaxPool2d(2)
        self.conv3 = Conv2d(32, 64, 5, padding=2)
        self.pool3 = MaxPool2d(2)
        self.flatten = Flatten()
        self.linear1 = Linear(1024, 64)
        self.linear2 = Linear(64, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.conv3(x)
        x = self.pool3(x)
        x = self.flatten(x)
        x = self.linear1(x)
        x = self.linear2(x)
        return x

my_model = MyCifarModel()
print(my_model)

# 使用生成数据来测试
x = torch.ones(1, 3, 32, 32)
y = my_model(x)
print(y.shape)

image-20241116180250220

  • 使用Sequential
from torch.nn import Linear, Module, Flatten, MaxPool2d, Conv2d, Sequential
import torch

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

    def forward(self, x):
        return self.model1(x)

my_model = MyCifarModel()
print(my_model)

# 使用生成数据来测试
x = torch.ones(1, 3, 32, 32)
y = my_model(x)
print(y.shape)

image-20241116180524929

13. 损失函数和反向传播

  • L1损失函数 和 MSE损失函数

L1损失函数,MSE损失函数

import torch
from torch.nn import L1Loss, MSELoss

inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)

# 不需要reshape()也可以
inputs = torch.reshape(inputs, (1, 1, 1, 3))
targets = torch.reshape(targets, (1, 1, 1, 3))

l1loss = L1Loss(reduction='mean')
output = l1loss(inputs, targets)

mseloss = MSELoss()
mse_output = mseloss(inputs, targets)

print(output)
print(mse_output)

image-20241118114808330

  • 交叉商损失函数 - 用在分类问题中

交叉熵损失函数

import torch
from torch.nn import L1Loss, MSELoss, CrossEntropyLoss

x = torch.tensor([0.1, 0.2, 0.3])
x = x.reshape((1, -1))
y = torch.tensor([1])

# -0.2 + log(exp(0.1) + exp(0.2) + exp(0.3))
cel = CrossEntropyLoss()
z = cel(x, y)
print(z)

image-20241118115738224

  • 使用CIFAR10数据集进行反向传播
from torchvision import transforms
from torchvision.datasets import CIFAR10
from torch.nn import Linear, Module, Flatten, MaxPool2d, Conv2d, Sequential, CrossEntropyLoss
import torch

dataset = CIFAR10(root="./dataset", train=False, transform=transforms.ToTensor())
dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=True)

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

    def forward(self, x):
        return self.model1(x)

my_model = MyCifarModel()
cel = CrossEntropyLoss()

for data in dataloader:
    imgs, labels = data
    outputs = my_model(imgs)
    loss = cel(outputs, labels)
    # 使用损失函数进行反向传播
    loss.backward()
    print(loss)

image-20241118120421297

14. 优化器

from torchvision import transforms
from torchvision.datasets import CIFAR10
from torch.nn import Linear, Module, Flatten, MaxPool2d, Conv2d, Sequential, CrossEntropyLoss
import torch

dataset = CIFAR10(root="./dataset", train=False, transform=transforms.ToTensor())
dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=True)

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

    def forward(self, x):
        return self.model1(x)

my_model = MyCifarModel()
cel = CrossEntropyLoss()
optim = torch.optim.SGD(my_model.parameters(), lr=0.01)

for epoch in range(20):
    total_loss = 0.0
    for data in dataloader:
        imgs, labels = data
        outputs = my_model(imgs)
        loss = cel(outputs, labels)

        optim.zero_grad()
        # 使用损失函数进行反向传播
        loss.backward()
        optim.step()
        total_loss += loss.item()
    print(total_loss)

image-20241118123906695

15. 现有模型的使用及修改

import torchvision
import torch
from torchvision.models import VGG16_Weights

vgg16_false = torchvision.models.vgg16()
# 之前的pretrained属性已经启用,会去下载预训练的模型数据
vgg16_true = torchvision.models.vgg16(weights=VGG16_Weights.IMAGENET1K_FEATURES)

# 给模型添加操作
vgg16_false.add_module("add_linear", torch.nn.Linear(1000, 10))
# 给classifier中添加操作
vgg16_false.classifier.add_module("7", torch.nn.Linear(1000, 10))
# 修改classifier中的操作
vgg16_false.classifier[6] = torch.nn.Linear(4096, 10)
print(vgg16_false)

image-20241120144829831

16. 网络模型的保存与读取

import torch
import torchvision

vgg16 = torchvision.models.vgg16()

# 保存方式1,模型参数+模型结构
torch.save(vgg16, "model_method1.pth")
# 自己创建的模型加载时需要注意要把自己的模型导入进来,否则会找不到对应的模型
model = torch.load("model_method1.pth")

# 保存方式2,模型参数(官方推荐方式)
torch.save(vgg16.state_dict(), "model_method2.pth")
# 加载时需要创建模型,让模型加载参数
state_dict = torch.load("model_method2.pth")
vgg16_2 = torchvision.models.vgg16()
vgg16_2.load_state_dict(state_dict)

17. 完整的模型训练步骤

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


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

    def forward(self, x):
        return self.model1(x)

if __name__ == '__main__':
    x = torch.ones(64, 3, 32, 32)
    mymodel = CIFAR10Model()
    y = mymodel(x)
    print(y.shape)

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

import MyModel

train_dataset = CIFAR10("./dataset",
                         transform=ToTensor(),
                         train=True,
                         download=True)
test_dataset = CIFAR10("./dataset",
                         transform=ToTensor(),
                         train=False,
                         download=True)
# 训练集和测试集的大小
len_train_dataset = len(train_dataset)
len_test_dataset = len(test_dataset)
print(f"训练集的数据量大小为:{len_train_dataset}")
print(f"训练集的数据量大小为:{len_test_dataset}")

# 训练的batch数据集
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=True)

# 学习率,epoch
learning_rate = 1e-2
epoch = 10

# 创建模型,损失函数,优化器
my_model = MyModel.CIFAR10Model()
loss_func = CrossEntropyLoss()
optimizer = SGD(my_model.parameters(), lr=learning_rate)

# 轮数
count = 0

# 数据记入tensorboard
writer = SummaryWriter('./log')

# 训练过程
for i in range(epoch):
    start_time = time.time()
    for images, labels in train_dataloader:
        optimizer.zero_grad()
        outputs = my_model(images)
        loss = loss_func(outputs, labels)
        loss.backward()
        optimizer.step()

        # 打印第几轮学习
        if count % 100 == 0:
            print(f"----------第{i + 1}轮训练, 第{count}轮batch, 损失值:{loss.item()}------------")
            writer.add_scalar('train_loss', loss.item(), count)
        count += 1

    print(f"----------第{i+1}轮epoch训练用时:{time.time() - start_time}s--------")
    # 每个epoch训练完成后保存模型
    torch.save(my_model, f"my_model_{i+1}.pth" )

    correct = 0
    test_loss = 0
    # 测试集准确率
    with torch.no_grad():
        for images, labels in test_dataloader:
            outputs = my_model(images)
            correct += (outputs.argmax(1) == labels).sum()

            test_loss += loss_func(outputs, labels).item()

    print(f"测试集总损失值:{test_loss}, 准确率:{correct/len_test_dataset*100 :.2f}%")
    writer.add_scalar('test_lossasdfasdf', test_loss, i)


writer.close()

image-20241120185242951

18. 使用GPU进行训练

image-20241120185654326

  • 方式一 xxx.cuda()
import torch
import torchvision
from torch.nn import CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor
from torch.optim import SGD
import time

import MyModel

train_dataset = CIFAR10("./dataset",
                         transform=ToTensor(),
                         train=True,
                         download=True)
test_dataset = CIFAR10("./dataset",
                         transform=ToTensor(),
                         train=False,
                         download=True)
# 训练集和测试集的大小
len_train_dataset = len(train_dataset)
len_test_dataset = len(test_dataset)
print(f"训练集的数据量大小为:{len_train_dataset}")
print(f"训练集的数据量大小为:{len_test_dataset}")

# 训练的batch数据集
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=True)

# 学习率,epoch
learning_rate = 1e-2
epoch = 10

# 创建模型,损失函数,优化器
my_model = MyModel.CIFAR10Model()
# 也可以直接  my_model.cuda()
if torch.cuda.is_available():
    my_model = my_model.cuda()
loss_func = CrossEntropyLoss()
# 也可以直接  loss_func.cuda()
if torch.cuda.is_available():
    loss_func = loss_func.cuda()
optimizer = SGD(my_model.parameters(), lr=learning_rate)

# 轮数
count = 0

# 数据记入tensorboard
writer = SummaryWriter('./log')

# 训练过程
for i in range(epoch):
    start_time = time.time()
    for images, labels in train_dataloader:
        if torch.cuda.is_available(): # 将数据集放到GPU上
            images, labels = images.cuda(), labels.cuda()

        optimizer.zero_grad()
        outputs = my_model(images)
        loss = loss_func(outputs, labels)
        loss.backward()
        optimizer.step()

        # 打印第几轮学习
        if count % 100 == 0:
            print(f"----------第{i + 1}轮训练, 第{count}轮batch, 损失值:{loss.item()}------------")
            writer.add_scalar('train_loss', loss.item(), count)
        count += 1

    print(f"----------第{i+1}轮epoch训练用时:{time.time() - start_time :.2f}s--------")
    # 每个epoch训练完成后保存模型
    torch.save(my_model, f"my_model_{i+1}.pth" )

    correct = 0
    test_loss = 0
    # 测试集准确率
    with torch.no_grad():
        for images, labels in test_dataloader:
            if torch.cuda.is_available():# 将数据集放到GPU上
                images, labels = images.cuda(), labels.cuda()

            outputs = my_model(images)
            correct += (outputs.argmax(1) == labels).sum()

            test_loss += loss_func(outputs, labels).item()

    print(f"测试集总损失值:{test_loss}, 准确率:{correct/len_test_dataset*100 :.2f}%")
    writer.add_scalar('test_lossasdfasdf', test_loss, i)


writer.close()
  • 方式二 device = torch.device(); xxx.to(device);
import torch
import torchvision
from torch.nn import CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor
from torch.optim import SGD
import time

import MyModel

train_dataset = CIFAR10("./dataset",
                         transform=ToTensor(),
                         train=True,
                         download=True)
test_dataset = CIFAR10("./dataset",
                         transform=ToTensor(),
                         train=False,
                         download=True)
# 训练集和测试集的大小
len_train_dataset = len(train_dataset)
len_test_dataset = len(test_dataset)
print(f"训练集的数据量大小为:{len_train_dataset}")
print(f"训练集的数据量大小为:{len_test_dataset}")

# 设置训练的设备
# 如果只有一个GPU也可以:torch.device("cuda:0") 相同  torch.device("cuda")
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 训练的batch数据集
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=True)

# 学习率,epoch
learning_rate = 1e-2
epoch = 10

# 创建模型,损失函数,优化器
my_model = MyModel.CIFAR10Model()
# 也可以直接  my_model.to(device)
if torch.cuda.is_available():
    my_model = my_model.to(device)
loss_func = CrossEntropyLoss()
# 也可以直接  loss_func.to(device)
if torch.cuda.is_available():
    loss_func = loss_func.to(device)
optimizer = SGD(my_model.parameters(), lr=learning_rate)

# 轮数
count = 0

# 数据记入tensorboard
writer = SummaryWriter('./log')

# 训练过程
for i in range(epoch):
    start_time = time.time()
    for images, labels in train_dataloader:
        if torch.cuda.is_available(): # 将数据集放到GPU上
            images, labels = images.to(device), labels.to(device)

        optimizer.zero_grad()
        outputs = my_model(images)
        loss = loss_func(outputs, labels)
        loss.backward()
        optimizer.step()

        # 打印第几轮学习
        if count % 100 == 0:
            print(f"----------第{i + 1}轮训练, 第{count}轮batch, 损失值:{loss.item()}------------")
            writer.add_scalar('train_loss', loss.item(), count)
        count += 1

    print(f"----------第{i+1}轮epoch训练用时:{time.time() - start_time :.2f}s--------")
    # 每个epoch训练完成后保存模型
    torch.save(my_model, f"my_model_{i+1}.pth" )

    correct = 0
    test_loss = 0
    # 测试集准确率
    with torch.no_grad():
        for images, labels in test_dataloader:
            if torch.cuda.is_available():# 将数据集放到GPU上
                images, labels = images.to(device), labels.to(device)

            outputs = my_model(images)
            correct += (outputs.argmax(1) == labels).sum()

            test_loss += loss_func(outputs, labels).item()

    print(f"测试集总损失值:{test_loss}, 准确率:{correct/len_test_dataset*100 :.2f}%")
    writer.add_scalar('test_lossasdfasdf', test_loss, i)

writer.close()

19. 完整的模型验证步骤

import torch

from MyModel import CIFAR10Model
from torchvision.transforms import Compose, ToTensor, Resize
from PIL import Image

img_path = "./dataset/img.png"
img = Image.open(img_path)
# png为4个通道,因此需要转为三通道
img = img.convert("RGB")
print(img)

img_compose = Compose([
    Resize((32, 32)),
    ToTensor(),
])

img_tensor = img_compose(img)
img_tensor = img_tensor.reshape(1, 3, 32, 32)

# 如果是在GPU上训练的模型,需要转为Cpu上的模型
model = torch.load("./my_model_6139.pth", map_location=torch.device('cpu'))
index = model(img_tensor).argmax()
print(index)

h训练用时:{time.time() - start_time :.2f}s--------“)
# 每个epoch训练完成后保存模型
torch.save(my_model, f"my_model_{i+1}.pth” )

correct = 0
test_loss = 0
# 测试集准确率
with torch.no_grad():
    for images, labels in test_dataloader:
        if torch.cuda.is_available():# 将数据集放到GPU上
            images, labels = images.to(device), labels.to(device)

        outputs = my_model(images)
        correct += (outputs.argmax(1) == labels).sum()

        test_loss += loss_func(outputs, labels).item()

print(f"测试集总损失值:{test_loss}, 准确率:{correct/len_test_dataset*100 :.2f}%")
writer.add_scalar('test_lossasdfasdf', test_loss, i)

writer.close()




### 19. 完整的模型验证步骤

```python
import torch

from MyModel import CIFAR10Model
from torchvision.transforms import Compose, ToTensor, Resize
from PIL import Image

img_path = "./dataset/img.png"
img = Image.open(img_path)
# png为4个通道,因此需要转为三通道
img = img.convert("RGB")
print(img)

img_compose = Compose([
    Resize((32, 32)),
    ToTensor(),
])

img_tensor = img_compose(img)
img_tensor = img_tensor.reshape(1, 3, 32, 32)

# 如果是在GPU上训练的模型,需要转为Cpu上的模型
model = torch.load("./my_model_6139.pth", map_location=torch.device('cpu'))
index = model(img_tensor).argmax()
print(index)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值