【Pytorch】计算机视觉项目——卷积神经网络CNN模型识别图像分类

目录

  • 一、前言
  • 二、CNN可视化解释器
    • 1. 卷积层工作原理
  • 三、详细步骤说明
    • 1. 数据集准备
    • 2.DataLoader
    • 3. 搭建模型CNN
      • 3.1 设置设备
      • 3.2 搭建CNN模型
      • 3.3 设置loss 和 optimizer
      • 3.4 训练和测试循环
    • 4. 模型评估和结果输出


一、前言

在上一篇笔记《【Pytorch】整体工作流程代码详解(新手入门)》中介绍了Pytorch的整体工作流程,本文继续说明如何使用Pytorch搭建卷积神经网络(CNN模型)来给图像分类。

其他相关文章:
深度学习入门笔记:总结了一些神经网络的基础概念。
TensorFlow专栏:《计算机视觉入门系列》介绍如何用TensorFlow框架实现卷积分类器。


二、CNN可视化解释器

卷积分类器,是通过将导入的图片,一层层筛选、过滤、学习图形的特征,最后实现对输入数据的分类、识别或预测。

下面是github上一个CNN可交互的可视化解释器( 链接在此)。

在这里插入图片描述
从上面的全局图可见,CNN模型由多个卷积层和池化层交替堆叠而成,图片被进行了不同的处理,每一层都被提取出了不同的特征,最终将每个单元的输出汇总,输出分类。

1. 卷积层工作原理

相当于是有一个滤镜格子(叫做卷积核或者滤波器),从左到右、从上至下地扫描整个输入图层,并生成新的图层。
在这里插入图片描述
整个过程中会压缩数据,如下图所示,将一个3*3 的图形,压缩成一个格子。
在这里插入图片描述

参数说明
Input输入数据,中间是一个44的格子
Padding, 外面加的一圈格子,加一个单元。
Kernel Size卷积核大小:这里是3
3 ,左手边的红格子
Stride 步长:卷积核每次走多少格子
在这里插入图片描述


三、详细步骤说明

1. 数据集准备

import torch
from torch import nn
import torchvision
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
print(f"Pytorch version:{torch.__version__}\n torchvision version:{torchvision.__version__}")

在这里插入图片描述
数据集介绍:
FashionMNIST是torchvision自带的一个图像数据集,用于机器学习和计算机视觉的训练和测试。它包含了10个不同类别的服装物品的灰度图像,包括T恤、裤子、套衫、裙子、外套、凉鞋、衬衫、运动鞋、包和短靴。每张图片的分辨率是28x28像素。

train_data=datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor(),target_transform=None
)test_data=datasets.FashionMNIST(root="data",train=False,download=True,transform=ToTensor(),target_transform=None
)#数据集查看
image, label = train_data[0]
# image, label #查看第一条训练数据
image.shape  #查看数据的形状

在这里插入图片描述
图像张量的形状是[1, 28, 28],或者说:[颜色=1,高度=28,宽度=28]

# 查看类别
class_names = train_data.classes
class_names

在这里插入图片描述

#图形可视化
import matplotlib.pyplot as plt
image, label = train_data[0]
print(f"Image shape: {image.shape}")
plt.imshow(image.squeeze()) 
plt.title(label);

在这里插入图片描述

2.DataLoader

from torch.utils.data import DataLoader# 设置批处理大小超参数
BATCH_SIZE = 32# 将数据集转换为可迭代的(批处理)
train_dataloader = DataLoader(train_data,batch_size=BATCH_SIZE,  # 每个批次有多少样本?shuffle=True  # 是否随机打乱?
)test_dataloader = DataLoader(test_data,batch_size=BATCH_SIZE,shuffle=False  # 测试数据集不一定需要洗牌
)#打印结果
print(f"Dataloaders: {train_dataloader, test_dataloader}")
print(f"Length of train dataloader: {len(train_dataloader)} batches of {BATCH_SIZE}")
print(f"Length of test dataloader: {len(test_dataloader)} batches of {BATCH_SIZE}")

在这里插入图片描述

参数介绍:
shuffle:指对数据集进行随机打乱,以便在训练模型时以随机顺序呈现数据。这样做有助于提高模型的泛化能力并减少模型对输入数据顺序的依赖性。相反,对于测试数据集通常被设置为False,因为在评估模型性能时,我们希望保持数据的原始顺序,以便能够正确评估模型在真实数据上的表现。

train_features_batch, train_labels_batch = next(iter(train_dataloader))
train_features_batch.shape, train_labels_batch.shape

在这里插入图片描述

3. 搭建模型CNN

3.1 设置设备

import torch
device = "cuda" if torch.cuda.is_available() else "cpu"
device

在GPU上跑。
在这里插入图片描述

3.2 搭建CNN模型

