Pytorch学习 day13(完整的模型训练步骤)

步骤一:定义神经网络结构

  • 注意:由于一次batch_size的大小为64,表示一次放入64张图片,且Flatten()只会对单张图片的全部通道做拉直操作,也就是不会将batch_size合并,但是一张图片有3个通道,在Maxpool层之后,有64个通道,且每个通道的大小为4*4,所以Flatten()的输入为[64, 64, 4, 4]那么Flatten()的输出就为[64, 1024], 1024 = 64 * 4 * 4
  • 注意:通过ones()函数创建一个全1的tensor,作为输入数据,我们只需要指定输入数据的形状即可,我们可以通过ones()创建的简单输入,来检测网络的结构是否正确,()内写序列
  • 代码如下:
# 搭建神经网络
import torch
from torch import nnclass Tudui(nn.Module):def __init__(self):super().__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),# 由于一次batch_size的大小为64,表示一次放入64张图片,且Flatten()只会对单张图片的全部通道做拉直操作,也就是不会将batch_size合并# 但是一张图片有3个通道,在Maxpool层之后,有64个通道,且每个通道的大小为4*4,所以Flatten()的输入为[64, 64, 4, 4]# 那么Flatten()的输出就为[64, 1024], 1024 = 64 * 4 * 4nn.Flatten(),nn.Linear(1024, 64),nn.Linear(64, 10))def forward(self, x):x = self.model(x)return xif __name__ == '__main__':tudui = Tudui()# 通过ones()函数创建一个全1的tensor,作为输入数据,我们只需要指定输入数据的形状即可,# 我们可以通过ones()创建的简单输入,来检测网络的结构是否正确,()内写序列input = torch.ones((64, 3, 32, 32))output = tudui(input)print(output.shape)

步骤二:导入数据集,载入数据,创建网络模型,设置训练参数

  • 注意:有些代码的模型结构在module.py文件夹内,需要我们手动导包后才能创建实例
  • 注意: 先进行梯度清零,之后再反向传播、更新参数
  • 注意:优化器实例 . 梯度清零,损失实例 . 反向传播,优化器实例 . 更新参数
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torchvision.transforms import transformsfrom learn_pytorch.module import Tuduitrain_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=False, transform=transforms.ToTensor(), download=True)# 获得训练数据集和测试数据集的大小
train_dataset_size = len(train_dataset)
test_dataset_size = len(test_dataset)
print('训练数据集大小:', train_dataset_size)
print('测试数据集大小:', test_dataset_size)# 加载训练数据集和测试数据集
train_loader = DataLoader(dataset=train_dataset, batch_size=64)
test_loader = DataLoader(dataset=test_dataset, batch_size=64)# 创建网络模型
tudui = Tudui()
# 创建损失函数
loss_fn = nn.CrossEntropyLoss()
# 创建优化器
# 1e-3 = 1 * 10^(-3) = 0.001
learn_rate = 1e-3
optimizer = torch.optim.SGD(tudui.parameters(), lr=learn_rate)# 设置训练网络的一些参数
# 训练的次数
total_train_step = 0
# 测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10for i in range(epoch):print(f'----第{i+1}轮训练开始----')for data in train_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)# 调用优化器的梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()total_train_step += 1print(f'训练次数: {total_train_step}, Loss: {loss.item()}')
  • loss跟loss.item()的区别在于:
    • 如果loss为tensor格式,那么输出会带有tensor(),而如果我们使用 .item()格式,则不会带有tensor(),如下:
import torcha = torch.tensor(5)
print(a)
print(a.item())# 输出结果:
# tensor(5)
# 5

