当前位置: 首页 > news >正文

CNN模型手写数字识别及其相关概念

        

CNN相关概念
卷积神经网络(Convolutional Neural Network,CNN)是一种专门为处理具有网格结构数据的深度学习模型,例如图像、声音和文本。
卷积核

特征提取:识别和提取输入数据中的局部特征。通过在不同位置应用卷积核,网络能够捕捉到图像中的边缘、纹理、形状等特征。

降维:卷积核在应用过程中,会减少特征图(feature map)的尺寸。

参数共享:在卷积层中,同一卷积核会在整个输入数据上滑动,这意味着卷积核中的权重参数是共享的。

局部响应归一化(LRN):有助于提高特征图中的对比度,使得模型能够更好地识别图像中的关键特征。

平移不变性:卷积核的滑动窗口特性使得网络对输入数据的平移具有不变性,即网络不会因为输入数据的位置变化而改变其识别特征的能力。

卷积层使用卷积核对输入数据进行滑动窗口处理,提取局部特征。
池化层池化层位于卷积层之后,用于减小特征图的尺寸,减少参数数量,并减少过拟合的风险。
全连接层其中每个神经元都与前一层中的所有神经元相连。全连接层通常位于网络的输出层,用于将前一层的特征映射到具体的输出类别或预测。在全连接层之后,通常会使用一个或多个激活函数来产生概率分布或类别预测。

CNN一般实现步骤:
  1. 数据加载与预处理。
  2. 模型搭建。
  3. 定义损失函数、优化器。
  4. 模型训练。
  5. 模型测试。

 基于Pytorch框架实现CNN神经网络手写数字识别。
流程步骤:
  1. 导入相关库。
  2. 使用MNIST数据集,进行数据预处理。
  3. CNN模型搭建。
  4. 参数设置。
  5. 模型训练。
 步骤1代码:
import numpy as np
import torch 
from torch import nn
from torchvision import datasets, transforms,utils
from PIL import Image
import matplotlib.pyplot as plt
 步骤2代码:
# 定义超参数
batch_size = 128  # 设置每个批次(batch)的样本数为128# 对输入的数据进行标准化处理
# transforms.ToTensor() 将图像数据转换为 PyTorch 中的张量(tensor)格式,并将像素值缩放到 0-1 的范围内。
# 这是因为神经网络需要的输入数据必须是张量格式,并且需要进行归一化处理,以提高模型的训练效果。
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean=[0.5],std=[0.5])])# 加载MNIST数据集
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True)# 创建数据加载器(用于将数据分次放进模型进行训练)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True,  # 装载过程中随机乱序num_workers=2)  # 表示2个子进程加载数据
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False,num_workers=2)
  • batch_size = 128: 设置每次迭代中从数据集中取样的样本数量。

  • transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=[0.5], std=[0.5])]): 定义一个转换器,它包含两个子转换器:transforms.ToTensor()用于将图像数据转换为PyTorch的张量格式,并归一化像素值到0-1范围内;transforms.Normalize(mean=[0.5], std=[0.5])用于进一步标准化像素值,使其均值为0.5,标准差为0.5。

  • train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True): 创建一个MNIST数据集实例,用于训练。root='./data'指定数据集下载和存储的路径;train=True指定加载训练数据;transform=transform指定之前定义的转换器;download=True表示如果数据集不在指定路径下,则自动下载。

  • test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True): 创建一个MNIST数据集实例,用于测试。train=False指定加载测试数据。

  • train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True, num_workers=2): 创建一个数据加载器,用于训练模型。dataset=train_dataset指定要加载的数据集;batch_size=batch_size指定每个批次的大小;shuffle=True指定是否在装载过程中随机乱序;num_workers=2指定使用2个子进程来并行加载数据。

  • test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False, num_workers=2): 创建一个数据加载器,用于测试模型。shuffle=False指定在装载过程中不进行随机乱序。其他参数与训练数据加载器相同。

 步骤3代码:
class CNN(nn.Module):# 定义网络结构def __init__(self):super(CNN, self).__init__()  # 调用父类的初始化方法# 定义第一个卷积层self.conv1 = nn.Conv2d(in_channels=1, out_channels=16,  # 输入通道数为1,输出通道数为16kernel_size=5, stride=1, padding=2)  # 卷积核大小为5x5,步长为1,填充为2# 定义第一个ReLU激活函数self.relu1 = nn.ReLU()# 定义第一个池化层self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)  # 池化核大小为2x2,步长为2# 定义第二个卷积层self.conv2 = nn.Conv2d(in_channels=16, out_channels=32,  # 输入通道数为16,输出通道数为32kernel_size=5, stride=1, padding=2)  # 卷积核大小为5x5,步长为1,填充为2# 定义第二个ReLU激活函数self.relu2 = nn.ReLU()# 定义第二个池化层self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)  # 池化核大小为2x2,步长为2# 定义第一个全连接层self.fc1 = nn.Linear(in_features=7*7*32, out_features=256)  # 输入特征数为7x7x32,输出特征数为256# 定义第一个全连接层的ReLU激活函数self.relu3 = nn.ReLU()# 定义第二个全连接层self.fc2 = nn.Linear(in_features=256, out_features=10)  # 输入特征数为256,输出特征数为10# 定义前向传播过程的计算函数def forward(self, x):# 第一层卷积、激活函数和池化x = self.conv1(x)x = self.relu1(x)x = self.pool1(x)# 第二层卷积、激活函数和池化x = self.conv2(x)x = self.relu2(x)x = self.pool2(x)# 将数据平展成一维x = x.view(-1, 7*7*32)# 第一层全连接层x = self.fc1(x)x = self.relu3(x)# 第二层全连接层x = self.fc2(x)return x
 步骤4代码:
