LeNet网络搭建

LeNet网络搭建

项目准备

首先,在某个磁盘中准备一个文件夹,就叫LeNet吧,作为项目的工程目录,然后配置好python环境。

python环境版本

  • python==3.8
  • Pytorch==1.10.1
  • Cudatookit==11.3
  • Cudnn==8.2
  • torchsummary==1.5.1
  • numpy==1.23.2
  • pandas==1.3.4
  • matplotlib==3.5.0
  • sklearn==0.0

定义模型类

创建一个model.py模型类。

# --model.py--
# 导包
import torch
from torch import nn
from torchsummmary import summary # 展现神经网络的参数class LeNet(nn.Module):def __init__(self):super(LeNet,self).__init__() # 要与类名相同# 第一层:定义卷积,输入通道数1,输出通道数6,卷积核大小6*6,步长不写默认1,填充2self.c1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5,padding=2)# 定义激活函数 sigmoidself.sig = nn.Sigmoid()# 第二层: 定义平均池化 感受野(核)是2*2,步长为2self.s2 = nn.AvgPool2d(kernel_size=2,stride=2)# 第三层:卷积层self.c3 = nn.Conv2d(in_channels=6,out_channels=16,kernel_size=5)# 第四层:定义平均池化self.s4 = nn.AvgPool2d(kernel_size=2,stride=2)# 定义平展层self.flatten = nn.Flatten()# 第五层: 线性全连接层(输入特征图,输出特征图)self.f5 = nn.Linear(400,120)# 第六层: 全连接层self.f6 = nn.Linear(120,84)# 第七层:全连接层self.f7 = nn.Linear(84,10)# 定义前向传播def forward(self,x):# x: 接受输入的数据x = self.c1(x) # 第一层卷积x = self.sig(x) # sigmoid激活函数x = self.s2(x) # 第二层平均池化x = self.c3(x) # 第三层卷积x = self.sig(x) # sigmoid激活函数x = self.s4(x) # 第四层池化x = self.flatten(x) # 平展层x = self.f5(x) #第五层全连接层x = self.f6(x) #第六层全连接层x = self.f7(x) #第七层全连接层return x# 在主函数中,测试下模型是否可行
if __name__ == "__main__":# 定义设备device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 实例化模型,并且放进设备中model = LeNet().to(device)# 输出模型的数据# summary(模型类,(输入的特征大小))print(summary(model,(1,28,28)))

定义训练类

数据准备

在进行训练模型前,需要提前准备好数据,来给模型训练。

这里准备的是服装的FashionMNIST数据:

  • 数据总量:七万张数据集
  • 数据集大小:28*28*1
  • 分类:10分类
  • 训练集:六万
  • 测试集:一万

创建一个plot.py 文件,用来加载数据,并且绘制出来。

# --plot.py--# torchvision.datasets库中包含了很多数据集
from torchvision.datasets import FashionMNIST
from torchvision import transforms # 处理数据集,来归一化
import torch.utils.data as Data
import numpy as np
import matplotlib.pyplot as plttrain_data = FashionMNIST(root='./data', # 指定数据集要下载的路径train=True, # 要训练集的数据# 将数据进行归一化操作tranform=transforms.Compose([transforms.Resize(size=224), # 将数据转成224大小transforms.ToTensor() # 将数据转成张量(Tensor)的形式,方面后续模型的应用]),download=True # 开始下载数据
)# 通过DataLoader()类来加载数据集
train_loader = Data.DataLoader(dataset=train_data,# 要加载的数据batch_size=64,# 每轮的训练的数据个数是64个shuffle=True, # 数据是否打乱num_workders=0 # 加载数据的进程
)# ---- 数据展示部分 ----
# 获得一个Batch(批次)的数据
# b_x:图片数据 b_y:标签
for step,(b_x,b_y) in enumerate(train_loader):if step > 0:break
# 比如64*224*224*1 将1移除,(批次,长,宽,通道数)
batch_x = b_x.squeeze().numpy() # 将四维张量移除第1维(第一个类别),并转换成numpy数据
batch_y = b_y.numpy() # 将张量转换numpy数组,方便画图
class_label = train_data.classes # 训练集的标签
print(class_label)# 绘制一个Batch可视化的图像
plt.figure(figsize=(12,5))
for ii ini np.arange(len(batch_y)):plt.subplot(4,16,ii + 1)plt.imshow(batch_x[ii, :, :],cmap=plt.cm.gray)plt.title(class_label[batch_y[ii]],size=10)plt.axis("off")plt.subplots_adjust(wspace=0.05)
plt.show()