步骤三:测试模型性能

  • 由于我们每轮训练结束,都需要看模型有没有训练好,所以我们需要用测试集对模型进行测试
  • 同时我们不希望模型根据测试集来更新梯度,即保证测试集不被污染,使用 with torch.no_grad()来关闭梯度计算,
  • 注意:因为此处我们没有使用梯度,所以虽然看起来不写 with torch.no_grad()和写没有什么区别,但是如果不写,就算不把梯度写入模型中,系统仍会计算梯度。而我们在测试时不需要更新参数,即不需要梯度计算,所以在测试过程中它会降低计算效率。
  • 综上:推荐在测试时,关闭梯度计算,代码如下:
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torchvision.transforms import transformsfrom learn_pytorch.module import Tuduitrain_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=False, transform=transforms.ToTensor(), download=True)# 获得训练数据集和测试数据集的大小
train_dataset_size = len(train_dataset)
test_dataset_size = len(test_dataset)
print('训练数据集大小:', train_dataset_size)
print('测试数据集大小:', test_dataset_size)# 加载训练数据集和测试数据集
train_loader = DataLoader(dataset=train_dataset, batch_size=64)
test_loader = DataLoader(dataset=test_dataset, batch_size=64)# 创建网络模型
tudui = Tudui()
# 创建损失函数
loss_fn = nn.CrossEntropyLoss()
# 创建优化器
# 1e-3 = 1 * 10^(-3) = 0.001
learn_rate = 1e-3
optimizer = torch.optim.SGD(tudui.parameters(), lr=learn_rate)# 设置训练网络的一些参数
# 训练的次数
total_train_step = 0
# 测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10for i in range(epoch):print(f'----第{i+1}轮训练开始----')for data in train_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)# 调用优化器的梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()total_train_step += 1if total_train_step % 100 == 0:print(f'训练次数: {total_train_step}, Loss: {loss.item()}')# 测试模型total_test_loss = 0# 模型运行以下代码时,不会计算梯度,也就是不会更新参数with torch.no_grad():for data in test_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)total_test_loss += loss.item()print(f'测试Loss = {total_test_loss}')

步骤四:在tensorboard中展示输出结果

  • 注意:要在代码的结尾关闭writer
  • 代码如下:
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision.transforms import transformsfrom learn_pytorch.module import Tuduitrain_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=False, transform=transforms.ToTensor(), download=True)# 获得训练数据集和测试数据集的大小
train_dataset_size = len(train_dataset)
test_dataset_size = len(test_dataset)
print('训练数据集大小:', train_dataset_size)
print('测试数据集大小:', test_dataset_size)# 加载训练数据集和测试数据集
train_loader = DataLoader(dataset=train_dataset, batch_size=64)
test_loader = DataLoader(dataset=test_dataset, batch_size=64)# 创建网络模型
tudui = Tudui()
# 创建损失函数
loss_fn = nn.CrossEntropyLoss()
# 创建优化器
# 1e-3 = 1 * 10^(-3) = 0.001
learn_rate = 1e-3
optimizer = torch.optim.SGD(tudui.parameters(), lr=learn_rate)
# 创建tensorboard的writer
writer = SummaryWriter('logs_module')# 设置训练网络的一些参数
# 训练的次数
total_train_step = 0
# 测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10for i in range(epoch):print(f'----第{i+1}轮训练开始----')for data in train_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)# 调用优化器的梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()total_train_step += 1if total_train_step % 100 == 0:print(f'训练次数: {total_train_step}, Loss: {loss.item()}')# 将训练的Loss写入tensorboardwriter.add_scalar('train_loss', loss.item(), total_train_step)# 测试模型total_test_loss = 0# 模型运行以下代码时,不会计算梯度,也就是不会更新参数with torch.no_grad():for data in test_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)total_test_loss += loss.item()# 每轮测试结束后,给测试的次数加1total_test_step += 1print(f'测试Loss = {total_test_loss}')# 将测试的Loss写入tensorboardwriter.add_scalar('test_loss', total_test_loss, total_test_step)writer.close()
  • 结果如下:
    在这里插入图片描述

步骤五:保存每轮模型训练的结果

  • 在每轮测试的代码后,加入以下代码即可:
    torch.save(tudui, f'pth/module{i}')print('模型已保存')

