pytorh模型训练、测试

2023-11-06 06:30
文章标签 训练 模型 测试 pytorh

本文主要是介绍pytorh模型训练、测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1 导入数据集

2 使用tensorboard展示经过各个层的图片数据

3 完整的模型训练测试流程

使用Gpu训练的两种方式

使用tensorboard显示模型

模型训练测试

L1Loss函数

保存未训练模型或者已经训练完的模型

4 加载训练好的模型进行测试


1 导入数据集

import torch
from torch.utils.data import DataLoader
import torchvision
from torchvision import transforms
import torch.nn as nn
# 准备数据集
from torch.utils.tensorboard import SummaryWriter
train_data = torchvision.datasets.CIFAR10('./data', train=True, transform=transforms.ToTensor(), download=True)
print("train数据", train_data)
print(f"train_data数据的长度是{len(train_data)}")
train_data = DataLoader(dataset=train_data, batch_size=64, shuffle=True)
print("------------------------------------------")
test_data = torchvision.datasets.CIFAR10('./data', train=False, transform=transforms.ToTensor(), download=True)
print("test数据", test_data)
print(f"test_data数据的长度是{len(test_data)}")
print("第一条数据",test_data[0])
test_data = DataLoader(dataset=test_data, batch_size=64, shuffle=True)

train数据 Dataset CIFAR10
    Number of datapoints: 50000
    Root location: ./data
    Split: Train
    StandardTransform
Transform: ToTensor()
train_data数据的长度是50000
------------------------------------------
Files already downloaded and verified
test数据 Dataset CIFAR10
    Number of datapoints: 10000
    Root location: ./data
    Split: Test
    StandardTransform
Transform: ToTensor()
test_data数据的长度是10000
第一条数据 (tensor([[[0.6196, 0.6235, 0.6471,  ..., 0.5373, 0.4941, 0.4549],
         [0.5961, 0.5922, 0.6235,  ..., 0.5333, 0.4902, 0.4667],
         [0.5922, 0.5922, 0.6196,  ..., 0.5451, 0.5098, 0.4706],
         ...,
         [0.2667, 0.1647, 0.1216,  ..., 0.1490, 0.0510, 0.1569],
         [0.2392, 0.1922, 0.1373,  ..., 0.1020, 0.1137, 0.0784],
         [0.2118, 0.2196, 0.1765,  ..., 0.0941, 0.1333, 0.0824]],

        [[0.4392, 0.4353, 0.4549,  ..., 0.3725, 0.3569, 0.3333],
         [0.4392, 0.4314, 0.4471,  ..., 0.3725, 0.3569, 0.3451],
         [0.4314, 0.4275, 0.4353,  ..., 0.3843, 0.3725, 0.3490],
 

2 使用tensorboard展示经过各个层的图片数据

class convModel(nn.Module):def __init__(self):super(convModel, self).__init__()self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, stride=1, padding=0, bias=True, padding_mode='zeros', kernel_size=3)def forward(self, input_data):return self.conv1(input_data)
write = SummaryWriter('convModel')
model = convModel()
for batch_id, data in enumerate(test_data):write.add_images('原始图片数据展示', data[0], dataformats='NCHW', global_step=batch_id)input_data, label = data[0],data[1]print("batchSize",input_data.size(0))output_data = model(input_data)# 因为经过卷积之后,通道数变为6了,而add_images的源码中要求的通道个数是4个,所以要进行通道变换output_shape_data = torch.reshape(output_data,(-1,3,30,30))write.add_images('经过卷积层之后的图片数据展示', output_shape_data, global_step=batch_id)if batch_id % 300 == 0:print("原始数据的形状", input_data.shape)print("经过卷积层之后的形状", output_data.shape)print("经过形状改变之后", output_shape_data.shape)
write.close()

batchSize 64
原始数据的形状 torch.Size([64, 3, 32, 32])
经过卷积层之后的形状 torch.Size([64, 6, 30, 30])
经过形状改变之后 torch.Size([128, 3, 30, 30])
batchSize 64
batchSize 64
batchSize 64
batchSize 64
batchSize 64
batchSize 64
batchSize 64

class maxPoolingModel(nn.Module):def __init__(self):super(maxPoolingModel, self).__init__()self.MaxPool2d = nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=False)def forward(self, input_data):return self.MaxPool2d(input_data)
write = SummaryWriter('maxPoolingModel')
model = maxPoolingModel()
for batch_id, data in enumerate(test_data):write.add_images('原始图片数据展示', data[0], dataformats='NCHW', global_step=batch_id)input_data, label = data[0],data[1]output_data = model(input_data)write.add_images('经过池化层之后的图片数据展示', output_data, global_step=batch_id)if batch_id % 300 == 0:print("原始数据的形状", input_data.shape)print("经过池化层之后的形状", output_data.shape)
write.close()

原始数据的形状 torch.Size([64, 3, 32, 32])
经过池化层之后的形状 torch.Size([64, 3, 16, 16])

class unLineModel(nn.Module):def __init__(self):super(unLineModel, self).__init__()self.sigmoid = nn.Sigmoid()def forward(self, input_data):return self.sigmoid(input_data)
write = SummaryWriter('unLineModel')
model = unLineModel()
for batch_id, data in enumerate(test_data):write.add_images('原始图片数据展示', data[0], dataformats='NCHW', global_step=batch_id)input_data, label = data[0],data[1]output_data = model(input_data)write.add_images('经过非线性层之后的图片数据展示', output_data, global_step=batch_id)if batch_id % 300 == 0:print("原始数据的形状", input_data.shape)print("经过非线性层之后的形状", output_data.shape)
write.close()

原始数据的形状 torch.Size([64, 3, 32, 32])
经过非线性层之后的形状 torch.Size([64, 3, 32, 32])

3 完整的模型训练测试流程

class Model(nn.Module):def __init__(self):super(Model,self).__init__()self.model = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2,stride=1),nn.MaxPool2d(kernel_size=2, stride=2),nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2,stride=1),nn.MaxPool2d(kernel_size=2, stride=2),nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2,stride=1),nn.MaxPool2d(kernel_size=2, stride=2),nn.Flatten(),nn.Linear(in_features=1024, out_features=64),nn.Linear(in_features=64, out_features=10))def forward(self, batch_data):return self.model(batch_data)
# 第一种方式:使用cuda,只需要给模型、损失函数、训练数据、测试数据调用cuda即可,但是这种情况下必须使用if torch.cuda.is_available():判断是否存在cuda,没有的话还是使用cpu,但是没有使用torch.cuda.is_available()判断的话会出错,导致程序无法运行
# 第二种方式:cuda:0 单个显卡
device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu')
model = Model()
model.to(device=device)
print(model)
batch_data = torch.ones((64,3,32,32)).to(device)
output = model(batch_data)
print("output.shape", output.shape)

