CNN实现手写数字识别(Pytorch)

这篇具有很好参考价值的文章主要介绍了CNN实现手写数字识别(Pytorch)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

CNN结构

CNN(卷积神经网络)主要包括卷积层、池化层和全连接层。输入数据经过多个卷积层和池化层提取图片信息后,最后经过若干个全连接层获得最终的输出。
CNN实现手写数字识别(Pytorch)CNN的实现主要包括以下步骤:

  1. 数据加载与预处理
  2. 模型搭建
  3. 定义损失函数、优化器
  4. 模型训练
  5. 模型测试

以下基于Pytorch框架搭建一个CNN神经网络实现手写数字识别。

CNN实现

此处使用MNIST数据集,包含60000个训练样本和10000个测试样本。分为图片和标签,每张图片是一个 28 × 28 28 \times 28 28×28 的像素矩阵,标签是0~9一共10种数字。每个样本的格式为[data, label]。

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)的样本数

# 对输入的数据进行标准化处理
# transforms.ToTensor() 将图像数据转换为 PyTorch 中的张量(tensor)格式,并将像素值缩放到 0-1 的范围内。
# 这是因为神经网络需要的输入数据必须是张量格式,并且需要进行归一化处理,以提高模型的训练效果。
# transforms.Normalize(mean=[0.5],std=[0.5]) 将图像像素值进行标准化处理,使其均值为 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) 

加载完数据后,可以得到60000个训练样本和10000个测试样本

print(len(train_dataset))
print(len(test_dataset))

CNN实现手写数字识别(Pytorch)

以及469个训练批次和79测试批次

# batch=128
# train_loader=60000/128 = 469 个batch
# test_loader=10000/128=79 个batch
print(len(train_loader))
print(len(test_loader))

CNN实现手写数字识别(Pytorch)

打印前5个手写数字样本看看

for i in range(0,5):
    oneimg,label = train_dataset[i]
    grid = utils.make_grid(oneimg)
    grid = grid.numpy().transpose(1,2,0) 
    std = [0.5]
    mean = [0.5]
    grid = grid * std + mean
    # 可视化图像
    plt.subplot(1, 5, i+1)
    plt.imshow(grid)
    plt.axis('off')

plt.show()

CNN实现手写数字识别(Pytorch)
这里用了 make_grid() 函数将多张图像拼接成一张网格图像,并调整了网格图像的形状,使得它可以直接作为 imshow() 函数的输入。这种方式可以在一张图中同时显示多张图像,比单独显示每张图像更加方便,常用于可视化深度学习中的卷积神经网络(CNN)中的特征图、卷积核等信息。
在 PyTorch 中,默认的图像张量格式是 (channel, height, width),即通道维度在第一个维度。 torchvision.transforms.ToTensor() 函数会将 PIL 图像对象转换为 PyTorch 张量,并将通道维度放在第一个维度。因此,当我们使用 ToTensor() 函数加载图像数据时,得到的 PyTorch 张量的格式就是 (channel, height, width)。代码中的 oneimg.numpy().transpose(1,2,0) 就是将 PyTorch 张量 oneimg 转换为 NumPy 数组,然后通过 transpose 函数将图像数组中的通道维度从第一个维度(channel-first)调整为最后一个维度(channel-last),即将 (channel, height, width) 调整为 (height, width, channel),以便于 Matplotlib 库正确处理通道信息。

2. 模型搭建

我们将使用Pytorch构建一个如下图所示的CNN,包含两个卷积层,和全连接层,并使用Relu作为激活函数。
CNN实现手写数字识别(Pytorch)
接下来看以下不同层的参数。

卷积层: Connv2d

  • in_channels ——输入数据的通道数目
  • out_channels ——卷积产生的通道数目
  • kernel_size ——卷积核的尺寸
  • stride——步长
  • padding——输入数据的边缘填充0的层数

池化层: MaxPool2d

  • kernel_siez ——池化核大小
  • stride——步长
  • padding——输入数据的边缘填充0的层数

