手写数字识别项目

项目概述

目标

本项目旨在实现一个能够识别手写数字的机器学习模型。这种类型的模型在数字化处理、自动数据录入和图像识别等领域有广泛的应用。本项目使用的是著名的MNIST数据集,该数据集包含了大量的手写数字样本。示例样本如下:

图片[1]-手写数字识别项目-点头深度学习网站

技术栈

  • Python: 编程语言
  • TensorFlow: 开源机器学习库,用于构建和训练模型
  • Keras: TensorFlow的高级API,简化模型构建过程
  • Pytorch: 类似Tensorflow版本的开源深度学习框架
  • Matplotlib: 数据可视化库

结果展示

模型的训练和验证准确率、损失函数的值可视化展示如下。

图片[2]-手写数字识别项目-点头深度学习网站

通常,一个成功训练的模型应该展示出随着训练次数增加,训练和验证准确率逐渐提高,而损失函数值逐渐降低的趋势。

解决过程

数据预处理

  • 加载数据: 使用TensorFlow提供的MNIST数据集。
  • 归一化: 将图像数据的像素值标准化到0到1之间,这有助于模型更快地收敛。
  • 调整数据形状: 为了适应模型的输入需求,将图像数据调整为四维数组。

构建模型

  • 使用了卷积神经网络(CNN),因为它非常适合图像数据。
  • 模型包含几个卷积层池化层,用于提取图像特征。
  • 接着是全连接层,用于分类。

训练模型

  • 使用交叉熵损失函数Adam优化器
  • 模型在训练集上进行训练,同时在测试集上进行验证。

性能评估

  • 使用测试数据集来评估模型的性能。
  • 主要关注指标为准确率

可视化结果

  • 绘制了训练和验证过程中的准确率和损失函数值的变化曲线。
  • 通过这些图表可以直观地了解模型训练的效果和过拟合或欠拟合的情况。

代码

tensorfow版本

import tensorflow as tf
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt
import numpy as np

# 第1步:加载和预处理数据
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0  # 归一化数据

# 选择一些图像进行展示
num_images = 15
sample_images = x_train[:num_images]
sample_labels = y_train[:num_images]

# 绘制图像
plt.figure(figsize=(10, 10))
for i in range(num_images):
    plt.subplot(3, 5, i + 1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(sample_images[i], cmap=plt.cm.binary)
    plt.xlabel('Label: {}'.format(sample_labels[i]))
plt.show()

# 重新塑形数据以适应模型
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)

# 第2步:构建模型
model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')
])

# 第3步:编译模型
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 第4步:训练模型
history = model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))

# 第5步:评估模型
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)

# 第6步:数据可视化
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Accuracy')
plt.plot(history.history['val_accuracy'], label = 'Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0, 1])
plt.legend(loc='lower right')

plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(loc='upper right')

plt.show()

# 输出测试准确率
test_acc

pytorch版本

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import matplotlib.pyplot as plt

# 第1步:加载和预处理数据
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('./data', train=False, transform=transform)

train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False)

# 第2步:定义模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1)
        self.fc1 = nn.Linear(9216, 64)
        self.fc2 = nn.Linear(64, 10)

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2(x), 2))
        x = x.view(-1, 9216)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

model = Net()

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

# 第4步:训练模型
def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(1, 6):
    train(model, device, train_loader, optimizer, epoch)

# 第5步:评估模型
def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += criterion(output, target).item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

test(model, device, test_loader)

结论

通过本项目,我们成功实现了一个基于卷积神经网络的手写数字识别模型。该模型能够准确地识别MNIST数据集中的手写数字,展现出了良好的性能和学习能力。通过结果的可视化,我们可以更好地理解模型训练过程和模型性能。此项目不仅展示了机器学习在图像识别领域的应用,也为未来相关领域的研究和开发奠定了基础。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容