上诉代码如果下载成功(只下载了train数据),那么在项目的根目录下就会创建以下文件目录:

LeNet-data-FashionMNIST-raw-train-images-idx3-ubyte-train-images-idx3-ubyte.gz

模型训练的代码模板

训练集模板

这里定义训练集模板,是为了未来的训练方便使用的,因为训练模型的时候,基本上就按这套模板来进行训练,也就说大部分代码结构是一致的。

创建model_train.py文件做模型训练

import torch
from torchvision.datasets import FashionMNIST
from torchvision import transforms
import torch.utils.data as Data
import numpy as np
import matplotlib.pyplot as plt
import torch.nn as nn
import pandas as pdfrom model import LeNet  # 导入自定义模型# 处理训练集(train) 和 验证集(val)
# 每训练一轮就验证一轮
def train_val_data_process():# 加载训练数据train_data = FashionMNIST(root='./data',  # 指定数据集要下载的路径train=True,  # 要训练集的数据# 将数据进行归一化操作tranform=transforms.Compose([transforms.Resize(size=28),  # 将数据转成28大小transforms.ToTensor()  # 将数据转成张量(Tensor)的形式,方面后续模型的应用]),download=True  # 开始下载数据)# 划分训练集和验证集 将数据集中的数据随机划分为训练集和验证集train_data, val_data = Data.random_split(train_data,  # 要划分的数据集[round(0.8 * len(train_data)),  # 将80%的数据集用作训练集round(0.2 * len(train_data))  # 将20%的数据集用作验证集])# 加载数据train_dataloader = Data.DataLoader(dataset=train_data,batch_size=32,  # 每轮训练的批次shuffle=True,num_workders=2)val_dataloader = Data.DataLoader(dataset=train_data,batch_size=32,  # 每轮训练的批次shuffle=True,num_workders=2)return train_dataloader, val_dataloader# 模型训练
def train_model_process(model, train_dataloader, val_dataloader, num_epochs):# model:训练的模型,train_dataloader:训练集,val_dataloader:验证集,num_epochs训练轮数# 指定使用的设备device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 定义优化器Adam(模型的参数,学习率)optimizer = torch.optim.Adam(model.parameters(), lr=0.001)# 定义损失函数 交叉熵损失criterion = nn.CrossEntropyLoss()# 将模型放入到设备当中 进行训练model = model.to(device)# 复制当前模型的参数best_model_wts = copy.deepcopy(model.state_dict())# -- 初始化参数,来记录参数 --best_acc = 0.0  # 最高准确度train_loss_all = []  # 训练集损失列表val_loss_all = []  # 验证集损失列表train_acc_all = []  # 训练集准确度列表val_acc_all = []  # 验证集准确度列表since = time.time()  # 记录训练的时间# -- 开始训练模型 --for epoch in range(num_epochs):print("Epoch {}/{}".format(epoch, num_epochs - 1))  # 打印轮数print("-" * 10)train_loss = 0.0  # 初始化训练集损失值train_corrents = 0  # 初始化训练集精度val_loss = 0.0  # 初始化验证集损失值val_corrents = 0  # 初始化验证集精度train_num = 0  # 该轮次的训练集样本数量val_num = 0  # 该轮次的验证集样本数量# 取出每轮中的数据集 进行 训练和计算for step, (b_x, b_y) in enumerate(train_dataloader):# b_x:128*28*28*1(批次,长,宽,通道)# b_y:128*labelb_x = b_x.to(device)  # 将训练数据放入设备b_y = b_y.to(device)  # 将标签数据放入设备model.train()  # 开启模型训练模型# 将每轮数据中的标签标签(batch)放入模型中进行前向传播,得到输出(不是结果)output = model(b_x)# 查找每一行中最大值对应的行标(索引),即概率最大pre_lab = torch.argmax(output, dim=1) # 里面有个softmax的过程# 计算每个batch的损失loss = criterion(output, b_y)  # 通过模型输出和标签来计算损失值# 将梯度初始化为0,每轮训练完后optimzer.zero_grad()# 反向传播计算loss.backward()# 根据反向传播的梯度信息来更新网络参数,降低loss函数计算值optimzer.step()# 对损失函数进行累加train_loss += loss.item() * b_x.size(0)# 如果预测正确,则准确度+1train_corrects += torch.sum(pre_lab == b_y.data)# 当前用于训练的样本数量train_num += b_x.size(0)# 模型验证for step, (b_x, b_y) in enumerate(val_dataloader):# 将特征放入到验证设备中b_x = b_x.to(device)# 将标签放入到验证设备中b_y = b_y.to(device)model.eval()  # 设置模型为评估(验证)模式# 前向传播过程,输入一个batch,输出该batch对应的预测out_put = model(b_x)# 查找每一行中最大值对应的行标,也就是正确的类别pre_lab = torch.argmax(output, dim=1)# 计算每一个batch的损失函数loss = criterion(output, b_y)# 对损失函数进行累加val_loss += loss.item() * b_x.size(0)# 如果预测正确,则准确度+1val_corrects += torch.sum(pre_lab == b_y.data)# 当前用于验证的样本数量val_num += b_x.size(0)# 计算并保存每一次迭代的loss值和准确率train_loss_all.append(train_loss / train_num)  # 训练集本轮的平均loss值train_acc_all.append(train_corrects.double().item() / train_num)  # 训练集本轮的平均准确率val_loss_all.append(val_loss / val_num)  # 验证集本轮的平均loss值val_acc_all.append(val_corrects.double().item() / val_num)  # 验证集本轮的平均准确率print("{} train loss:{:.4f} train acc: {:.4f}".format(epoch, train_loss_all[-1], train_acc_all[-1]))print("{} val loss:{:.4f} val acc: {:.4f}".format(epoch, val_loss_all[-1], val_acc_all[-1]))# val_acc_all[-1] 表示当前轮次的准确度# 寻找最高准确度的权重参数if val_acc_all[-1] > best_acc: # 如果本轮的准确度比之前的高best_acc = val_acc_all[-1] # 那就更新准确度# 保存当前最高	准确度的参数best_model_wts = copy.deepcopy(model.state_dict())# 计算训练的耗时 (当前时间-之前的时间)time_use = time.time() - sinceprint("训练耗费的时间{:.0f}m{:.0f}s".format(time_use//60,time_use%60))# 将最优模型参数best_model_wts保存torch.save(best_model_wts,'best_model.pth') # 保存模型参数 pth是权重文件的后缀# 保存训练好的模型参数train_process = pd.DataFrame(data={"epoch":range(num_epochs),"train_loss_all":train_loss_all,"val_loss_all":val_loss_all,"train_acc_all":train_acc_all,"val_acc_all":val_acc_all})return train_process# 定义画图的函数,绘制loss值和准确度
def matplot_acc_loss(train_process):plt.figure(figsize=(12,4))plt.subplot(1,2,1) # 一行两列,第一张图plt.plot(train_process["epoch"],train_process.train_loss_all,'ro-',label="train loss")plt.plot(train_process["epoch"],train_process.val_loss_all,'bs-',label="val loss")plt.legend() # 图例plt.xlabel("epoch") # x轴标签plt.ylabel("loss") # y轴标签plt.subplot(1,2,2) # 一行两列,第二张图plt.plot(train_process["epoch"],train_process.train_acc_all,'ro-',label="train acc")plt.plot(train_process["epoch"],train_process.val_acc_all,'bs-',label="val acc")plt.xlabel("epoch") # x轴标签plt.ylabel("acc") # y轴标签plt.legend() # 图例plt.show() # 显示图像if __name__ == "__main__":# 将自定义的模型 实例化LeNet = LeNet()# 加载数据集train_dataloader,val_dataloader = train_val_data_process()# 训练模型 (要训练的模型,训练集,测试集,训练轮数)train_process = train_model_process(LeNet,train_dataloader,val_dataloader,20)# 绘制图像matplot_acc_loss(train_process)