全连接层: Linear

  • in_features:输入特征数
  • out_features:输出特征数

代码实现如下:

class CNN(nn.Module):
    # 定义网络结构
    def __init__(self):
        super(CNN, self).__init__()
        # 图片是灰度图片,只有一个通道
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, 
                               kernel_size=5, stride=1, padding=2)
        self.relu1 = nn.ReLU()
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, 
                               kernel_size=5, stride=1, padding=2)
        self.relu2 = nn.ReLU()
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(in_features=7*7*32, out_features=256)
        self.relu3 = nn.ReLU()
        self.fc2 = nn.Linear(in_features=256, out_features=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

定义损失函数和优化函数

import torch.optim as optim

learning_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)

3. 模型训练

model = CNN() # 实例化CNN模型
num_epochs = 10 # 定义迭代次数

# 如果可用的话使用 GPU 进行训练,否则使用 CPU 进行训练。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 将神经网络模型 net 移动到指定的设备上。
model = model.to(device)
total_step = len(train_loader)
for epoch in range(num_epochs):
    for i, (images,labels) in enumerate(train_loader):
        images=images.to(device)
        labels=labels.to(device)
        optimizer.zero_grad() # 清空上一个batch的梯度信息
        # 将输入数据 inputs 喂入神经网络模型 net 中进行前向计算,得到模型的输出结果 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')

CNN实现手写数字识别(Pytorch)

保存模型

# 模型保存
PATH = './mnist_net.pth'
torch.save(model.state_dict(), PATH)

4. 模型测试

# 测试CNN模型
with torch.no_grad(): # 进行评测的时候网络不更新梯度
    correct = 0
    total = 0
    for images, labels in test_loader:
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0
        correct += (predicted == labels).sum().item()
    print('Accuracy of the network on the 10000 test images: {} %'.format(100 * correct / total))

CNN实现手写数字识别(Pytorch)
这里训练的模型准确率达到了98%,非常高,如果还想继续提高模型准确率,可以调整迭代次数、学习率等参数或者修改CNN网络结构实现。

可视化检验一个批次测试数据的准确性

# 将 test_loader 转换为一个可迭代对象 dataiter
dataiter = iter(test_loader)
# 使用 next(dataiter) 获取 test_loader 中的下一个 batch 的图像数据和标签数据
images, labels = next(dataiter)

# print images
test_img = utils.make_grid(images)
test_img = test_img.numpy().transpose(1,2,0)
std = [0.5]
mean =  [0.5]
test_img = test_img*std+0.5
plt.imshow(test_img)
plt.show()
plt.savefig('./mnist_net.png')
print('GroundTruth: ', ' '.join('%d' % labels[j] for j in range(128)))

CNN实现手写数字识别(Pytorch)

参考来源:
使用Pytorch框架的CNN网络实现手写数字(MNIST)识别
PyTorch初探MNIST数据集文章来源地址https://www.toymoban.com/news/detail-438972.html