import torch.optim as optimlearning_rate = 0.001 # 学习率# 定义损失函数,计算模型的输出与目标标签之间的交叉熵损失
criterion = nn.CrossEntropyLoss()
# 训练过程通常采用反向传播来更新模型参数,这里使用的是SDG(随机梯度下降)优化器
# momentum 表示动量因子,可以加速优化过程并提高模型的泛化性能。
optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.9)
#也可以选择Adam优化方法
# optimizer = torch.optim.Adam(net.parameters(),lr=1e-2)
步骤5代码:
# 实例化CNN模型
model = CNN()
num_epochs = 10  # 定义迭代次数为10# 如果可用的话使用 GPU 进行训练,否则使用 CPU 进行训练。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 将神经网络模型 model 移动到指定的设备上。
model = model.to(device)
total_step = len(train_loader)
for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):# 将输入数据 images 和标签数据 labels 移动到指定的设备上。images = images.to(device)labels = labels.to(device)optimizer.zero_grad()  # 清空上一个batch的梯度信息# 将输入数据 images 喂入神经网络模型 model 中进行前向计算,得到模型的输出结果 outputs。outputs = model(images)# 使用交叉熵损失函数 criterion 计算模型输出 outputs 与标签数据 labels 之间的损失值 loss。loss = criterion(outputs, labels)# 使用反向传播算法计算模型参数的梯度信息,并使用优化器 optimizer 对模型参数进行更新。loss.backward()optimizer.step()  # 更新梯度# 输出训练结果if (i + 1) % 100 == 0:print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch + 1, num_epochs, i + 1, total_step, loss.item()))print('Finished Training')

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 一个全面、先进、公平且模块化的开源RAG框架
  • 【JVM】JVM栈帧中的动态链接 与 Java的面向对象特性--多态
  • SOMEIP_ETS_098: SD_ClientService_subscribe_without_method_call
  • [数据集][目标检测]轮胎缺陷检测数据集VOC+YOLO格式2154张4类别
  • go基础知识归纳总结
  • 【ARM compiler】生成ELF文件中包含了那些内容
  • Mertens定理(级数乘法)
  • 电脑安装Winserver2016无法安装网卡驱动(解决办法)
  • Android 12 SystemUI下拉状态栏禁止QuickQSPanel展开
  • LeetCode:977. 有序数组的平方 双指针 时间复杂度O(n)
  • 利用数据分析提升SEO排名的7种方法
  • C++ vectorOJ练习题
  • 【C/C++】“秒懂”学C/C++不可错过的“经典编程题” — 日期类的经典运用 (含题链接)
  • Git-下载的zip包项目重新指向github项目地址
  • Request Response
  • 深入了解以太坊
  • [译]Python中的类属性与实例属性的区别
  • 【391天】每日项目总结系列128(2018.03.03)
  • ➹使用webpack配置多页面应用(MPA)
  • 30秒的PHP代码片段(1)数组 - Array
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Linux中的硬链接与软链接
  • SpiderData 2019年2月25日 DApp数据排行榜
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 开发基于以太坊智能合约的DApp
  • 一起参Ember.js讨论、问答社区。
  • Semaphore
  • 函数计算新功能-----支持C#函数
  • 如何用纯 CSS 创作一个货车 loader
  • 正则表达式-基础知识Review
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (13)DroneCAN 适配器节点(一)
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (ZT)一个美国文科博士的YardLife
  • (二)windows配置JDK环境
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (三)终结任务
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (五)MySQL的备份及恢复
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转) 深度模型优化性能 调参
  • .form文件_一篇文章学会文件上传
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .Net 应用中使用dot trace进行性能诊断
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • [Android Pro] Notification的使用
  • [Bug]使用gradio创建应用提示AttributeError: module ‘gradio‘ has no attribute ‘inputs‘
  • [C#] 如何调用Python脚本程序
  • [C#]winform部署官方yolov10目标检测的onnx模型
  • [C#]实现GRPC通讯的服务端和客户端实例