一、学习总结
本次学习围绕卷积神经网络 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% 以上。同时弹出可视化窗口,展示手写数字原图、真实标签与模型预测结果,识别准确。
六、核心原理简析
- 数据预处理:将图像转为张量并标准化,加快模型收敛;
- CNN 结构:卷积提取图像特征,池化降维减参,全连接层完成多分类;
- 训练机制:使用交叉熵损失 + Adam 优化器,通过反向传播不断更新网络权重;
- 模型推理:关闭梯度计算,提升测试速度,结合 matplotlib 实现结果可视化。
七、总结
本次通过 CNN 完成手写数字识别,完整走完深度学习图像分类全流程。CNN 凭借优秀的特征提取能力,在视觉任务中表现突出。本项目代码简洁、易复现,适合新手入门学习,后续可通过增加网络层数、添加正则化、调整超参数等方式进一步优化模型性能。