一、CRFAR10的训练过程
1、导入相关模块
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
from torch import nn
from torch.utils.data import DataLoader
# 用来计时,方便计算项目的训练时间
import time
在终端输入:nvidia-smi 即可查看GPU的相关信息。
GPU的使用:将网络模型、数据(输入,标签)、损失函数调用.cuda()转移到cuda上即可。
2、准备数据集并加载数据集
# 准备数据集
train_data = torchvision.datasets.CIFAR10("./data_train",train=True,transform=torchvision.transforms.ToTensor(),
download=True)
test_data = torchvision.datasets.CIFAR10("./data_test",train=False,transform=torchvision.transforms.ToTensor(),
download=True)
# lenth 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print(f"测试数据集的长度为:{test_data_size}")
# 加载数据集
train_dataloader = DataLoader(train_data,batch_size=64)
test_dataloader = DataLoader(test_data,batch_size=64)
3、创建网络模型
class Dreamzed(nn.Module):
def __init__(self):
super(Dreamzed, self).__init__()
self.module = nn.Sequential(
nn.Conv2d(3,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(1024,64),
nn.Linear(64,10)
)
def forward(self,x):
x = self.module(x)
return x
dreamzed = Dreamzed()
# 将网络模型转移到cuda上(如果有的话)
if torch.cuda.is_available():
tudui = tudui.cuda()
4、定义损失函数和优化器
# 定义损失函数
loss_fn = nn.CrossEntropyLoss()
# 将损失函数转移到cuda上
if torch.cuda.is_available():
loss_fn = loss_fn.cuda()
# 定义优化器
# learning_rate = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(),lr=learning_rate)
5、定义训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的次数
epoch = 30
# 添加tensorboard
writer = SummaryWriter("./logs_train")
# 记录开始时间
start_time = time.time()
在终端输入:tensorboard --logdir=logs_train 即可查看整个训练过程的可视化。
6、开始训练
for i in range(epoch):
print(f"-----第{i+1}轮训练开始-----")
# 训练步骤开始
# dreamzed.train()只对特定的层起作用,如dropout层等,如果有这些层就必须调用,如果没有调用也没有问题
for data in train_dataloader:
imgs,targets = data
#将训练数据转移到cuda上
if torch.cuda.is_available():
imgs = imgs.cuda()
targets = targets.cuda()
outputs = dreamzed(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(end_time - start_time)
print(f"训练次数:{total_train_step},Loss:{loss.item()}")#item()可以将tensor数据类型转化为真实的数字
writer.add_scalar("train_loss",loss.item(),total_train_step)
7、开始测试
# 测试步骤开始
# tudui.eval()只对特定的层起作用,如dropout层等,如果有这些层就必须调用,如果没有调用也没有问题
total_test_loss = 0
# 整体正确的个数
total_accuracy = 0
# 测试中不需要梯度清零
with torch.no_grad():
for data in test_dataloader:
imgs,targets = data
if torch.cuda.is_available():
imgs = imgs.cuda()
targets = targets.cuda()
outputs = tudui(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(f"整体数据集上的Loss:{total_test_loss}")
print(f"整体测试集上的正确率:{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 = total_test_step + 1
# 保存模型
torch.save(dreamzed,f"dreamzed_{i}_gpu.pth")
print("模型已保存")
# 保存方式二:torch.save(dreamzed.state_dict(),"tudui_{}.pth".format(i))
writer.close()
准确率是分类问题特有的评价标准。
这里利用了argmax来计算准确率。argmax的使用如下所示:
import torch
# 分类问题特有的评估标准:准确率
outputs = torch.tensor([[0.1,0.2],
[0.3,0.4]])
# 若argmax(1),则输出每一行上的最大值代表的类别(索引)
# 若argsmax(0),则输出每一列上的最大值代表的类别(索引)
print(outputs.argmax(1))
#计算预测的分类,比如有两类0和1
preds = outputs.argmax(1)
#实际所属的分类
targets = torch.tensor([0,1])
#计算准确率
print((preds == targets).sum())
二、模型验证过程
import torch
from PIL import Image
import torchvision
from torch import nn
#导入需要验证的图片
image_path = "./images/airplane.jpg"
image = Image.open(image_path)
image = image.convert('RGB')
#将图片转变为模型input需要的格式
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),torchvision.transforms.ToTensor()])
image = transform(image)
#验证图片的格式是否符合要求
print(image.shape)
#需要将模型的搭建移过来,但不需要实例化对象
class Dreamzed(nn.Module):
def __init__(self):
super(Dreamzed, self).__init__()
self.module = nn.Sequential(
nn.Conv2d(3,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(1024,64),
nn.Linear(64,10)
)
def forward(self,x):
x = self.module(x)
return x
#加载训练好的模型(注意必须先保存已经训练好的模型才能加载)
module = torch.load("dreamzed_29_gpu.pth",map_location=torch.device("cpu"))
print(module)
image = torch.reshape(image,(1,3,32,32))
module.eval()
#验证过程不需要梯度清零
with torch.no_grad():
output = module(image)
print(output)
#输出属于哪一类
print(output.argmax(1))
验证结果如下图所示:
结果为飞机,验证正确。