二十八、【人工智能】【机器学习】【PyTorch】- 手写体识别

目录

引言

PyTorch简介

深度学习与手写体识别

实现手写体识别的PyTorch模型

数据预处理

构建模型

训练模型

评估模型

最新进展

代码实现

[步骤1: 导入必要的库](#步骤1: 导入必要的库)

[步骤2: 准备数据集](#步骤2: 准备数据集)

[步骤3: 定义CNN模型](#步骤3: 定义CNN模型)

[步骤4: 定义损失函数和优化器](#步骤4: 定义损失函数和优化器)

[步骤5: 训练模型](#步骤5: 训练模型)

[步骤6: 测试模型](#步骤6: 测试模型)

完整代码

结论


引言

在过去的几十年里,手写体识别一直是计算机视觉和模式识别领域的重要课题。随着深度学习技术的兴起,特别是卷积神经网络(Convolutional Neural Networks, CNNs)的发展,我们已经能够以前所未有的精度和效率识别手写字符。本文将深入探讨如何使用PyTorch这一强大的深度学习框架,实现手写体识别,并介绍一些最新的技术进步。

PyTorch简介

PyTorch是由Facebook的人工智能研究实验室开发的一个开源机器学习库。它提供了动态计算图,使得构建和调整复杂的深度学习模型变得直观而高效。PyTorch的灵活性和易用性使其成为学术界和工业界广泛使用的工具之一。

深度学习与手写体识别

手写体识别的传统方法依赖于特征工程和基于规则的系统,但这些方法往往无法处理手写体的多样性和复杂性。相比之下,深度学习模型,尤其是CNNs,能够自动学习和提取图像中的特征,无需显式的人工特征设计。这使得它们在手写体识别任务上取得了显著的成功。

实现手写体识别的PyTorch模型

我们将使用经典的MNIST数据集作为案例研究,这是一个包含60,000个训练样本和10,000个测试样本的手写数字数据集。下面是如何使用PyTorch构建一个基本的CNN模型的步骤:

数据预处理

  • 加载MNIST数据集 :使用torchvision.datasets.MNIST加载并分割训练和测试数据。
  • 数据转换 :使用transforms对图像进行归一化和张量化处理。

构建模型

  • 定义CNN架构:包括卷积层、池化层和全连接层。
  • 初始化模型:创建模型实例并选择合适的设备(CPU或GPU)。

训练模型

  • 设置训练参数:如学习率、优化器、损失函数。
  • 训练循环:遍历数据集,前向传播,计算损失,反向传播,更新权重。

评估模型

  • 测试模型:在测试集上评估模型的性能。
  • 分析结果:查看混淆矩阵,评估分类准确率。

最新进展

近年来,手写体识别领域的一些最新进展包括:

  • 注意力机制:引入注意力机制可以增强模型在局部区域的聚焦能力,提高识别准确性。
  • 数据增强:通过旋转、缩放和剪切等操作增加训练集多样性,有助于提高模型的泛化能力。
  • 迁移学习:利用在大型数据集上预训练的模型,通过微调适应手写体识别任务,可以节省时间和计算资源。

代码实现

pytorch实现手写字体的识别。本算法最终识别率在97.76左右。

步骤1: 导入必要的库

python 复制代码
import pandas as pd
import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import torch.optim as optim

步骤2: 准备数据集

python 复制代码
# 读取文件
filename = r"F:\BaiduNetdiskDownload\mnist_train.csv"
# 使用 loadtxt 读取文件,忽略第一列(标签),并将剩余列转换为整数
train_features = (np.loadtxt(filename, delimiter=',', skiprows=0, usecols=range(1, 785), dtype=int) / 255.0)
train_labels = np.loadtxt(filename, delimiter=',', usecols=(0,), dtype=int)

# 加载训练和测试数据
# train_features, train_labels = load_data_from_excel(r'F:\BaiduNetdiskDownload\mnist_train.csv')
# test_features, test_labels = load_data_from_excel(r'F:\BaiduNetdiskDownload\mnist_test.csv')
# 读取文件
fileTestname = r"F:\BaiduNetdiskDownload\mnist_test.csv"
# 使用 loadtxt 读取文件,忽略第一列(标签),并将剩余列转换为整数
test_features = (np.loadtxt(fileTestname, delimiter=',', skiprows=0, usecols=range(1, 785), dtype=int) / 255.0)
test_labels = np.loadtxt(fileTestname, delimiter=',', usecols=(0,), dtype=int)
# 转换为PyTorch的Tensor
train_features = torch.from_numpy(train_features).float()
train_labels = torch.from_numpy(train_labels).long()
test_features = torch.from_numpy(test_features).float()
test_labels = torch.from_numpy(test_labels).long()


# 自定义Dataset类
class ExcelDataset(Dataset):
    def __init__(self, features, labels):
        self.features = features
        self.labels = labels

    def __len__(self):
        return len(self.features)

    def __getitem__(self, idx):
        return self.features[idx], self.labels[idx]


# 创建数据集实例
train_dataset = ExcelDataset(train_features, train_labels)
test_dataset = ExcelDataset(test_features, test_labels)

# 创建DataLoader
train_loader = DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)

步骤3: 定义CNN模型

python 复制代码
# 定义模型
class MnistModel(nn.Module):
    def __init__(self):
        super(MnistModel, self).__init__()
        self.fc = nn.Sequential(
            nn.Linear(784, HIDDEN_SIZE_1),
            nn.ReLU(),
            nn.Linear(HIDDEN_SIZE_1, HIDDEN_SIZE_2),
            nn.ReLU(),
            nn.Linear(HIDDEN_SIZE_2, 32),
            nn.ReLU(),
            nn.Linear(32, 10),

        )

    def forward(self, x):
        x = x.view(x.size(0), -1)
        return self.fc(x)

步骤4: 定义损失函数和优化器

python 复制代码
model = MnistModel()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

步骤5: 训练模型

python 复制代码
# 训练模型
for epoch in range(NUM_EPOCHS):
    for i, (images, labels) in enumerate(train_loader):
        # 清零优化器中累积的梯度
        optimizer.zero_grad()
        # 构建训练模型
        outputs = model(images)
        # 计算损失函数
        loss = criterion(outputs, labels)
        # 启动反向传播过程
        loss.backward()
        # 使用优化算法来更新模型的参数
        optimizer.step()

        if (i + 1) % 100 == 0:
            print(f'Epoch [{epoch + 1}/{NUM_EPOCHS}], Step [{i + 1}/{len(train_loader)}], Loss: {loss.item():.4f}')

# 保存模型
torch.save(model.state_dict(), MODEL_PATH)

步骤6: 测试模型

python 复制代码
# 加载模型进行测试
model.load_state_dict(torch.load(MODEL_PATH))
model.eval()
#
# # 测试模型
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('Test Accuracy: {} %'.format(100 * correct / total))

完整代码

python 复制代码
import pandas as pd
import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import torch.optim as optim

# 定义超参数
BATCH_SIZE = 64
NUM_EPOCHS = 30
LEARNING_RATE = 0.0009
HIDDEN_SIZE_1 = 128
HIDDEN_SIZE_2 = 64
MODEL_PATH = r'F:\ai\moudle.ckpt'

# 读取文件
filename = r"F:\BaiduNetdiskDownload\mnist_train.csv"
# 使用 loadtxt 读取文件,忽略第一列(标签),并将剩余列转换为整数
train_features = (np.loadtxt(filename, delimiter=',', skiprows=0, usecols=range(1, 785), dtype=int) / 255.0)
train_labels = np.loadtxt(filename, delimiter=',', usecols=(0,), dtype=int)

# 加载训练和测试数据
# train_features, train_labels = load_data_from_excel(r'F:\BaiduNetdiskDownload\mnist_train.csv')
# test_features, test_labels = load_data_from_excel(r'F:\BaiduNetdiskDownload\mnist_test.csv')
# 读取文件
fileTestname = r"F:\BaiduNetdiskDownload\mnist_test.csv"
# 使用 loadtxt 读取文件,忽略第一列(标签),并将剩余列转换为整数
test_features = (np.loadtxt(fileTestname, delimiter=',', skiprows=0, usecols=range(1, 785), dtype=int) / 255.0)
test_labels = np.loadtxt(fileTestname, delimiter=',', usecols=(0,), dtype=int)
# 转换为PyTorch的Tensor
train_features = torch.from_numpy(train_features).float()
train_labels = torch.from_numpy(train_labels).long()
test_features = torch.from_numpy(test_features).float()
test_labels = torch.from_numpy(test_labels).long()


# 自定义Dataset类
class ExcelDataset(Dataset):
    def __init__(self, features, labels):
        self.features = features
        self.labels = labels

    def __len__(self):
        return len(self.features)

    def __getitem__(self, idx):
        return self.features[idx], self.labels[idx]


# 创建数据集实例
train_dataset = ExcelDataset(train_features, train_labels)
test_dataset = ExcelDataset(test_features, test_labels)

# 创建DataLoader
train_loader = DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)


# 定义模型
class MnistModel(nn.Module):
    def __init__(self):
        super(MnistModel, self).__init__()
        self.fc = nn.Sequential(
            nn.Linear(784, HIDDEN_SIZE_1),
            nn.ReLU(),
            nn.Linear(HIDDEN_SIZE_1, HIDDEN_SIZE_2),
            nn.ReLU(),
            nn.Linear(HIDDEN_SIZE_2, 32),
            nn.ReLU(),
            nn.Linear(32, 10),

        )

    def forward(self, x):
        x = x.view(x.size(0), -1)
        return self.fc(x)


model = MnistModel()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

# 训练模型
for epoch in range(NUM_EPOCHS):
    for i, (images, labels) in enumerate(train_loader):
        # 清零优化器中累积的梯度
        optimizer.zero_grad()
        # 构建训练模型
        outputs = model(images)
        # 计算损失函数
        loss = criterion(outputs, labels)
        # 启动反向传播过程
        loss.backward()
        # 使用优化算法来更新模型的参数
        optimizer.step()

        if (i + 1) % 100 == 0:
            print(f'Epoch [{epoch + 1}/{NUM_EPOCHS}], Step [{i + 1}/{len(train_loader)}], Loss: {loss.item():.4f}')

# 保存模型
torch.save(model.state_dict(), MODEL_PATH)

# 加载模型进行测试
# model.load_state_dict(torch.load(MODEL_PATH))
# model.eval()
#
# # 测试模型
# 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('Test Accuracy: {} %'.format(100 * correct / total))

结论

手写体识别是深度学习技术应用的一个生动例子,展示了AI在理解和解析人类创造的内容方面的能力。随着算法和硬件的进步,我们可以期待未来在手写体识别和其他相关领域看到更多令人兴奋的成果。

需要训练集的同学可以访问以下链接获取:

链接:https://pan.baidu.com/s/1afPQFahKy9Ei8IjNk8o8pw?pwd=so5x

提取码:so5x

相关推荐
迅易科技1 小时前
借助腾讯云质检平台的新范式,做工业制造企业质检的“AI慧眼”
人工智能·视觉检测·制造
古希腊掌管学习的神2 小时前
[机器学习]XGBoost(3)——确定树的结构
人工智能·机器学习
ZHOU_WUYI2 小时前
4.metagpt中的软件公司智能体 (ProjectManager 角色)
人工智能·metagpt
靴子学长3 小时前
基于字节大模型的论文翻译(含免费源码)
人工智能·深度学习·nlp
AI_NEW_COME4 小时前
知识库管理系统可扩展性深度测评
人工智能
海棠AI实验室4 小时前
AI的进阶之路:从机器学习到深度学习的演变(一)
人工智能·深度学习·机器学习
hunteritself4 小时前
AI Weekly『12月16-22日』:OpenAI公布o3,谷歌发布首个推理模型,GitHub Copilot免费版上线!
人工智能·gpt·chatgpt·github·openai·copilot
IT古董5 小时前
【机器学习】机器学习的基本分类-强化学习-策略梯度(Policy Gradient,PG)
人工智能·机器学习·分类
centurysee5 小时前
【最佳实践】Anthropic:Agentic系统实践案例
人工智能
mahuifa5 小时前
混合开发环境---使用编程AI辅助开发Qt
人工智能·vscode·qt·qtcreator·编程ai