以上代码,可以根据具体情况(硬件设备),适当的更改 train_val_data_process()函数 中的 train_dataloaderval_dataloaderbatch_sizenum_workders

执行以上代码,本地会多出一个best_model.pth文件,里面保存的是模型的参数。

测试集模板

创建一个model_test.py文件

import torch
import torch.utils.data as Data
from torchvision import transforms
from torchvision.datasets importn FashionMNISTfrom model import LeNet # 导入自定义的模型# 定义一个方法,用来加载测试数据
def test_data_process():# 加载测试数据test_data = FashionMNIST(root='./data',  # 指定数据集要下载的路径train=False,  # 不使用训练集# 将数据进行归一化操作tranform=transforms.Compose([transforms.Resize(size=28),  # 将数据转成28大小transforms.ToTensor()  # 将数据转成张量(Tensor)的形式,方面后续模型的应用]),download=True  # 开始下载数据)# 通过DataLoader类来加载测试数据test_dataloader = Data.DataLoader(dataset=test_data,batch_size=1,  # 一张一张的测试shuffle=True,num_workders=0)return test_dataloader# 测试模型
def test_model_process(model, test_dataloader):# 指定设备device = "cuda" if torch.cuda.is_available() else "cpu"# 将模型放入设备中 测试训练model = model.to(device)# -- 初始化参数 --test_corrects = 0.0 # 测试准确度test_num = 0 # 测试样本的数量# 只进行前向传播,不计算梯度,从而节省内存,加快运行速度with torch.no_grad(): # 将梯度置为0for test_data_x,test_data_y in test_dataloader: # 测试的数据 和 标签# 上面设置了批次为1test_data_x = test_data_x.to(device) # 将测试数据放入到设备test_data_y = test_data_y.to(device) # 将标签数据放入到设备model.eval() # 设置模型为评估模式# 前向传播过程,输入为测试数据,输出为每个样本的预测值output = model(test_data_x)# 查找每一行中最大值的行标(索引)pre_lab = torch.argmax(output,dim=1) # 里面有个softmax的过程# 模型预测的结果 与 标签 比较,也就是比对答案,对,就test_corrects+1test_corrects += torch.sum(pre_lab == test_data_y.data)# 将所有的测试样本进行累加test_num += test_data_x.size(0)# 计算测试准确率test_acc = test_corrects.double().item() / test_numprint("测试的准确率为: ",test_acc)if __name__ == "__main__":# 加载模型model = LeNet()# 加载训练好的模型参数model.load_state_dict(torch.load('best_model.pth'))# 加载测试的数据集test_dataloader = test_data_process()# 加载模型测试的函数,传入要训练的模型,和 测试的数据集test_model_process(model,test_dataloader)

