赞
踩
在人工智能和机器学习的浪潮中,手写数字识别作为计算机视觉领域的经典问题,一直吸引着研究者和开发者的广泛关注。这项技术在实际应用中也展现出巨大的潜力,如自动化数据录入、银行支票处理、邮政编码识别等。随着深度学习技术的兴起,特别是卷积神经网络(CNN)在图像识别领域的突破性进展,手写数字识别的准确性和效率得到了显著提升。
本项目旨在构建一个基于深度学习的手写数字识别模型,将会使用Python 编程语言,结合强大的 PyTorch 库来实现。PyTorch 提供了灵活的计算图和自动微分机制等功能,使得模型的构建、训练和优化变得简单而高效。模型将从读取图像开始,通过一系列图像预处理步骤,包括灰度化、尺寸调整、归一化等,以确保输入数据的一致性和模型的泛化能力。
在模型设计上,模型采用了一个多层前馈神经网络,其中包括全连接层和ReLU 激活函数,以及用于提高模型性能的特定技术,如 Otsu 的阈值处理和形态学膨胀。这些技术的应用,旨在增强数字的可识别性,降低背景噪声的影响。通过精心设计的网络结构和训练策略,本文的模型能够在MNIST 等标准数据集上实现高准确率的手写数字识别。
在实验部分,本文将详细介绍数据的加载和预处理过程、模型的初始化和训练过程、以及模型性能的评估。本文还将展示模型结构的可视化,使读者能够直观地理解模型的工作原理。通过这些详细的实验步骤和结果分析,本文期望为读者提供一种清晰、系统的方法来理解和实现手写数字识别。
·硬件环境:AMD Ryzen 7 5800H ,16GB DDR4内存,NVIDIA GTX 3060显卡
·软件环境:Python 3.9,PyTorch 2.3.0+cpu,torchvision 0.18.0+cpu,NumPy 1.24.2
·开发工具:PyCharm 2023.2.1
打开命令行工具(在Windows上是CMD或PowerShell,在macOS或Linux上是Terminal),执行以下命令安装PyTorch。我们将使用清华大学的镜像源以加快下载速度。
pip install torch torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple
我们还将使用NumPy和Pillow等库,同样使用清华源进行安装:
pip install numpy pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
本次实验中使用的模型是一个自定义的多层前馈神经网络(Multilayer Feedforward Neural Network),专为手写数字识别任务设计。该模型利用深度学习的原理,通过学习输入图像的特征来实现对数字的有效分类。
模型结构由以下几个主要部分组成:
·输入层:接收28x28像素的手写数字图像。
·隐藏层:包含两个线性层,其中第一个线性层后接ReLU激活函数,第二个线性层同样后接ReLU激活函数。
·输出层:最后一个线性层映射到10个输出节点,代表数字0到9。
下方表格展示模型的结构,使用了torchsummary 库进行转化。
Layer (type) Output Shape Param #
Linear-1 [-1, 128] 100,480
Linear-2 [-1, 64] 8,256
Linear-3 [-1, 10] 650
Total params: 109,386
Trainable params: 109,386
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.42
Estimated Total Size (MB): 0.42
----------------------------------------------------------------
模型的输入是标准化后的灰度图像,维度为(1, 28, 28),其中1代表批次大小,28x28代表图像的尺寸
官方提供的数据集训练集索引等文件无法直接查看,MNIST数据集的训练集索引文件(例如train-images-idx3-ubyte)是一种特定格式的文件。这个文件是一个二进制文件,包含了训练集中所有图像的索引信息,每个图像的像素数据和标签信息在文件内按顺序排列。
要查看这些二进制文件中的内容,需要使用专门的程序来解析文件格式,本文提供了转化的程序,具体见附录sampled_data.py 代码。转化之后部分样本图片见下图。
模型的输入数据是灰度图像,这些图像已经被预处理并标准化,以适应模型的输入要求。具体来说,每张图像的尺寸是28x28像素,代表了一个手写数字的形状和边缘细节。
1:这个数字代表批次大小(batch size),即每次输入到模型中的图像数量。在这里,批次大小为1,意味着模型将逐个处理图像
28:图像的高度,以像素为单位
28:图像的宽度,以像素为单位
图像在输入到模型之前,会经过以下预处理步骤:
灰度转换:将彩色图像转换为灰度图像,以减少不必要的颜色信息,降低计算复杂度。
尺寸调整:将图像大小调整为28x28像素,以符合模型输入的固定尺寸要求。
标准化:将图像像素值从[0, 255]线性缩放到[0.0, 1.0]范围内,以提高模型训练的稳定性和收敛速度。
图像数据以NumPy数组的形式进行处理,数据类型为float32,像素值归一化到[0.0, 1.0]范围内。模型的输出是一个10维的概率分布向量,每个维度对应一个数字类别的预测概率。
该模型是本文根据实验目的自行设计和实现的。虽然它基于常见的多层感知机(MLP)架构,但本文根据MNIST数据集的特点对网络结构进行了调整,以优化识别性能。
模型的输出是一个10维的概率分布向量。这个向量中的每个维度对应一个数字类别(0到9),表示模型对输入图像表示该数字的预测概率。
10:这个数字代表输出向量的维度,即模型预测的类别数。在MNIST数据集中,共有10个类别,分别对应数字0到9。
输出向量中的每个元素值表示模型对输入图像属于对应数字的置信度。例如,如果输出向量中索引为2的元素值最高,那么模型预测输入图像表示数字2。
模型的最后一层是一个线性层,它将前一层的输出映射到10维空间。然后,使用log_softmax激活函数生成最终的输出向量。log_softmax不仅能够将模型输出转换为概率分布,还能够提高数值稳定性,使得模型在训练过程中更加稳定。
MNIST数据集包含60,000张训练图像和10,000张测试图像。训练集用于模型的训练,测试集用于评估模型的性能。
·训练集(Training Set):包含60,000张图像,用于模型的学习过程。这些图像提供了大量的数据,使模型能够学习到数字的特征和模式。
·测试集(Test Set):包含10,000张图像,用于评估模型在未见过的数据上的表现。测试集提供了一个衡量模型泛化能力的标准。
训练集和测试集中每个图像都是灰度的,像素值范围从0(黑色)到255(白色)。同时图像已经被大小标准化,即所有图像都调整为28*28像素,这简化了模型输入的处理。图像中的数字没有额外的背景,通常是白色背景上的黑色数字。
MNIST数据集可以在多个平台上获取,包括官方网站和各种机器学习库。可以使用 torchvision 库加载 MNIST 数据集,如果本地没有找到模型,这段代码会自动下载并加载 MNIST 数据集,使其准备好用于模型的训练和测试。
from torchvision import datasetstrain_dataset = datasets.MNIST(root='./data', train=True, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, download=True)
本文使用PyTorch的DataLoader和datasets来加载MNIST数据集。
from torchvision
import datasets, transforms# 定义图像预处理的转换
transform = transforms.Compose([ transforms.ToTensor(), # 将图像转换为张量
transforms.Normalize((0.1307,), (0.3081,)) # 标准化
])
# 加载训练集和测试集
train_dataset = datasets.MNIST(root='./data', train=True,
transform=transform, download=True)test_dataset = datasets.MNIST(root='./data', train=False, transform=transform)
# 创建DataLoader实例
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
本文定义了一个多层前馈神经网络,如下所示:
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128) # 第一个隐藏层
self.fc2 = nn.Linear(128, 64) # 第二个隐藏层
self.fc3 = nn.Linear(64, 10) # 输出层
def forward(self, x):
x = x.view(-1, 28 * 28) # 展平图像
x = F.relu(self.fc1(x)) # 第一个隐藏层的ReLU激活
x = F.relu(self.fc2(x)) # 第二个隐藏层的ReLU激活
x = self.fc3(x) # 输出层
return F.log_softmax(x, dim=1) # log_softmax输出
训练模型时ÿ
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。