二十八、【人工智能】【机器学习】【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

相关推荐
HPC_fac1305206781642 分钟前
以科学计算为切入点:剖析英伟达服务器过热难题
服务器·人工智能·深度学习·机器学习·计算机视觉·数据挖掘·gpu算力
小陈phd3 小时前
OpenCV从入门到精通实战(九)——基于dlib的疲劳监测 ear计算
人工智能·opencv·计算机视觉
Guofu_Liao4 小时前
大语言模型---LoRA简介;LoRA的优势;LoRA训练步骤;总结
人工智能·语言模型·自然语言处理·矩阵·llama
ZHOU_WUYI8 小时前
3.langchain中的prompt模板 (few shot examples in chat models)
人工智能·langchain·prompt
如若1238 小时前
主要用于图像的颜色提取、替换以及区域修改
人工智能·opencv·计算机视觉
老艾的AI世界9 小时前
AI翻唱神器,一键用你喜欢的歌手翻唱他人的曲目(附下载链接)
人工智能·深度学习·神经网络·机器学习·ai·ai翻唱·ai唱歌·ai歌曲
DK221519 小时前
机器学习系列----关联分析
人工智能·机器学习
Robot2519 小时前
Figure 02迎重大升级!!人形机器人独角兽[Figure AI]商业化加速
人工智能·机器人·微信公众平台
FreedomLeo19 小时前
Python数据分析NumPy和pandas(四十、Python 中的建模库statsmodels 和 scikit-learn)
python·机器学习·数据分析·scikit-learn·statsmodels·numpy和pandas
浊酒南街10 小时前
Statsmodels之OLS回归
人工智能·数据挖掘·回归