回顾一下CNN的参数设置:

  1. in_channels:输入数据的通道数,对于二维卷积,表示输入图像或特征图的深度或通道数。
  2. out_channels:输出的通道数,即卷积核的数量。每个卷积核生成一个输出通道。
  3. kernel_size:卷积核的大小或滤波器的大小,用整数或元组表示,指定了卷积核的高度和宽度。kernel_size=3意味着卷积核的高度和宽度均为3。
  4. stride:卷积核滑动的步长,决定卷积核在输入数据上滑动的距离。stride=1表示卷积核在输入上每次滑动1个步长。
  5. padding:在输入数据周围填充0的层数。填充有助于保持输入和输出尺寸相同,特别是在卷积层之间传递信息时。这里的padding=1表示在输入数据周围填充一层0,以保持卷积操作后尺寸不变。
# Create a convolutional neural network
class FashionMNISTModelV2(nn.Module):def __init__(self, input_shape: int, hidden_units: int, output_shape: int):super().__init__()self.block_1 = nn.Sequential(nn.Conv2d(in_channels=input_shape,out_channels=hidden_units,kernel_size=3, stride=1,padding=1),nn.ReLU(),nn.Conv2d(in_channels=hidden_units,out_channels=hidden_units,kernel_size=3,stride=1,padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=2,stride=2) )self.block_2 = nn.Sequential(nn.Conv2d(hidden_units, hidden_units, 3, padding=1),nn.ReLU(),nn.Conv2d(hidden_units, hidden_units, 3, padding=1),nn.ReLU(),nn.MaxPool2d(2))self.classifier = nn.Sequential(nn.Flatten(),nn.Linear(in_features=hidden_units*7*7,out_features=output_shape))def forward(self, x: torch.Tensor):x = self.block_1(x)# print(x.shape)x = self.block_2(x)# print(x.shape)x = self.classifier(x)# print(x.shape)return x# 加入参数
torch.manual_seed(42)
model_2 = FashionMNISTModelV2(input_shape=1,hidden_units=10,output_shape=len(class_names)).to(device)
model_2

在这里插入图片描述

3.3 设置loss 和 optimizer

导入accurcay_fn辅助函数文件

import requests
from pathlib import Path# 从Learn PyTorch存储库中下载辅助函数(如果尚未下载)
if Path("helper_functions.py").is_file():print("helper_functions.py已存在,跳过下载")
else:print("正在下载helper_functions.py")# 注意:你需要使用"raw" GitHub URL才能使其工作request = requests.get("https://raw.githubusercontent.com/mrdbourke/pytorch-deep-learning/main/helper_functions.py")with open("helper_functions.py", "wb") as f:f.write(request.content)

创建loss、accuracy和optimizer

from helper_functions import accuracy_fn# 设置loss和optimizer
loss_fn = nn.CrossEntropyLoss() # this is also called "criterion"/"cost function" in some places
optimizer = torch.optim.SGD(params=model_0.parameters(), lr=0.1)

创建一个计时器

from timeit import default_timer as timer
def print_train_time(start:float,end:float,device:torch.device=None):total_time=end-startprint(f"Train time on {device}: {total_time:.3f} seconds")return total_time

3.4 训练和测试循环

def train_step(model: torch.nn.Module,data_loader: torch.utils.data.DataLoader,loss_fn: torch.nn.Module,optimizer: torch.optim.Optimizer,accuracy_fn,device: torch.device = device):train_loss, train_acc = 0, 0model.to(device)for batch, (X, y) in enumerate(data_loader):X, y = X.to(device), y.to(device)y_pred = model(X)loss = loss_fn(y_pred, y)train_loss += losstrain_acc += accuracy_fn(y_true=y,y_pred=y_pred.argmax(dim=1))optimizer.zero_grad()loss.backward()optimizer.step()train_loss /= len(data_loader)train_acc /= len(data_loader)print(f"Train loss: {train_loss:.5f} | Train accuracy: {train_acc:.2f}%")def test_step(data_loader: torch.utils.data.DataLoader,model: torch.nn.Module,loss_fn: torch.nn.Module,accuracy_fn,device: torch.device = device):test_loss, test_acc = 0, 0model.to(device)model.eval() # put model in eval mode# Turn on inference context managerwith torch.inference_mode():for X, y in data_loader:X, y = X.to(device), y.to(device)test_pred = model(X)test_loss += loss_fn(test_pred, y)test_acc += accuracy_fn(y_true=y,y_pred=test_pred.argmax(dim=1) # Go from logits -> pred labels)test_loss /= len(data_loader)test_acc /= len(data_loader)print(f"Test loss: {test_loss:.5f} | Test accuracy: {test_acc:.2f}%\n")
torch.manual_seed(42)from timeit import default_timer as timer
train_time_start_model_2 = timer()epochs = 3
for epoch in tqdm(range(epochs)):print(f"Epoch: {epoch}\n---------")train_step(data_loader=train_dataloader,model=model_2,loss_fn=loss_fn,optimizer=optimizer,accuracy_fn=accuracy_fn,device=device)test_step(data_loader=test_dataloader,model=model_2,loss_fn=loss_fn,accuracy_fn=accuracy_fn,device=device)train_time_end_model_2 = timer()
total_train_time_model_2 = print_train_time(start=train_time_start_model_2,end=train_time_end_model_2,device=device)