到了这里,关于CNN实现手写数字识别(Pytorch)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • pytorch集智-5手写数字识别器-卷积神经网络

    简称:CNN,convolutional neural network 应用场景:图像识别与分类(CNN),看图说话(CNN+RNN)等 优越性:和多层感知机相比,cnn可以识别独特的模式,可以自动从数据中提取特征。一般机器学习需要特征工程,cnn可以自动识别,极大代替或取代了特征工程 和多层感知机原理不同

    2024年01月19日
    浏览(43)
  • 真的不能再详细了,2W字保姆级带你一步步用Pytorch搭建卷积神经网络实现MNIST手写数字识别

    目录 一、引言(环境)  二、正文 1. 代码基本情况介绍 2. MNIST数据集介绍         3. 代码输出结果介绍 数据集取样: 训练信息输出: 前三次训练成果以及预测: 八次训练的结果:  4. 代码拆解讲解 基本的参数设定 MNIST数据集下载、保存与加载 神经网络模型 训练前的准

    2023年04月20日
    浏览(38)
  • 用PyTorch实现MNIST手写数字识别(最新,非常详细)

    本文基于 PyTorch 框架,采用 CNN卷积神经网络 实现 MNIST 手写数字识别,仅在 CPU 上运行。 已分别实现使用Linear纯线性层、CNN卷积神经网络、Inception网络、和Residual残差网络四种结构对MNIST数据集进行手写数字识别,并对其识别准确率进行比较分析。(另外三种还未发布) 看完

    2024年02月06日
    浏览(36)
  • 机器学习第一周:用卷积神经网络实现Mnist手写数字识别(付基础知识解释)

    MNIST 数据集是一个手写数字识别数据集,包含了 60000 张训练图像和 10000 张测试图像,每张图像都是 28x28 像素的灰度图像。 在这个代码中,我们首先使用了 numpy 库中的 np.random.seed() 方法来设置随机种子,以确保结果可重复。 然后,我们使用了 Keras 中的 mnist.load_data() 方法来

    2024年02月08日
    浏览(43)
  • 在树莓派上实现numpy的conv2d卷积神经网络做图像分类,加载pytorch的模型参数,推理mnist手写数字识别,并使用多进程加速

    这几天又在玩树莓派,先是搞了个物联网,又在尝试在树莓派上搞一些简单的神经网络,这次搞得是卷积识别mnist手写数字识别 训练代码在电脑上,cpu就能训练,很快的: 然后需要自己在dataset里导出一些图片:我保存在了mnist_pi文件夹下,“_”后面的是标签,主要是在pc端导

    2024年02月07日
    浏览(35)
  • 手写数字识别-基于卷积神经网络

    🌞欢迎来到机器学习的世界  🌈博客主页:卿云阁  💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🌠本阶段属于练气阶段,希望各位仙友顺利完成突破 📆首发时间:🌹2021年6月5日🌹 ✉️希望可以和大家一起完成进阶之路! 🙏作者水平很有限,如果发

    2024年02月10日
    浏览(44)
  • python与深度学习(六):CNN和手写数字识别二

    本篇文章是对上篇文章训练的模型进行测试。首先是将训练好的模型进行重新加载,然后采用opencv对图片进行加载,最后将加载好的图片输送给模型并且显示结果。 在这里导入需要的第三方库如cv2,如果没有,则需要自行下载。 把MNIST数据集进行加载,并且把训练好的模型也

    2024年02月15日
    浏览(36)
  • [Pytorch]手写数字识别——真·手写!

    Github网址:https://github.com/diaoquesang/pytorchTutorials/tree/main 本教程创建于2023/7/31,几乎所有代码都有对应的注释,帮助初学者理解dataset、dataloader、transform的封装,初步体验调参的过程,初步掌握opencv、pandas、os等库的使用,😋纯手撸手写数字识别项目(为减少代码量简化了部分

    2024年02月14日
    浏览(78)
  • 【Pytorch+torchvision】MNIST手写数字识别

    深度学习入门项目,含代码详细解析 在本文中,我们将在 PyTorch 中构建一个简单的卷积神经网络,并使用 MNIST数据集 训练它识别手写数字。 MNIST包含70,000张手写数字图像: 60,000张用于培训,10,000张用于测试。图像是 灰度(即通道数为1) , 28x28像素 ,并且居中的,以减少预

    2024年02月14日
    浏览(40)
  • 【Pytorch】计算机视觉项目——卷积神经网络CNN模型识别图像分类

    在上一篇笔记《【Pytorch】整体工作流程代码详解(新手入门)》中介绍了Pytorch的整体工作流程,本文继续说明如何使用Pytorch搭建卷积神经网络(CNN模型)来给图像分类。 其他相关文章: 深度学习入门笔记:总结了一些神经网络的基础概念。 TensorFlow专栏:《计算机视觉入门

    2024年02月05日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包