步骤六:计算每轮训练的AP

  • 注意:通过argmax()来得出output的每组序列中哪一个下标的概率最大,()内填1表示横向看,0表示纵向看
  • 注意:通过Preds == target来得出每个预测是否与真实值相同,返回False、True的序列
  • 注意:通过.sum()来计算一共有多少个True
    在这里插入图片描述
  • 代码如下:
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision.transforms import transformsfrom learn_pytorch.module import Tuduitrain_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = torchvision.datasets.CIFAR10(root='Dataset', train=False, transform=transforms.ToTensor(), download=True)# 获得训练数据集和测试数据集的大小
train_dataset_size = len(train_dataset)
test_dataset_size = len(test_dataset)
print('训练数据集大小:', train_dataset_size)
print('测试数据集大小:', test_dataset_size)# 加载训练数据集和测试数据集
train_loader = DataLoader(dataset=train_dataset, batch_size=64)
test_loader = DataLoader(dataset=test_dataset, batch_size=64)# 创建网络模型
tudui = Tudui()
# 创建损失函数
loss_fn = nn.CrossEntropyLoss()
# 创建优化器
# 1e-3 = 1 * 10^(-3) = 0.001
learn_rate = 1e-3
optimizer = torch.optim.SGD(tudui.parameters(), lr=learn_rate)
# 创建tensorboard的writer
writer = SummaryWriter('logs_module')# 设置训练网络的一些参数
# 训练的次数
total_train_step = 0
# 测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10for i in range(epoch):print(f'----第{i+1}轮训练开始----')for data in train_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)# 调用优化器的梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()total_train_step += 1if total_train_step % 100 == 0:print(f'训练次数: {total_train_step}, Loss: {loss.item()}')# 将训练的Loss写入tensorboardwriter.add_scalar('train_loss', loss.item(), total_train_step)# 测试模型total_test_loss = 0total_accuracy = 0# 模型运行以下代码时,不会计算梯度,也就是不会更新参数with torch.no_grad():for data in test_loader:inputs, targets = dataoutputs = tudui(inputs)loss = loss_fn(outputs, targets)total_test_loss += loss.item()accuray = (outputs.argmax(1) == targets).sum()total_accuracy += accurayprint(f'测试准确率 = {total_accuracy / test_dataset_size}')# 每轮测试结束后,给测试的次数加1total_test_step += 1print(f'测试Loss = {total_test_loss}')# 将测试的Loss写入tensorboardwriter.add_scalar('test_loss', total_test_loss, total_test_step)# 将测试的准确率写入tensorboardwriter.add_scalar('test_accuracy', total_accuracy / test_dataset_size, total_test_step)torch.save(tudui, f'pth/module{i}')print('模型已保存')
writer.close()
  • 结果如下:
    在这里插入图片描述

注意事项

  • 在模型的训练代码前,可以加上如下代码,因为有些网络层需要它才能表示训练状态开启:
  • 官网解释如下:
    在这里插入图片描述
# 开始训练
tudui.train()
  • 在模型的测试代码前,也可以加上如下代码,因为有些网络层需要它才能表示测试状态开启:
  • 官网解释如下:
    在这里插入图片描述
tudui.eval()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/741936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv9改进项目|关于本周更新计划的说明24/3/12

目前售价售价59.9,改进点30个 专栏地址: 专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!! 日期:24/3/12 本周更新计划说明: 1. 更新华为Gold YOLO中的…

读西游记第一回:西游记世界格局

天地之数: 元:十二万九千六百岁(129600年) 1元12会:子、丑、寅、卯、巳、午、未、申、酉、戌、亥。每会18000年。与12地支对应。 亥会期:前5400年混沌期,后5400年,盘古开天辟地&am…

论文阅读——Vision Transformer with Deformable Attention

Vision Transformer with Deformable Attention 多头自注意力公式化为: 第l层transformer模块公式化为: 在Transformer模型中简单地实现DCN是一个non-trivial的问题。在DCN中,特征图上的每个元素都单独学习其偏移,其中HWC特征图上…

Mysql数据库学习笔记——第二篇

DML 添加数据 INSERT INTO 表名(字段1,字段2,……) VALUES(值1,值2,……); # 给指定字段添加数据INSERT INTO 表名 VALUES(值1,值2,……); # 给全部字段添加数据INSERT INTO 表名(字段1,字段2,……) VALUES(值1,值2,……),(值1,值2,……),(值1,值2,……); …

【开发】微服务整合Sentinel

目录 前言 1W:什么是Sentinel? 2W:为什么使用Sentinel? 3W:如何使用Sentinel? 1. 在pom.xml中导入Sentinel依赖坐标 2. 配置控制台 3. 访问API接口的任意端点 流量控制 1. 簇点链路 2. 快速入门…

某医院系统未授权访问

开局还是先测一下登录框,弱密码走一波,无果 通过指纹识别出该站是springboot开发,扫描目录查看是否存在泄露 存在泄露,访问地址 很多接口,不可能一个一个手动测试吧,上工具 工具扫描完会生成文档&#xff0…

算法(结合算法图解)

算法简介简单查找二分查找法 选择排序内存的工作原理数组和链表数组选择排序小结 递归小梗 要想学会递归,首先要学会递归。 递归的基线条件和递归条件递归和栈小结 快速排序分而治之快速排序合并排序时间复杂度的平均情况和最糟情况小结 散列表散列函数缓冲小结性能…