Model(
  (model): Sequential(
    (0): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (4): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Flatten(start_dim=1, end_dim=-1)
    (7): Linear(in_features=1024, out_features=64, bias=True)
    (8): Linear(in_features=64, out_features=10, bias=True)
 

使用Gpu训练的两种方式
# 第一种方式:使用cuda,只需要给模型、损失函数、训练数据、测试数据调用cuda即可,但是这种情况下必须使用if torch.cuda.is_available():判断是否存在cuda,没有的话还是使用cpu,但是没有使用torch.cuda.is_available()判断的话会出错,导致程序无法运行
# 第二种方式:cuda:0 单个显卡
device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu'),在这种情况写,只需要将对应的模型、损失函数、训练数据、测试数据使用to调用device上即可
使用tensorboard显示模型
from torch.utils.tensorboard import SummaryWriter
write = SummaryWriter('model')
write.add_graph(model=model,input_to_model=batch_data)
write.close()
模型训练测试
# -------------------------CrossEntropyLoss()维度要求的底层源码-------------------
# Shape:
#         - Input: :math:`(N, C)` where `C = number of classes`, or
#           :math:`(N, C, d_1, d_2, ..., d_K)` with :math:`K \geq 1`
#           in the case of `K`-dimensional loss.
#         - Target: :math:`(N)` where each value is :math:`0 \leq \text{targets}[i] \leq C-1`, or
#           :math:`(N, d_1, d_2, ..., d_K)` with :math:`K \geq 1` in the case of
#           K-dimensional loss.
#         - Output: scalar.
#           If :attr:`reduction` is ``'none'``, then the same size as the target:
#           :math:`(N)`, or
#           :math:`(N, d_1, d_2, ..., d_K)` with :math:`K \geq 1` in the case
#           of K-dimensional loss.
criteria = nn.CrossEntropyLoss()
criteria.to(device)
nn.L1Loss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
sum_loss_list = []
epoch_list = []
from torch.utils.tensorboard import  SummaryWriter
write = SummaryWriter("figure")
total_train_step = 0
total_test_step = 0
for epoch in range(50):ever_epoch_loss_sum = 0.0print("---------------------第 {} 轮训练开始---------------------".format(epoch+1))model.train()for batch_id, data in enumerate(train_data):input_data, input_label = datainput_data = input_data.to(device)input_label = input_label.to(device)output_data = model(input_data)# if batch_id%300 == 0:#     print("input_data", input_data.shape)  # input_data torch.Size([64, 3, 32, 32])#     print("output_data", output_data.shape) # output_data torch.Size([64, 10])#     print("input_label", input_label.shape) # input_label torch.Size([64])loss = criteria(output_data, input_label)ever_epoch_loss_sum = ever_epoch_loss_sum + loss.item()loss.backward()optimizer.step()optimizer.zero_grad()if total_train_step % 200 == 0:print("当前总的训练次数:{} ,每一次的Loss:{}".format(total_train_step, loss.item()))write.add_scalar('train_loss', loss.item(), total_train_step)total_train_step = total_train_step + 1sum_loss_list.append(ever_epoch_loss_sum)epoch_list.append(epoch)print("---------------------第 {} 轮测试开始---------------------".format(epoch+1))model.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for batch_id, data in enumerate(test_data):images, label = dataimages = images.to(device)label = label.to(device)output = model(images)loss = criteria(output,label)total_test_loss = total_test_loss + loss.item()accuracy = (output.argmax(1) == label).sum()total_accuracy = total_accuracy + accuracyprint("整体测试集上的Loss: {}".format(total_test_loss))print("整体数据集上的正确率:{}".format(total_accuracy/len(test_data)))write.add_scalar("test_accuracy",total_accuracy/len(test_data),total_test_step)write.add_scalar('test_loss', total_test_loss, total_test_step)total_test_step = total_test_step + 1torch.save(model,'model_{}.pth'.format(epoch))print("保存第 {} 轮模型".format(epoch+1))
write.close()
L1Loss函数
inputs = torch.tensor([1,2,3], dtype=torch.float32)
print("原始数据inputs", inputs)
print("原始数据形状inputs.shape", inputs.shape)
targets = torch.tensor([1,2,5], dtype=torch.float32)
print("目标数据targets", targets)
print("目标数据形状targets.shape", targets.shape)
inputs = torch.reshape(inputs,(1,-1))
print("形状改变数据inputs", inputs)
print("形状改变数据形状inputs.shape", inputs.shape)
targets = torch.reshape(targets,(1,-1))
print("目标数据改变targets", targets)
print("目标数据形状改变targets.shape", targets.shape)
loss = nn.L1Loss()# - Input: :math:`(N, *)` where :math:`*` means, any number of additional#          dimensions#        - Target: :math:`(N, *)`, same shape as the input
result = loss(inputs, targets)
print(result)

原始数据inputs tensor([1., 2., 3.])
原始数据形状inputs.shape torch.Size([3])
目标数据targets tensor([1., 2., 5.])
目标数据形状targets.shape torch.Size([3])
形状改变数据inputs tensor([[1., 2., 3.]])
形状改变数据形状inputs.shape torch.Size([1, 3])
目标数据改变targets tensor([[1., 2., 5.]])
目标数据形状改变targets.shape torch.Size([1, 3])
tensor(0.6667)

保存未训练模型或者已经训练完的模型
# 模型的保存
torch.save(model,'class_model.pth')
# 模型加载,但是这种情况下如果加载的模型和原本的模型没有在同一个文件中,那么需要将原本的模型使用from加载到当前文件中,再使用torch.load
model = torch.load('class_model.pth')
print(model)

4 加载训练好的模型进行测试

import torch.nn as nn
import torch
class Model(nn.Module):def __init__(self):super(Model,self).__init__()self.model = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2,stride=1),nn.MaxPool2d(kernel_size=2, stride=2),nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2,stride=1),nn.MaxPool2d(kernel_size=2, stride=2),nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2,stride=1),nn.MaxPool2d(kernel_size=2, stride=2),nn.Flatten(),nn.Linear(in_features=1024, out_features=64),nn.Linear(in_features=64, out_features=10))def forward(self, batch_data):return self.model(batch_data)
load_model = torch.load('G:\python_files\深度学习代码库\model_49.pth') # 加载模型,使用上面的非字典形式保存的模型,这个时候加载的时候必须把原本定义的模型加载到当前文件,然后使用该函数加载。同时需要注意,如果加载的模型原本是在cuda上跑的,这个时候要将模型使用load函数的参数map_location=torch.device('cpu')加载到cpu上,或者也可以将图片的数据放入到gpu上,与原本的模型对应起来
from torchvision import transforms
from PIL import Image
image = Image.open('G:\python_files\深度学习代码库\cats\cat\cat.10.jpg')
trans = transforms.Compose([transforms.Resize((32,32)),transforms.ToTensor()])
trans_image_tensor = trans(image)
# 因为上面的模型训练的时候输入是(NCHW),所以将训练完的模型加载进来使用测试的时候必须要将一张图片reshape模型需要的形状,否则就会报错
tensor_shape = torch.reshape(trans_image_tensor,(1,3,32,32)).to(torch.device("cuda:0"))
load_model.eval()
with torch.no_grad():output = load_model(tensor_shape)print(output)

注意事项:

load_model = torch.load('G:\python_files\深度学习代码库\model_49.pth') # 加载模型,使用上面的非字典形式保存的模型,这个时候加载的时候必须把原本定义的模型加载到当前文件,然后使用该函数加载。同时需要注意,如果加载的模型原本是在cuda上跑的,这个时候要将模型使用load函数的参数map_location=torch.device('cpu')加载到cpu上,或者也可以将图片的数据放入到gpu上,与原本的模型对应起来
# 因为上面的模型训练的时候输入是(NCHW),所以将训练完的模型加载进来使用测试的时候必须要将一张图片reshape模型需要的形状,否则就会报错
tensor_shape = torch.reshape(trans_image_tensor,(1,3,32,32)).to(torch.device("cuda:0"))

这篇关于pytorh模型训练、测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/354962

相关文章

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验