查看测试过程中的具体数值

# ...以上代码与上面相同if __name__ == "__main__":# 加载模型model = LeNet()# 加载训练好的模型参数文件model.load_state_dict(torch.load('best_model.pth'))# 加载测试集数据test_dataloader = test_data_process()# 指定测试所用的设备device = "cuda" if torch.cuda.is_available() else "cpu"# 将模型放入到设备当中model = model.to(device)# 衣服的类别类别,顺序不可以换classes = ['T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankle boot']# 将梯度设置为0with torch.no_grad():# 遍历测试集中的 数据 和 标签for b_x,b_y in test_dataloader:b_x = b_x.to(device) # 将测试数据放入设备b_y = b_y.to(device) # 将标签数据放入设备# 设置模型为训练模型model.eval()# 模型推理的结果output = model(b_x)# 获取最大值的下标,也就是预测结果,结果是个Tensor张量pre_lab = torch.argmax(output,dim=1) # 里面有softmax的过程# 取出张量中的下标result = pre_lab.item() # 预测值的索引label = b_y.item() # 标签的索引print("预测值: ",classes[result],"------","真实值: ",classes[label])

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

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

相关文章

【uni-app】2025最新uni-app一键登录保姆级教程(包含前后端获取手机号方法)(超强避坑指南)