Ubuntu系统下查看安装的CUDA和CUDNN的版本

一、查看 CUDA 版本: #查看cuda版本和显存使用情况nvidia-smi 二、查看 CUDNN 版本: 安装链接:cuDNN Archive | NVIDIA Developer #回到系统主目录 cd ~ #查看cudnn版本 cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJO…

华为机考:HJ43 迷宫问题

华为机考:HJ43 迷宫问题 描述 DFS 从迷宫入口开始进行dfs搜索,每次进入一个点,将其加入临时路径数组中,把该位改成0表示不能进入,然后依次搜索该位下、右、上、左四个方向的点,如果搜索的这个点可以进入则…

3d渲染的模型仿佛有一层雾是怎么回事?---模大狮模型网

当在3D渲染的模型上出现仿佛有一层雾的效果时,可能是由于以下几个原因导致的: 环境光设置过高: 如果环境光设置过高,会使整个场景看起来像是笼罩在一层薄雾中。尝试降低环境光的强度,让场景更清晰明亮。 材质透明度设…

图【数据结构】

文章目录 图的基本概念邻接矩阵邻接表图的遍历BFSDFS 图的基本概念 图是由顶点集合及顶点间的关系组成的一种数据结构 顶点和边:图中结点称为顶点 权值:边附带的数据信息 路径 : 简单路径 和 回路: 子图:设图G {V, E}和图G1…

MySQL8 设置大小写敏感

问题描述 今天对我本地的数据库迁移服务器上,完成之后启动项目报错 说数据库中不存在 quartz_LOCKS 这张表 我打开服务器上面的数据上面展示的表名是 quartz_LOCKS,然后通过查询 lower_case_table_names 配置可知 show variables like lower_case_tabl…

Kamailio的SIP服务的性能

官方的性能报告: Kamailio (OpenSER) 1.2.0 - Transaction Module and User Location Performance Tests 如下的提取的性能参数也是基于官方的性能报告,信令走的UDP,作为做系统方案的参照,Kamailio的性能还是非常,非常…

leetcode代码记录(盛最多水的容器

目录 1. 题目:2. 我的代码:小结: 1. 题目: 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以…

【Hibernate-Validate】常用注解

常用注解: NotNull:被注释的元素(任何元素)必须不为 nul, 集合为空也是可以的。NotEmpty:用来校验字符串、集合、map、数组不能为null或也不能为空(字符串传入空格也不可以)(集合需至少包含一个元素)NotBlank:被注释的字符串的必须非空,空格也不行,空字…

来吧伙计们,让AI教我们怎么说海盗语

“如果想伺机而动,就是这样。”——杰克船长提到海盗,我们往往联想到约翰尼德普在《加勒比海盗》中饰演的杰克船长。我们有什么理由不喜欢海盗呢?他们航行在海上,寻找埋藏的宝藏,痛饮朗姆酒,用自己独特的海…

FreMIM:傅里叶变换与遮罩的图像建模在医学图像分割中的应用

代码链接:GitHub - Rubics-Xuan/FreMIM: This repo holds the official code for the paper "FreMIM: Fourier Transform Meets Masked Image Modeling for Medical Image Segmentation". 论文链接:https://arxiv.org/abs/2304.10864 收录于…

差旅补助解决方案|数字化差补赋能业务提效

长期以来,差旅补助一直是企业为了激励员工出差并表达对员工的关怀而采取的一种方式,以经济和福利支持来鼓励员工积极投入工作。然而,由于传统差旅补助的核算、发放和管理方式存在诸多问题,往往适得其反,无法实现企业的…

RocketMQ 面试题及答案整理,最新面试题

RocketMQ的消息存储机制是如何设计的? RocketMQ消息存储机制的设计原理: 1、CommitLog文件: 所有的消息都存储在一个连续的CommitLog文件中,保证了消息的顺序写入,提高写入性能。 2、消费队列: 为每个主…

MySQL row_number()函数,rank()函数和dense_rank()函数

从MySQL8.0开始引用row_number(), rank()函数和dense_rank()函数,也就是常见的窗口函数,三个函数都是一种用于计算排名的工具,它们根据指定的列对结果集进行排序,并为每一行分配一个排名值(1,2,3,...)。 函…