基于Pytorch框架构建LeNet-5模型

Pytorch

  • 一、训练模型
    • 1.导入必要的库
    • 2.设置超参数
    • 3.数据预处理
    • 4.读取数据
  • 二、定义卷积神经网络
    • 1.定义卷积神经网络
    • 2.定义学习率
    • 3.实例化模型并且移动到GPU
    • 4.选择优化器
  • 三、定义调整学习率的函数
    • 1.定义调整学习率的函数
  • 四、训练模型
    • 1.设置模型为训练模式
    • 2.遍历训练数据加载器
    • 3.打印进度
  • 五、验证模型
    • 1.设置模型为验证模式
    • 2.初始化计数器
    • 3.遍历测试数据加载器
    • 4.计算准确率
    • 5.打印验证结果
  • 五、定义训练循环
    • 2.执行训练和验证
    • 3.保存模型

一、训练模型

1.导入必要的库

torch.nn.functional as F: 导入 PyTorch 的不带参数的函数模块,包含各种函数,如激活函数、池化层等。
torch.optim as optim: 导入 PyTorch 的优化器模块,用于定义优化器。
torch.cuda.is_available(): 导入 PyTorch 的 CUDA 模块,用于检查是否有可用的 CUDA GPU。
torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’): 导入 PyTorch 的设备模块,用于定义计算设备。如果 CUDA GPU 可用,则定义为 ‘cuda’;否则定义为 ‘cpu’。

# 导入库
import torch.nn.functional as F
import torch.optim as optim
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.optim
import torch.utils.data
import torch.utils.data.distributed
import torchvision.transforms as transforms
import torchvision.datasets as datasets

2.设置超参数

定义超参数,这些参数将用于控制模型的训练过程。

以下是超参数的详细说明:
CH_SIZE: 定义了每个训练批次的样本数量。较大的批大小可以提高计算效率,但可能会增加内存需求。在这个例子中,批大小被设置为 20。
EPOCHS: 定义了训练过程中迭代的轮数。每个 epoch 表示数据集被完整地遍历了一次。在这个例子中,训练过程被设置为进行 10 个 epoch。
DEVICE: 定义了计算设备。如果环境中存在可用的 GPU,它会定义为 ‘cuda’;如果环境中没有可用的 GPU,它会定义为 ‘cpu’。

# 设置超参数
#每次的个数
BATCH_SIZE = 20
#迭代次数
EPOCHS = 10
#采用cpu还是gpu进行计算
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

3.数据预处理

定义数据预处理步骤,这些步骤将被应用于每个图像上,以增强数据的多样性并标准化数据格式。
以下是预处理步骤的详细说明:
1)Resize(100): 将图片大小调整为 100x100 像素。
2)RandomVerticalFlip(): 随机垂直翻转图片。
3)RandomCrop(50): 从原始图片中随机裁剪一个大小为 50x50 的区域。
4)RandomResizedCrop(150): 从原始图片中随机裁剪一个大小为 150x150 的区域,并随机调整裁剪区域的缩放比例。
5)ColorJitter(brightness=0.5, contrast=0.5, hue=0.5): 随机调整图片的亮度、对比度和色调。
6)ToTensor(): 将 PIL 图像转换为 PyTorch 张量。
7)Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]): 对图像进行归一化处理,将每个通道的均值和标准差调整为 0.5。

# 定义数据预处理
transform = transforms.Compose([transforms.Resize(100),transforms.RandomVerticalFlip(),transforms.RandomCrop(50),transforms.RandomResizedCrop(150),transforms.ColorJitter(brightness=0.5, contrast=0.5, hue=0.5),transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])

4.读取数据

使用 PyTorch 的数据加载和处理功能来读取数据集,并为训练和测试阶段准备数据加载器。

