[pytorch] --- pytorch基础之模型训练套路

ops/2024/10/11 11:20:39/

0 深度学习模型训练的一般套路

数据处理

  • 数据读取与预处理:从本地或URL读取数据,并进行预处理操作,如数据校验、格式转换等。
  • 数据标注与整理:设定合理的标签体系,并对数据进行标注。将标注好的各种标签数据分别存放,保证数据集的均衡性。
  • 数据增强:通过旋转、缩放、裁剪等方式增加数据的多样性,以提升模型的泛化能力。

模型设计

  • 网络结构设计:选择合适的网络结构,如卷积神经网络(CNN)、循环神经网络(RNN)等,并设计层数和每层的参数。
  • 损失函数设定:根据任务类型选择合适的损失函数,如交叉熵损失用于分类问题,均方误差损失用于回归问题。

训练配置

  • 优化器选择:设定采用的寻解方法,即优化器,如Adam、随机梯度下降法(SGD)等。
  • 计算资源分配:指定训练所需的硬件资源,如GPU、CPU的分配。

训练过程

  • 前向传播:输入数据通过设计的网络结构进行一系列线性和非线性变换,得到预测值。
  • 损失计算:计算预测值与真实标签之间的差异,即损失值,用以评估模型当前的表现。
  • 后向传播:通过损失函数的梯度指导模型参数的更新,不断迭代优化模型参数。
  • 迭代训练:循环进行前向传播、损失计算和后向传播,直至满足停止条件(如达到预设的迭代次数或损失值低于某个阈值)。

模型保存

  • 保存训练好的模型:将训练完成的模型保存,以便后续的使用或部署。

下面以具体实例给出上面的步骤

1 数据处理

为了方便,我们这里直接使用pytorch官方的CIFAR10数据集进行训练

1.2 dataset下载数据集python代码实现

train_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),download=True)# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10, 训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

输出如下:

/home/decre/miniconda3/envs/pytorch/bin/python /home/decre/work/ybb/base_pytorch/05_train.py 
Files already downloaded and verified
Files already downloaded and verified
训练数据集的长度为:50000
测试数据集的长度为:10000

1.3 dataloader加载数据集

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

2 模型设计

2.1 搭建网络模型

在这里插入图片描述

2.2 模型的python代码实现

model.py文件实现如下:
习惯上把模型单独存一个py文件里面,这里也把这个代码块存在"model.py"下

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念
import torch
from torch import nn# 搭建神经网络
class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.model = 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(64*4*4, 64),nn.Linear(64, 10))def forward(self, x):x = self.model(x)return xif __name__ == '__main__':tudui = Tudui()input = torch.ones((64, 3, 32, 32))output = tudui(input)print(output.shape)

2.3 损失函数

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

3 训练配置

3.1 优化器

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

3.2 其他训练参数设置

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

3.3 计算资源分配-CPU

3.4 计算资源分配-GPU

明确定义训练设备是GPU

# 定义训练的设备
device = torch.device("cuda")
# 创建模型的时候指定使用cuda加速
tudui = tudui.to(device)# 损失函数指定使用cuda加速
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)

4 训练过程(给出cpu版本)


# 添加tensorboard
writer = SummaryWriter("../logs_train")for i in range(epoch):print("-------第 {} 轮训练开始-------".format(i+1))# 训练步骤开始tudui.train()for data in train_dataloader:imgs, targets = dataoutputs = tudui(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 测试步骤开始tudui.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = dataoutputs = 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 + accuracyprint("整体测试集上的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 = total_test_step + 1torch.save(tudui, "tudui_{}.pth".format(i))print("模型已保存")

5 保存模型

torch.save(tudui, "tudui_{}.pth".format(i))

6 完整示例代码

6.1 cpu版本训练模型代码

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoadertrain_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),download=True)# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10, 训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
tudui = Tudui()# 损失函数
loss_fn = nn.CrossEntropyLoss()# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("../logs_train")for i in range(epoch):print("-------第 {} 轮训练开始-------".format(i+1))# 训练步骤开始tudui.train()for data in train_dataloader:imgs, targets = dataoutputs = tudui(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 测试步骤开始tudui.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = dataoutputs = 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 + accuracyprint("整体测试集上的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 = total_test_step + 1torch.save(tudui, "tudui_{}.pth".format(i))print("模型已保存")writer.close()

