【Pytorch】小土堆笔记(未完成)

transforms

在训练的过程中,神经网络模型接收的数据类型是 Tensor,而不是 PIL 对象,因此我们还需要对数据进行预处理操作,比如图像格式的转换。

同时我们可以对图片进行一系列图像变换与增强操作,例如裁切边框、调整图像比例和大小、标准化等,以便模型能够更好地学习到数据的特征。

这些操作都可以通过torchvision.transforms来完成,所以transforms可以理解为图像预处理工具包。

transforms具体用法可以参照:3.2 PyTorch_Torchvision-02:transforms - 知乎 (zhihu.com)

dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()])

train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform, download=True)

Compose可以将各种操作组合在一起,在数据里量足够的情况下我们一般使用ToTensor足够,不需要进行图片增强操作,所以我们可以简写:

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

dataloader

① Dataset只是去告诉我们程序,我们的数据集在什么位置,数据集第一个数据给它一个索引0,它对应的是哪一个数据。

② Dataloader就是把数据加载到神经网络当中,Dataloader所做的事就是每次从Dataset中取数据,至于怎么取,是由Dataloader中的参数决定的。

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

test_loader = DataLoader(test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=True)

这里的四个参数,分别解释一下:

batch_size 就是每批次大小

shuffle 是否打乱数据,推荐设置为True

num_workers 这个参数决定了有几个进程来处理data loading。0意味着所有的数据都会被load进主进程。(默认为0)

drop_last 如果设置为True:这个是对最后的未完成的batch来说的,比如你的batch_size设置为64,而一个epoch只有100个样本,那么训练的时候后面的36个就被扔掉了…
如果为False(默认),那么会继续正常执行,只是最后的batch_size会小一点(也有可能会报错)

在加载数据集后,我们可以使用以下结构来访问每一批数据的内容。

writer = SummaryWriter("logs/11_dataloader")
# 测试数据集使用dataLoder后的结果
step = 0
for data in test_loader:
    imgs, targets = data
    # print(imgs.shape)
    # print(targets)
    writer.add_images("Epoch:{}".format(), imgs, step)
    step = step+1
writer.close()

加载、修改、保存模型

import torchvision
from torch import nn

vgg16 = torchvision.models.vgg16(weights= torchvision.models.VGG16_Weights.DEFAULT)

train_data = torchvision.datasets.CIFAR10("../dataset", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)

# x下面的几种常见的修改方式,效果都一样

# vgg16.add_module('add_linear', nn.Linear(1000, 10))
# print(vgg16)
#
# vgg16.classifier.add_module('add_linear', nn.Linear(1000, 10))
# print(vgg16)

vgg16.classifier[6] = nn.Linear(4096, 10)
import torch
import torchvision

vgg16 = torchvision.models.vgg16()

# 保存方式 1 模型结构+模型参数
torch.save(vgg16, "vgg16_method1.pth")
# 读取方式
model1 = torch.load("vgg16_method1.pth")
#print(model1)

# 保存方式 2 模型参数(官方推荐)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")
# 读取方式
vgg16_new = torchvision.models.vgg16()
vgg16_new.load_state_dict(torch.load("vgg16_method2.pth"))
# vgg16_new = torch.load("vgg16_method2.pth")
print(vgg16_new)

模型的训练(cpu)

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

from model import MyModel
# 准备数据集

train_data = torchvision.datasets.CIFAR10("../dataset", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10("../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(f"测试数据集的长度为:{test_data_size}")

# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 创建网络
myModel = MyModel()

# 损失函数
loss_fn = nn.CrossEntropyLoss()

# 优化器
# learning_rate = 0.01
# 1e-2 = 1 * 10^-2 = 1/100 = 0.01
learning_rate = 1e-2 # 0.01
optimizer = torch.optim.SGD(myModel.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 训练训练的次数
total_train_step = 0
# 记录训练的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("./logs/27_model_train")


for i in range(epoch):
    print("------------------第{}轮训练------------------".format(i+1))
    myModel.train()
    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        outputs = myModel(imgs)
        loss = loss_fn(outputs, targets)
        # 优化器优化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # 记录训练次数
        total_train_step = total_train_step + 1
        if total_train_step % 100 ==0:
            print("训练次数:{}, Loss:{}".format(total_train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 测试步骤开始
    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_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()
            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy
    print("整体测试集上的Loss : {}".format(total_test_loss))
    print("整体测试集上的正确率: {}".format(total_accuracy/test_data_size))
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy/test_data_size)
    total_test_step = total_test_step + 1
    torch.save(myModel, "MyModel_{}.pth".format(i))
    print("模型已保存")
writer.close()

模型训练(GPU)

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

from model import MyModel
import time
# 准备数据集

train_data = torchvision.datasets.CIFAR10("../dataset", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10("../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(f"测试数据集的长度为:{test_data_size}")

# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64, drop_last=True)
test_dataloader = DataLoader(test_data, batch_size=64, drop_last=True)

# 创建网络
myModel = MyModel()
myModel = myModel.cuda()  # 使用GPU训练

# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.cuda()  # 使用GPU训练
# 优化器
# learning_rate = 0.01
# 1e-2 = 1 * 10^-2 = 1/100 = 0.01
learning_rate = 1e-2  # 0.01
optimizer = torch.optim.SGD(myModel.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 训练训练的次数
total_train_step = 0
# 记录训练的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("./logs/27_model_train")
start_time = time.time()
for i in range(epoch):
    print("------------------第{}轮训练------------------".format(i + 1))
    myModel.train()
    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        imgs = imgs.cuda()  # GPU加速
        targets = targets.cuda()
        outputs = myModel(imgs)
        loss = loss_fn(outputs, targets)
        # 优化器优化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # 记录训练次数
        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            end_time = time.time()
            print("用时:{}".format(end_time - start_time))
            print("训练次数:{}, Loss:{}".format(total_train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 测试步骤开始
    myModel.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            imgs = imgs.cuda()  # GPU加速
            targets = targets.cuda()
            outputs = myModel(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()
            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy
    print("整体测试集上的Loss : {}".format(total_test_loss))
    print("整体测试集上的正确率: {}".format(total_accuracy / test_data_size))
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy / test_data_size)
    total_test_step = total_test_step + 1
    torch.save(myModel, "MyModel_{}.pth".format(i))
    print("模型已保存")
writer.close()

 

posted @ 2023-10-09 10:17  巴塞罗那的余晖  阅读(38)  评论(0编辑  收藏  举报
//雪花飘落效果