以下是代码的详细步骤:
1)dataset_train = datasets.ImageFolder(‘E:\xm\dataset\train’, transform): 创建一个ImageFolder数据集,用于加载和分类E:\xm\dataset\train目录中的图像。这个目录应该包含多个子目录,每个子目录代表一个类别,子目录中的图像将归属于该类别。transform变量包含了应用于每个图像的预处理操作。
2)print(dataset_train.imgs): 打印数据集中所有图像的文件路径和对应的类别索引。imgs是一个列表,每个元素是一个包含图像文件路径和类别索引的元组。
3)print(dataset_train.class_to_idx): 打印类别到索引的映射。class_to_idx是一个字典,键是类别名称,值是相应的索引。
4)dataset_test = datasets.ImageFolder(‘E:\xm\dataset\val’, transform): 创建一个ImageFolder数据集,用于加载和分类E:\xm\dataset\val目录中的验证图像。
5)print(dataset_test.class_to_idx): 这行代码打印验证数据集中类别到索引的映射。
6)train_loader = torch.utils.data.DataLoader(dataset_train, batch_size=BATCH_SIZE, shuffle=True): 创建一个训练数据加载器。DataLoader类接受一个数据集和一个批处理大小batch_size,以及一个shuffle标志,表示是否在每次遍历数据集时随机打乱数据的顺序。
7)test_loader = torch.utils.data.DataLoader(dataset_test, batch_size=BATCH_SIZE, shuffle=True): 创建一个测试数据加载器。与训练数据加载器类似,但它也用于加载验证数据集。

# 读取数据
dataset_train = datasets.ImageFolder('E:\\xm\dataset\\train', transform)
print(dataset_train.imgs)# 对应文件夹的label
print(dataset_train.class_to_idx)
dataset_test = datasets.ImageFolder('E:\\xm\dataset\\val', transform)# 对应文件夹的label
print(dataset_test.class_to_idx)# 导入数据
train_loader = torch.utils.data.DataLoader(dataset_train, batch_size=BATCH_SIZE, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset_test, batch_size=BATCH_SIZE, shuffle=True)

运行结果:
在这里插入图片描述

二、定义卷积神经网络

1.定义卷积神经网络

定义名为 ConvNet 的卷积神经网络类,它继承自 torch.nn.Module。这个类实现了一个简单的卷积神经网络结构,用于图像分类任务。

以下是网络结构的详细说明:
1)init(self): 构造函数中,定义了以下层:

  • 6 个卷积层(conv1 到 conv6),每个卷积层后面都跟着一个 ReLU 激活函数和 一个最大池化层(max_pool1 到max_pool4)。
  • 每个卷积层的输出通道数逐渐增加,从 32 到 128。
  • 两个全连接层(fc1 和 fc2),其中 fc1 具有512 个神经元,fc2 具有 1 个神经元(对应于二分类问题)。
  • 最后一个全连接层后面跟着一个 Sigmoid 激活函数。

2)forward(self, x): 前向传播函数接收输入 x,并依次通过以下层:

  • 6 个卷积和池化层的组合,用于提取图像特征。
  • 将最后一个池化层的输出特征图展平为一维向量。
  • 通过全连接层 fc1 和 fc2。
  • 通过 Sigmoid 激活函数生成最终输出。
class ConvNet(nn.Module):def __init__(self):super(ConvNet, self).__init__()self.conv1 = nn.Conv2d(3, 32, 3)self.max_pool1 = nn.MaxPool2d(2)self.conv2 = nn.Conv2d(32, 64, 3) self.max_pool2 = nn.MaxPool2d(2) self.conv3 = nn.Conv2d(64, 64, 3) self.conv4 = nn.Conv2d(64, 64, 3) self.max_pool3 = nn.MaxPool2d(2) self.conv5 = nn.Conv2d(64, 128, 3) self.conv6 = nn.Conv2d(128, 128, 3) self.max_pool4 = nn.MaxPool2d(2) self.fc1 = nn.Linear(4608, 512) self.fc2 = nn.Linear(512, 1)def forward(self, x): in_size = x.size(0) x = self.conv1(x) x = F.relu(x) x = self.max_pool1(x) x = self.conv2(x) x = F.relu(x) x = self.max_pool2(x) x = self.conv3(x) x = F.relu(x) x = self.conv4(x) x = F.relu(x) x = self.max_pool3(x) x = self.conv5(x) x = F.relu(x) x = self.conv6(x) x = F.relu(x)x = self.max_pool4(x) # 展开x = x.view(in_size, -1)x = self.fc1(x)x = F.relu(x) x = self.fc2(x) x = torch.sigmoid(x) return x

2.定义学习率

定义模型的学习率为 0.0001。

modellr = 1e-4

3.实例化模型并且移动到GPU

创建 ConvNet 模型实例,并使用 to(DEVICE) 方法将其移动到指定的计算设备上。如果 DEVICE 是 ‘cuda’,则模型将被移动到 GPU;如果 DEVICE 是 ‘cpu’,则模型将被移动到 CPU。

# 实例化模型并且移动到GPU
model = ConvNet().to(DEVICE)

4.选择优化器

创建 Adam 优化器,其中 model.parameters() 表示模型的所有参数,lr=modellr 表示学习率为 0.0001。