在这里插入图片描述

4. 模型评估和结果输出

torch.manual_seed(42)
def eval_model(model: torch.nn.Module,data_loader: torch.utils.data.DataLoader,loss_fn: torch.nn.Module,accuracy_fn,device: torch.device = device):  #注意loss, acc = 0, 0model.eval()with torch.inference_mode():for X, y in data_loader:#注意设备转移X, y = X.to(device), y.to(device)y_pred = model(X)loss += loss_fn(y_pred, y)acc += accuracy_fn(y_true=y, y_pred=y_pred.argmax(dim=1))loss /= len(data_loader)acc /= len(data_loader)return {"model_name": model.__class__.__name__, "model_loss": loss.item(),"model_acc": acc}model_2_results = eval_model(model=model_2,data_loader=test_dataloader,loss_fn=loss_fn,accuracy_fn=accuracy_fn
)
model_2_results

模型输出结果:
在这里插入图片描述

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

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

相关文章

虚析构函数

1)类指针指向本身的对象 Son *xiaoming new Son; delete xiaoming; 构造及析构顺序: 父类构造 子类构造; 子类析构; 父类析构。 2)父类指针指向子类对象,,父类析构函数不是虚函数 Father *father new Son; delete f…

YOLOv5源码中的参数超详细解析(5)— 验证部分(val.py)参数解析

前言:Hello大家好,我是小哥谈。YOLOv5是一种先进的目标检测算法,它可以实现快速和准确的目标检测。在YOLOv5源码中,train.py和detect.py文件讲完了之后,接着就是讲val.py文件了。本节课就结合源码对val.py文件进行逐行解析~!🌈 前期回顾: YOLOv5源码中的参数超详细解…

RK3566上运行yolov5模型进行图像识别

一、简介 本文记录了依靠RK官网的文档,一步步搭建环境到最终在rk3566上把yolov5 模型跑起来。最终实现的效果如下: 在rk3566 板端运行如下app: ./rknn_yolov5_demo model/RK356X/yolov5s-640-640.rknn model/bus.jpg其中yolov5s-640-640.r…

GPT学习笔记

百度的文心一言 阿里的通义千问 通过GPT能力,提升用户体验和产品力 GPT的出现是AI的iPhone时刻。2007年1月9日,第一代iPhone发布,开启移动互联网时代。新一轮的产业革命。 GPT模型发展时间线: Copilot - 副驾驶 应用&#xf…

基于DevEco Studio的OpenHarmony应用原子化服务(元服务)入门教程

一、创建项目 二、创建卡片 三、应用服务代码 Index.ets Entry Component struct Index {State TITLE: string OpenHarmony;State CONTEXT: string 创新召见未来!;build() {Row() {Column() {Text(this.TITLE).fontSize(30).fontColor(0xFEFEFE).fontWeight(…

基于SpringAOP实现自定义接口权限控制

文章目录 一、接口鉴权方案分析1、接口鉴权方案2、角色分配权限树 二、编码实战1、定义权限树与常用方法2、自定义AOP注解3、AOP切面类(也可以用拦截器实现)4、测试一下 一、接口鉴权方案分析 1、接口鉴权方案 目前大部分接口鉴权方案,一般…

SurfaceFlinger的硬件Vsync深入分析-千里马android framework车机手机系统开发

背景: 学过或者你看过surfaceflinger相关文章同学都知道,vsync其实都是由surfaceflinger软件层面进行模拟的,但是软件模拟有可能会有误差或偏差,这个时候就需要有个硬件vsync帮忙校准。 故才会在surfaceflinger的systrace出现如下…

应用安全四十二:SSO安全

一、什么是SSO SSO是单点登录(Single Sign On)的缩写,是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的企业业务整合的解决方案之一。 身份验证过程依赖于双方之间的信任关…

新一代存储介质技术SCM探讨

什么是SCM介质? SCM介质现状 SCM介质产品形态和在存储系统中的应用 高性能SSD 字节型DIMM形态 小结 什么是SCM介质? SCM(Storage Class Memory)是当前业界非常热门的新介质形态,同时具备持久化(Storage Cla…

VMware安装CentOS最小化开发环境导引

目录 一、概要 二、介绍 三、下载 四、安装 4.1 创建虚拟机 4.2 安装CentOS 五、配置网卡 六、配置本地安装源 七、安装软件 7.1 gcc/g 7.2 C的atomic库 7.3 java 7.4 Cmake 7.5 MariaDB客户端(兼容mysql) 八、用户配置文件.bash_profile…

python学习10

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

MySQL进阶之性能优化与调优技巧

数据库开发-MySQL 1. 多表查询1.1 概述1.1.2 介绍1.1.3 分类 1.2 内连接1.3 外连接1.4 子查询1.4.1 介绍1.4.2 标量子查询1.4.3 列子查询1.4.4 行子查询1.4.5 表子查询 2. 事务2.1 介绍2.2 操作2.3 四大特性 3. 索引3.1 介绍3.2 结构3.3 语法 1. 多表查询 1.1 概述 1.1.2 介绍…