前言: 最近在配置uni-app一键登录时遇到了不少坑,uni-app的配套文档较为混乱,并且有部分更新的内容也没有及时更改在文档上,导致部分开发者跟着uni-app配套文档踩坑!而目前市面上的文章质量也层次不齐,有的…

干货分享:ISO 20000认证的适用范围、认证资料清单、认证流程等问题详解

编辑:石芸姗 审核:贺兆普 在当今这个数字化时代,信息技术(IT)已成为企业运营与发展的核心驱动力。随着技术的不断进步和业务需求的日益复杂,企业对IT服务的质量、效率及安全性提出了更高要求。 信息技术服…

Element-plus表格使用总结

这里我使用的是Vue工程进行开发学习,安装需要通过包管理器进行下载 npm install element-plus --save 然后在main.js中配置文件即可使用,如果在引入index.css时没有提示,无需担心,直接写index.css即可导入样式。 Table表格 表格…

CNN和Transfomer介绍

文章目录 CNN和Transfomer介绍CNN和Transfomer的区别1. **基本概念**2. **数据处理方式**3. **模型结构差异**4. **应用场景区别** 自注意力机制1. **自注意力机制的概念**2. **自注意力机制的实现步骤**3. **自注意力机制的优势** Transformer结构组成1. **多头注意力层&#…

如何解决 ‘adb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件的问题

在cmd中输入 adb ,显示 ‘adc‘ 不是内部或外部命令,也不是可运行的程序或批处理文件的问题 解决办法:在环境变量中添加adb所在的路径 1、找到 adb.exe 的所在的文件路径,一般在 Android 安装目录下 \sdk\platform-tools\adb.exe…

数据结构---------二叉树前序遍历中序遍历后序遍历

以下是用C语言实现二叉树的前序遍历、中序遍历和后序遍历的代码示例&#xff0c;包括递归和非递归&#xff08;借助栈实现&#xff09;两种方式&#xff1a; 1. 二叉树节点结构体定义 #include <stdio.h> #include <stdlib.h>// 二叉树节点结构体 typedef struct…

网络架构与IP技术:4K/IP演播室制作的关键支撑

随着科技的不断发展&#xff0c;广播电视行业也在不断迭代更新&#xff0c;其中4K/IP演播室技术的应用成了一个引人注目的焦点。4K超高清技术和IP网络技术的结合&#xff0c;不仅提升了节目制作的画质和效果&#xff0c;还为节目制作带来了更高的效率和灵活性。那么4K超高清技术…

MySQL 8.0:explain analyze 分析 SQL 执行过程

介绍 MySQL 8.0.16 引入一个实验特性&#xff1a;explain formattree &#xff0c;树状的输出执行过程&#xff0c;以及预估成本和预估返 回行数。在 MySQL 8.0.18 又引入了 EXPLAIN ANALYZE&#xff0c;在 formattree 基础上&#xff0c;使用时&#xff0c;会执行 SQL &#…

观察者模式(sigslot in C++)

大家&#xff0c;我是东风&#xff0c;今天抽点时间整理一下我很久前关注的一个不错的库&#xff0c;可以支持我们在使用标准C的时候使用信号槽机制进行观察者模式设计&#xff0c;sigslot 官网&#xff1a; http://sigslot.sourceforge.net/ 本文较为详尽探讨了一种观察者模…

【已解决】黑马点评项目Redis版本替换过程中误删数据库后前端显示出现的问题

为了实现基于Redis的Stream结构作为消息队列&#xff0c;实现异步秒杀下单的功能&#xff0c;换Redis版本 Redis版本太旧了&#xff0c;所以从3.2.1换成了5.0.14 此时犯了一个大忌&#xff0c;因为新的Redis打开后&#xff0c;没有缓存&#xff0c;不知道出了什么问题&#xf…

