一、学习总结

本次学习围绕卷积神经网络 CNN 与手写数字图像分类展开,以 PyTorch 为开发框架,完成 MNIST 手写数字识别完整项目实践。

系统掌握了图像分类基础流程:数据集加载、数据标准化预处理、卷积神经网络搭建、模型迭代训练、精度评估与结果可视化。理解了卷积层负责提取图像局部纹理与轮廓特征、池化层压缩特征维度、全连接层完成最终分类的核心原理,对比全连接网络,认识到 CNN 在图像处理上的优势。

熟练使用 torchvision 加载公共数据集,通过 DataLoader 实现批量数据读取与打乱训练;学会搭建简易 CNN 网络,合理设置卷积核、通道数、激活函数;掌握模型训练的完整逻辑:前向传播计算损失、反向传播更新参数、利用 GPU 加速运算;同时实现模型测试、准确率统计与单张图片预测可视化,完整落地深度学习项目流程。

实践中熟悉了张量维度变换、模型评估关闭梯度、数据设备迁移等实操细节,通过迭代训练直观看到损失下降、准确率提升,深入理解模型优化原理。深度学习项目流程规范,合理的数据处理与网络设计是模型高性能的核心,本次实践为后续计算机视觉相关学习积累了实操经验。

二、项目介绍

MNIST 是经典手写数字数据集,包含 0~9 共 10 类灰度手写图片。本文使用两层卷积 + 池化的轻量 CNN 模型,基于 PyTorch 完成训练、测试与单图预测,模型识别精度高,适合深度学习入门练习。

三、环境依赖

bash

运行

pip install torch torchvision matplotlib

四、完整代码

python

运行

# 导入必要库
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt

# 1. 数据预处理与加载
transform = transforms.Compose([
    transforms.ToTensor(),  # 转为Tensor并归一化到[0,1]
    transforms.Normalize((0.1307,), (0.3081,))  # 用MNIST数据集的均值和标准差标准化
])

# 加载MNIST数据集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)

# 2. 构建CNN模型
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        # 卷积层
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        # 池化层
        self.pool = nn.MaxPool2d(2, 2)
        # 全连接层
        self.fc1 = nn.Linear(64 * 7 * 7, 128)
        self.fc2 = nn.Linear(128, 10)
        # 激活函数
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))
        x = self.pool(self.relu(self.conv2(x)))
        x = x.view(-1, 64 * 7 * 7)
        x = self.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 初始化模型、损失函数、优化器
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = CNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 3. 模型训练
def train(model, train_loader, criterion, optimizer, device, epochs=5):
    model.train()
    for epoch in range(epochs):
        running_loss = 0.0
        for images, labels in train_loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            loss = criterion(outputs, labels)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            running_loss += loss.item()
        print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}")

train(model, train_loader, criterion, optimizer, device)

# 4. 模型评估
def test(model, test_loader, device):
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print(f"Test Accuracy: {100 * correct / total:.2f}%")

test(model, test_loader, device)

# 5. 单张图片预测演示
def predict_single_image(model, test_dataset, device, index=10):
    model.eval()
    image, label = test_dataset[index]
    image = image.unsqueeze(0).to(device)
    with torch.no_grad():
        output = model(image)
        _, predicted = torch.max(output, 1)
    plt.imshow(image.squeeze().cpu().numpy(), cmap='gray')
    plt.title(f"True Label: {label}, Predicted: {predicted.item()}")
    plt.axis('off')
    plt.show()

predict_single_image(model, test_dataset, device, index=10)

五、运行结果

控制台输出:

plaintext

Epoch 1, Loss: 0.1527
Epoch 2, Loss: 0.0479
Epoch 3, Loss: 0.0316
Epoch 4, Loss: 0.0233
Epoch 5, Loss: 0.0179
Test Accuracy: 99.15%

训练损失持续下降,测试集准确率达到 99% 以上。同时弹出可视化窗口,展示手写数字原图、真实标签与模型预测结果,识别准确。

六、核心原理简析

  1. 数据预处理:将图像转为张量并标准化,加快模型收敛;
  2. CNN 结构:卷积提取图像特征,池化降维减参,全连接层完成多分类;
  3. 训练机制:使用交叉熵损失 + Adam 优化器,通过反向传播不断更新网络权重;
  4. 模型推理:关闭梯度计算,提升测试速度,结合 matplotlib 实现结果可视化。

七、总结

本次通过 CNN 完成手写数字识别,完整走完深度学习图像分类全流程。CNN 凭借优秀的特征提取能力,在视觉任务中表现突出。本项目代码简洁、易复现,适合新手入门学习,后续可通过增加网络层数、添加正则化、调整超参数等方式进一步优化模型性能。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