PyTorch-Tutorial项目:CNN实现MNIST手写数字识别详解
前言
卷积神经网络(CNN)是深度学习中处理图像数据的经典架构。本文将通过PyTorch框架,详细讲解如何使用CNN实现MNIST手写数字识别任务。这个教程来自一个知名的PyTorch学习项目,我们将深入解析其中的关键技术和实现细节。
环境准备
在开始之前,需要确保已安装以下Python库:
- PyTorch 0.4或更高版本
- torchvision
- matplotlib
- sklearn (用于可视化)
MNIST数据集加载
MNIST是一个包含0-9手写数字的数据集,包含60,000张训练图片和10,000张测试图片,每张图片大小为28×28像素。
train_data = torchvision.datasets.MNIST(
root='./mnist/',
train=True,
transform=torchvision.transforms.ToTensor(), # 转换为Tensor并归一化到[0,1]
download=True,
)
数据加载时使用了ToTensor()
转换,它会:
- 将PIL图像或numpy数组转换为PyTorch张量
- 自动将像素值从[0,255]归一化到[0.0,1.0]范围
- 调整维度顺序为(C×H×W)
数据预处理
我们使用DataLoader
来创建批处理数据,这对于训练大型数据集非常关键:
train_loader = Data.DataLoader(
dataset=train_data,
batch_size=BATCH_SIZE, # 每批50个样本
shuffle=True, # 打乱数据顺序
)
测试数据也做了相应处理:
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)/255.
这里unsqueeze(dim=1)
是为了增加通道维度,将(2000,28,28)变为(2000,1,28,28),符合CNN输入要求。
CNN网络架构设计
本教程实现了一个经典的CNN结构,包含两个卷积层和最后的全连接层:
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(1, 16, 5, 1, 2), # 输入1通道,输出16通道,5x5卷积核
nn.ReLU(),
nn.MaxPool2d(2), # 2x2最大池化
)
self.conv2 = nn.Sequential(
nn.Conv2d(16, 32, 5, 1, 2),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.out = nn.Linear(32*7*7, 10) # 全连接层输出10类
网络结构说明:
- 第一卷积层:1→16通道,保持空间尺寸不变(通过padding=2实现)
- 最大池化:将28×28降采样为14×14
- 第二卷积层:16→32通道
- 再次池化:14×14降采样为7×7
- 全连接层:将32×7×7=1568维特征映射到10维输出(对应0-9数字)
训练过程
训练使用Adam优化器和交叉熵损失函数:
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss()
for epoch in range(EPOCH):
for step, (b_x, b_y) in enumerate(train_loader):
output = cnn(b_x)[0]
loss = loss_func(output, b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
关键点:
zero_grad()
:清除上一批次的梯度backward()
:反向传播计算梯度step()
:更新参数
可视化与评估
教程提供了两种评估方式:
- 准确率计算:
test_output, _ = cnn(test_x)
pred_y = torch.max(test_output, 1)[1].data.numpy()
accuracy = (pred_y == test_y.numpy()).mean()
- T-SNE降维可视化(需要sklearn):
tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)
low_dim_embs = tsne.fit_transform(last_layer.data.numpy()[:500, :])
T-SNE可以将高维特征降至2维,直观展示不同类别在特征空间的分布情况。
结果分析
运行完整代码后,我们可以看到:
- 测试准确率通常在98%左右,说明CNN在MNIST上表现优异
- T-SNE可视化显示不同数字在特征空间形成了明显的簇
- 从测试样本预测结果看,CNN能准确识别大多数手写数字
总结
本教程展示了使用PyTorch实现CNN的完整流程,包括:
- 数据加载与预处理
- CNN网络设计
- 训练过程实现
- 模型评估与可视化
通过这个简单但完整的例子,我们可以掌握PyTorch中CNN的基本使用方法,为更复杂的图像任务打下基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考