6.2 gpu版本1训练模型代码

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter# from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoadertrain_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),download=True)# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10, 训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.model = 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(64*4*4, 64),nn.Linear(64, 10))def forward(self, x):x = self.model(x)return x
tudui = Tudui()
if torch.cuda.is_available():tudui = tudui.cuda()# 损失函数
loss_fn = nn.CrossEntropyLoss()
if torch.cuda.is_available():loss_fn = loss_fn.cuda()
# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("../logs_train")for i in range(epoch):print("-------第 {} 轮训练开始-------".format(i+1))# 训练步骤开始tudui.train()for data in train_dataloader:imgs, targets = dataif torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()outputs = tudui(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 测试步骤开始tudui.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = dataif 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 + accuracyprint("整体测试集上的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 = total_test_step + 1torch.save(tudui, "tudui_{}.pth".format(i))print("模型已保存")writer.close()

6.3 gpu版本2训练模型代码

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter# from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader# 定义训练的设备
device = torch.device("cuda")train_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),download=True)# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10, 训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.model = 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(64*4*4, 64),nn.Linear(64, 10))def forward(self, x):x = self.model(x)return x
tudui = Tudui()
tudui = tudui.to(device)# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)
# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("../logs_train")for i in range(epoch):print("-------第 {} 轮训练开始-------".format(i+1))# 训练步骤开始tudui.train()for data in train_dataloader:imgs, targets = dataimgs = imgs.to(device)targets = targets.to(device)outputs = tudui(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 测试步骤开始tudui.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = dataimgs = imgs.to(device)targets = targets.to(device)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 + accuracyprint("整体测试集上的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 = total_test_step + 1torch.save(tudui, "tudui_{}.pth".format(i))print("模型已保存")writer.close()

http://www.ppmy.cn/ops/107230.html

相关文章

react lazy加载资源找不到的问题

在 Umi 4 中,默认按页拆包进行优化,实现每个页面只需加载最少的 js 资源,这会产生很多异步 js 分包。通常我们会开启 hash: true 构建,将 js / css 等资源做长期缓存,而 html 不缓存。 然而,在版本发布时&…

计算机毕业设计选题-基于python的企业人事管理系统【源码+文档+数据库】

💖🔥作者主页:毕设木哥 精彩专栏推荐订阅:在 下方专栏👇🏻👇🏻👇🏻👇🏻 实战项目 文章目录 实战项目 一、基于python的企业人事管理系…

【Oracle篇】全面理解优化器和SQL语句的解析步骤(含执行计划的详细分析和四种查看方式)(第二篇,总共七篇)

💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨ 💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️…

3177. 求出最长好子序列 II / 3176. 求出最长好子序列 I(24.9.7 / 24.9.8)

昨日与今日题目相同,只有数据量变大了 题目 给定一个整数数组 nums 和一个非负整数 k。如果一个整数序列 seq 在范围下标范围 [0, seq.length - 2] 中存在不超过 k 个下标 i 满足 seq[i]!seq[i 1],那么称这个整数序列为好序列。要求返回 nums 中好子序…

基础物理-向量3

总结 标量和向量 标量,如温度,仅具有大小。它们通过一个带有单位的数字(例如 10C)表示,并遵循算术和普通代数的规则。向量,如位移,既具有大小又具有方向(例如 5 米,向北…

Flutter 局部变量刷新问题

在Flutter中,当你调用setState时,它会触发Widget树的重新构建。这意味着任何依赖于状态的Widget都会重新构建,从而反映新的状态值。但是,具体的刷新行为取决于dd是如何定义和使用的。 让我们来看看两种情况下setState的行为&…

bash反弹shell分析

目录 介绍步骤 介绍 与目标主机建立连接的原理是利用漏洞执行ShellCode。 GetShell的实质是:执行ShellCode,将目标主机的Shell重定向到攻击机。拿到Shell利于后续的渗透。 所谓的反弹Shell是指GetShell的过程由目标主机主动发起(反向连接&a…

微信小程序显示后台文章副文本,图片和视频正常显示

解决方案: 使用 wxParse 或 rich-text 组件: 这两种方式可以解析 HTML 字符串并渲染富文本内容,包括图片和视频。 数据处理: 将后台返回的富文本数据进行处理,提取出图片和视频的链接,并将其转换成小程序支持的格式。 方案一:使…