# 选择简单暴力的Adam优化器,学习率调低
optimizer = optim.Adam(model.parameters(), lr=modellr)

三、定义调整学习率的函数

1.定义调整学习率的函数

这个函数实现一个简单的学习率衰减策略,它能够根据当前的 epoch 调整学习率。

1)定义学习率衰减规则:

  • modellrnew = modellr * (0.1 ** (epoch // 5)) :定义了一个学习率衰减规则,其中 modellr
    是初始学习率,0.1 ** (epoch // 5) 表示每 5 个 epoch 学习率减少 10 倍。

2)打印新学习率:

  • print(“lr:”,modellrnew):打印出新的学习率。

3)调整优化器的学习率:

  • for param_group in optimizer.param_groups:
    遍历优化器中的每个参数组,并将每个参数组的学习率设置为新学习率。
def adjust_learning_rate(optimizer, epoch):"""Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""modellrnew = modellr * (0.1 ** (epoch // 5)) print("lr:",modellrnew) for param_group in optimizer.param_groups: param_group['lr'] = modellrnew

四、训练模型

1.设置模型为训练模式

将模型设置为训练模式,这样模型在计算梯度时会使用 Dropout 和 BatchNorm 层。

# 定义训练过程
def train(model, device, train_loader, optimizer, epoch):model.train() 

2.遍历训练数据加载器

遍历 train_loader 中的每个批次,并将数据和标签移动到指定的设备上。然后,它执行前向传播、计算损失、反向传播和更新模型参数。

for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device).float().unsqueeze(1)
optimizer.zero_grad()
output = model(data)

# print(output)
loss = F.binary_cross_entropy(output, target)
loss.backward()
optimizer.step()

3.打印进度

在每 10 个批次后打印当前的轮次、批次数、损失值和进度百分比,以便监控训练进度。

if (batch_idx + 1) % 10 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),100. * (batch_idx + 1) / len(train_loader), loss.item()))

五、验证模型

1.设置模型为验证模式

将模型设置为验证模式,这样模型在计算梯度时不会使用 Dropout 和 BatchNorm 层。

# 定义测试过程
def val(model, device, test_loader):model.eval()

2.初始化计数器

用于在每次迭代时累积损失、正确预测的数量和总样本数。

test_loss = 0
correct = 0
total = 0

3.遍历测试数据加载器

遍历 test_loader 中的每个批次,并将数据和标签移动到指定的设备上。然后,它执行前向传播并计算损失。由于模型处于验证模式,它不会计算梯度。同时,它累积损失、样本数和正确预测的数量。

  with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device).float().unsqueeze(1)output = model(data)test_loss += F.binary_cross_entropy(output, target, reduction='mean').item()pred = torch.tensor([[1] if num[0] >= 0.5 else [0] for num in output]).to(device)correct += pred.eq(target.long()).sum().item()total += target.size(0)  # 计算总数

4.计算准确率

accuracy = 100. * correct / total

5.打印验证结果

在验证过程结束时打印平均损失和准确率。

print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(

test_loss, correct, total, 100 * correct / total))

说明:这个函数实现了一个基本的验证循环,它能够验证模型在测试数据集上的性能。在实际使用中,您可能需要根据您的具体任务调整超参数,并确保数据加载器的设置与模型的需求相匹配。

五、定义训练循环

1.调整学习率
在每个 epoch 开始时调整学习率。

# 训练
for epoch in range(1, EPOCHS + 1):adjust_learning_rate(optimizer, epoch)

2.执行训练和验证

在每个 epoch 中执行训练和验证过程。

   train(model, DEVICE, train_loader, optimizer, epoch) val(model, DEVICE, test_loader)

3.保存模型

在训练结束后保存模型的状态字典。

torch.save(model.state_dict(), 'ConvNet.pth')

运行结果:
在这里插入图片描述
在这里插入图片描述

# 二、测试模型import torch
from PIL import Image
import torchvision.transforms as transforms
from torchvision import models
from torch.autograd import Variable# 定义数据预处理
transform_test = transforms.Compose([transforms.Resize(100),transforms.RandomVerticalFlip(),transforms.RandomCrop(50),transforms.RandomResizedCrop(150),transforms.ColorJitter(brightness=0.5, contrast=0.5, hue=0.5),transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])# 定义类别
classes = ['cat', 'dog']  # 替换为您的实际类别名称# 检查是否有可用的 GPU
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 定义自定义的 VGG-19 模型
# 定义网络
class ConvNet(nn.Module):def __init__(self):super(ConvNet, self).__init__()self.conv1 = nn.Conv2d(3, 32, 3)self.max_pool1 = nn.MaxPool2d(2)self.conv2 = nn.Conv2d(32, 64, 3)self.max_pool2 = nn.MaxPool2d(2)self.conv3 = nn.Conv2d(64, 64, 3)self.conv4 = nn.Conv2d(64, 64, 3)self.max_pool3 = nn.MaxPool2d(2)self.conv5 = nn.Conv2d(64, 128, 3)self.conv6 = nn.Conv2d(128, 128, 3)self.max_pool4 = nn.MaxPool2d(2)self.fc1 = nn.Linear(4608, 512)self.fc2 = nn.Linear(512, 1)def forward(self, x):in_size = x.size(0)x = self.conv1(x)x = F.relu(x)x = self.max_pool1(x)x = self.conv2(x)x = F.relu(x)x = self.max_pool2(x)x = self.conv3(x)x = F.relu(x)x = self.conv4(x)x = F.relu(x)x = self.max_pool3(x)x = self.conv5(x)x = F.relu(x)x = self.conv6(x)x = F.relu(x)x = self.max_pool4(x)# 展开x = x.view(in_size, -1)x = self.fc1(x)x = F.relu(x)x = self.fc2(x)x = torch.sigmoid(x)return x# 实例化 Resnet50 类# 加载权重
model.load_state_dict(torch.load("ConvNet.pth"))
model.to(DEVICE)
model.eval()# 定义预测函数
def predict_image(image_path):# 打开图片image = Image.open(image_path)# 应用预处理image = transform(image).unsqueeze(0)  # 添加batch维度# 转换为Variable(如果模型需要)image = Variable(image).to(DEVICE)# 获取模型预测output = model(image)_, prediction = torch.max(output.data, 1)return classes[prediction.item()]# 上传的图片路径
uploaded_image_path = '44.jpg'
# 进行预测
predicted_class = predict_image(uploaded_image_path)print(f"The uploaded image is predicted as: {predicted_class}")

运行结果:
在这里插入图片描述

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

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

相关文章

【Day02】0基础微信小程序入门-学习笔记

文章目录 模板与配置学习目标WXML 模板语法1.数据绑定(类似于 Vue2 )2. 事件绑定3. 条件渲染4.列表渲染 WXSS模板样式1. rpx尺寸单位2.样式导入3. 全局样式和局部样式 全局配置1. window2. tabBar 页面配置网络数据请求总结 持续更新~ 模板与配置 学习目…

gateway整合sentinel限流

官方文档:https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81 从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流: route 维度:即在 Spr…

【第28章】Vue实战篇之用户重置密码

文章目录 前言一、调用接口二、重置密码三、界面展示总结 前言 这里我们来通过调用后端接口来完成密码重置功能并且修改成功清除缓存重新登录。 一、调用接口 export const userResetPasswordService (data)>{return request.patch(/user/updatePwd, data) }二、重置密码…

【数据结构与算法】详解循环队列:基于数组实现高效存储与访问

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ​ 目录 一、引言 🍃队列的概念 🍃循环队列的概念 🍃为什…

DIY灯光特效:霓虹灯动画制作教程

下面我们根据这张霓虹灯案例,教大家如何用智能动物霓虹灯闪烁的效果,大家可以根据思路,实现自己想要的动效效果,一起动手来做吧。 即时设计-可实时协作的专业 UI 设计工具 设置背景 新建画板尺寸为:800PX^600PX,设置背景色#120527。 绘制主题 输入自己喜欢文案,轮廓化,具体…

网络基础-协议

一、ARP 通过IP得到Mac 首先会查看缓存的arp表中是否有相应的IP和Mac对应关系,如果有直接进行包封装。如果没有则进行广播当对应的地址就收到广播包后会根据arp中的源地址进行单播返回相应的IP和Mac对应关系。 arp -a 查看现有的arp缓存 二、RARP反向地址解析 通过…

酒店多商户版微信小程序源码

一站式预订新体验 一、引言:打破传统,开启智能预订新时代 在数字化浪潮的推动下,传统的酒店预订方式已经逐渐无法满足现代人的需求。为此,一款集众多酒店商户于一体的“酒店多商户版小程序”应运而生,以其便捷、智能…

江门电子行业实施MES系统前后对比

在江门电子行业实施MES系统之前和之后的对比可以涉及以下几个方面: 生产效率提升:实施MES系统后,江门电子行业可以实现生产过程的实时监控和优化,减少生产中的浪费和停机时间,提高生产效率。 质量控制改善:…

【机器学习】机器学习重要方法——深度学习:理论、算法与实践

文章目录 引言第一章 深度学习的基本概念1.1 什么是深度学习1.2 深度学习的历史发展1.3 深度学习的关键组成部分 第二章 深度学习的核心算法2.1 反向传播算法2.2 卷积神经网络(CNN)2.3 循环神经网络(RNN) 第三章 深度学习的应用实…

解释一下在React中,什么是“渲染Props”模式,以及它与使用Hooks之前的状态管理有何不同?

在React中,"渲染Props"模式是一种组件设计模式,它通过将一个函数作为prop传递给组件,允许父组件定义子组件的渲染逻辑。这种模式使得组件更加灵活和可复用,因为它们可以接受一个渲染函数来决定如何渲染自己。 渲染Prop…

视频监控解决方案:视频平台升级技术方案(下)

目录 1 项目概况 2 项目需求 2.1 视频感知资源扩充 2.2 视频支撑能力升级 2.3 视频应用能力升级 3 技术设计方案 3.1系统总体架构 3.2视频感知资源扩充设计 3.3 视频支撑能力升级设计 3.4 视频应用能力升级设计 3.4.1视频资源目录管理 3.4.2标签管理 3.4.3设备智能…

MySQL----undo log回滚日志原理、流程以及与redo log比较

回滚日志 回滚日志,保存了事务发生之前的数据的一个版本,用于事务执行时的回滚操作,同时也是实现多版本并发控制(MVCC)下读操作的关键技术。 如何理解Undo Log 事务需要保证原子性,也就是事务中的操作要…

Nvidia Isaac Sim图编程OmniGraph 入门教程 2024(6)

Nvidia Isaac Sim 入门教程 2024 版权信息 Copyright 2023-2024 Herman YeAuromix. All rights reserved.This course and all of its associated content, including but not limited to text, images, videos, and any other materials, are protected by copyright law. …

学习笔记——动态路由——RIP(距离矢量协议)

一、距离矢量协议 1、距离矢量协议 矢量行为:协议收到一个路由之后,查看是否可以加入到本地的路由表中,如果可以加入,则可以传递,如果不可以加入,则无法传递。 距离矢量路由协议 RIP基于距离矢量算法(又…

使用 Reqable 在 MuMu 模拟器进行App抓包(https)

1、为什么要抓包? 用开发手机应用时,查看接口数据不能像在浏览器中可以直接通过network查看,只能借助抓包工具来抓包,还有一些线上应用我们也只能通过抓包来排查具体的问题。 2、抓包工具 实现抓包,需要一个抓包工具…

​【VMware】VMware Workstation的安装

目录 🌞1. VMware Workstation是什么 🌞2. VMware Workstation的安装详情 🌼2.1 VMware Workstation的安装 🌼2.2 VMware Workstation的无限使用 🌞1. VMware Workstation是什么 VMware Workstation是一款由VMwar…

【多模态】BEIT: BERT Pre-Training of Image Transformers

论文:BEIT: BERT Pre-Training of Image Transformers 链接:https://arxiv.org/pdf/2301.00184 Introduction BEIT(Bidirectional Encoder representation from Image Transformers)Motivation: 启发于BERT的自编码方式&#xf…

【Linux】Centos升级到国产操作系统Openeuler

一、前言 迁移工具采用Openeuler官网提供的x2openEuler工具,是一款将源操作系统迁移到目标操作系统的迁移工具套件,具有批量化原地升级能力,当前支持将源 OS 升级至 openEuler 20.03。 官网链接:openEuler迁移专区 | 迁移专区首页…

详解Spring AOP(一)

目录 1. AOP概述 2.Spring AOP快速入门 2.1引入AOP依赖 2.2编写AOP程序 3.Spring AOP核心概念 3.1切点(PointCut) 3.2连接点(Join Point) 3.3通知(Advice) 3.4切面(Aspect) …

SwiftUI 6.0(iOS 18/macOS 15)关于颜色 Color 的新玩法

概览 WWDC 2024 重装升级的 SwiftUI 6.0 让 Apple 不同平台(iOS 18/macOS 15)显得愈发的冰壶玉衡、美轮美奂。 之前梦寐以求的颜色混合功能在 WWDC 24 里终于美梦成真啦! 在本篇博文中,您将学到如下内容: 概览1. 梦想…