基于Spring Boot的九州美食城商户一体化系统

一、系统背景与目标 随着美食城行业的快速发展&#xff0c;传统的管理方式已经难以满足日益增长的管理需求和用户体验要求。因此&#xff0c;九州美食城商户一体化系统应运而生&#xff0c;旨在通过信息化、智能化的管理方式&#xff0c;实现美食城的商户管理、菜品管理、订单…

springboot vue 会员营销系统

springboot vue 会员营销系统介绍 演示地址&#xff1a; 开源版本&#xff1a;http://8.146.211.120:8083/ 完整版本&#xff1a;http://8.146.211.120:8086/ 移动端 http://8.146.211.120:8087/ 简介 欢迎使用springboot vue会员营销系统。本项目包含会员储值卡、套餐卡、计…

HarmonyOS NEXT 技术实践-基于意图框架服务实现智能分发

在智能设备的交互中&#xff0c;如何准确理解并及时响应用户需求&#xff0c;成为提升用户体验的关键。HarmonyOS Next 的意图框架服务&#xff08;Intents Kit&#xff09;为这一目标提供了强大的技术支持。本文将通过一个项目实现的示例&#xff0c;展示如何使用意图框架服务…

sfnt-pingpong -测试网络性能和延迟的工具

sfnt-pingpong 是一个用于测试网络性能和延迟的工具&#xff0c;通常用于测量不同网络环境下的数据包传输性能、吞吐量、延迟等指标。 它通常是基于某种网络协议&#xff08;如 TCP&#xff09;执行“ping-pong”式的测试&#xff0c;即客户端和服务器之间相互发送数据包&…

前端下载文件的几种方式使用Blob下载文件

前端下载文件的几种方式 使用Blob下载文件 在前端下载文件是个很通用的需求&#xff0c;一般后端会提供下载的方式有两种&#xff1a; 1.直接返回文件的网络地址&#xff08;一般用在静态文件上&#xff0c;比如图片以及各种音视频资源等&#xff09; 2.返回文件流&#xff08;…

智能座舱进阶-应用框架层-Jetpack主要组件

Jetpack的分类 1. DataBinding&#xff1a;以声明方式将可观察数据绑定到界面元素&#xff0c;通常和ViewModel配合使用。 2. Lifecycle&#xff1a;用于管理Activity和Fragment的生命周期&#xff0c;可帮助开发者生成更易于维护的轻量级代码。 3. LiveData: 在底层数据库更…

知乎 PB 级别 TiDB 数据库集群管控实践

以下文章来源于知乎技术专栏 &#xff0c;作者代晓磊 导读 在现代企业中&#xff0c;数据库的运维管理至关重要&#xff0c;特别是面对分布式数据库的复杂性和大规模集群的挑战。作为一款兼容 MySQL 协议的分布式关系型数据库&#xff0c;TiDB 在高可用、高扩展性和强一致性方…

SpringBoot 自动装配原理及源码解析

目录 一、引言 二、什么是 Spring Boot 的自动装配 三、自动装配的核心注解解析 3.1 SpringBootApplication 注解 &#xff08;1&#xff09;SpringBootConfiguration&#xff1a; &#xff08;2&#xff09;EnableAutoConfiguration&#xff1a; &#xff08;3&#xf…

C++中的字符串实现

短字符串优化(SSO) 实现1 实现2 写时复制 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstdio> #include<cstring> #include<cstring> using std::cout; using std::endl;// 引用计数存放的位置 // 1. 存放在栈上 --- 不行 // 2. 存…

Linux 基本使用和程序部署

1. Linux 环境搭建 1.1 环境搭建方式 主要有 4 种&#xff1a; 直接安装在物理机上。但是Linux桌面使用起来非常不友好&#xff0c;所以不建议。[不推荐]。使用虚拟机软件&#xff0c;将Linux搭建在虚拟机上。但是由于当前的虚拟机软件(如VMWare之类的)存在一些bug&#xff…