PyTorch实战:LeNet-5手写数字识别

张开发
2026/6/9 21:24:11 15 分钟阅读
PyTorch实战:LeNet-5手写数字识别
基于 PyTorch 实现经典 LeNet-5 手写数字识别前言LeNet-5 是深度学习入门最经典的卷积神经网络由 Yann LeCun 提出专门用于手写数字识别MNIST 数据集。本文将完整讲解模型结构、核心层参数、代码实现、训练与评估新手也能从零跑通。一、项目背景与开发思路1.1 项目核心目标本项目是深度学习入门级实战项目基于经典卷积神经网络 LeNet-5 实现手写数字0~9自动识别。核心目标复现并理解经典卷积神经网络 LeNet-5 的结构与原理使用 PyTorch 框架完成模型定义、数据集加载、训练、评估与推理全流程实现对 MNIST 手写数字数据集的高精度识别目标准确率 ≥ 98%搭建一套可直接运行、可扩展、可二次开发的深度学习训练 推理框架掌握深度学习项目标准开发流程模型构建 → 数据处理 → 训练 → 评估 → 部署使用1.2 技术栈选型运行环境Python 3.10PyTorch 2.0深度学习核心框架CPU / GPU 通用项目默认 CPU 运行前端 / 可视化无 Web 前端纯算法项目Matplotlib可选图像展示、结果可视化OpenCV本地图片读取与预处理大模型 / 深度学习核心LeNet-5 卷积神经网络本项目核心模型MNIST 手写数字数据集标准 benchmark 数据集开发工具VS Code代码编辑器Pylance代码语法检查Torch、TorchVision、TorchAudioPyTorch 生态工具库1.3 整体开发流程本项目严格遵循工业界深度学习标准开发流程分为四大核心模块模型模块Model定义 LeNet-5 网络结构实现 3 层卷积 2 层全连接的前向传播逻辑封装为独立类支持导入、训练、推理数据模块Data自动下载 MNIST 数据集数据预处理图像 → 张量归一化构建训练集 / 测试集使用 DataLoader 实现批次加载、乱序处理训练模块Train定义损失函数交叉熵损失CrossEntropyLoss定义优化器Adam 自适应优化器实现单轮训练逻辑前向传播 → 损失计算 → 反向传播 → 参数更新模型权重保存评估模块Evaluate关闭梯度计算提升推理速度计算测试集准确率与平均损失输出可视化指标监控模型效果二、项目整体架构简洁版项目根目录 ├─ models/ # 模型定义 │ └─ Lenet5.py # LeNet-5 网络结构 ├─ utils/ # 工具函数 │ └─ datasel.py # 数据集加载 ├─ train.py # 训练 评估主程序 ├─ inference.py # 单张图片推理可选 └─ lenet5.pth # 训练好的模型权重三、LeNet-5 模型详解1. 模型整体结构LeNet-5 一共5 层核心结构3 个卷积层Conv2d提取图像特征2 个全连接层Linear分类决策配合ReLU 激活MaxPool 池化适配 MNIST 数据输入为1×28×28单通道灰度图输出为10 分类0~9。2. 核心层参数解释必懂1卷积层nn.Conv2d作用对图像进行特征提取捕捉边缘、纹理等信息。python运行nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)in_channels输入通道数灰度图 1彩色图 3out_channels输出通道数提取多少种特征kernel_size卷积核大小常用 3×3、5×5stride步长卷积核移动距离padding填充保持图像尺寸不缩小LeNet 中卷积层plaintextconv1: 1→65×5padding2 尺寸不变 conv2: 6→165×5 尺寸缩小 conv3:16→1205×5 压缩为 1×1 特征2全连接层nn.Linear作用将高维特征映射为类别概率完成最终分类。nn.Linear(in_features, out_features)in_features输入特征数量out_features输出特征数量分类数LeNet 中全连接层fc4: 120 → 84 fc5: 84 → 10 输出 0~9 十个数字四、完整实现过程4.1 模型构建LeNet-5import torch import torch.nn as nn class Lenet5(nn.Module): def __init__(self): super(Lenet5, self).__init__() # 第1层卷积 激活 池化 self.conv1 nn.Conv2d(1, 6, 5, 1, 2) self.relu1 nn.ReLU() self.pool1 nn.MaxPool2d(2) # 第2层卷积 激活 池化 self.conv2 nn.Conv2d(6, 16, 5) self.relu2 nn.ReLU() self.pool2 nn.MaxPool2d(2) # 第3层卷积 激活 self.conv3 nn.Conv2d(16, 120, 5) self.relu3 nn.ReLU() # 第4层全连接 self.fc4 nn.Linear(120, 84) self.relu4 nn.ReLU() # 第5层输出层 self.fc5 nn.Linear(84, 10) def forward(self, x): # 前向传播 x self.pool1(self.relu1(self.conv1(x))) x self.pool2(self.relu2(self.conv2(x))) x self.relu3(self.conv3(x)) x x.view(-1, 120) # 展平 x self.relu4(self.fc4(x)) x self.fc5(x) return x4.2 数据加载MNISTfrom torchvision.transforms import Compose, ToTensor from torch.utils.data import DataLoader from torchvision.datasets import MNIST def load_minist(root./mnist, batch_size64): # 数据转换图片 → 张量 transform Compose([ToTensor()]) # 训练集 测试集 ds_train MNIST(root, trainTrue, downloadTrue, transformtransform) ds_valid MNIST(root, trainFalse, downloadTrue, transformtransform) # 构建批次加载器 loader_train DataLoader(ds_train, shuffleTrue, batch_sizebatch_size) loader_valid DataLoader(ds_valid, shuffleFalse, batch_size1000) return loader_train, loader_valid4.3 模型训练def train_one(model, loader, loss_fun, optimizer, devicecpu): model.train() model.to(device) for x, y in loader: optimizer.zero_grad() x, y x.to(device), y.to(device) y_ model(x) loss loss_fun(y_, y) loss.backward() optimizer.step()4.4 模型评估torch.no_grad() def evaluate(model, loader, loss_fun, devicecpu): model.eval() model.to(device) total 0 correct 0 total_loss 0 for x, y in loader: x, y x.to(device), y.to(device) y_ model(x) loss loss_fun(y_, y) total_loss loss.item() _, pred torch.max(y_, dim1) correct (pred y).sum().item() total len(x) acc correct / total * 100 print(f测试损失{total_loss:.6f}准确率{acc:.2f}%)4.5 主训练流程def train(epochs5, lr0.001): model Lenet5() loader_train, loader_valid load_minist() loss_fun nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lrlr) for epoch in range(epochs): print(f 第 {epoch1} 轮 ) train_one(model, loader_train, loss_fun, optimizer) evaluate(model, loader_valid, loss_fun) torch.save(model.state_dict(), lenet5.pth) if __name__ __main__: train(epochs5)五、运行结果训练 5 轮左右测试集准确率可达 98%~99%。输出示例 第 5 轮 测试损失8.2645准确率98.74%六、总结LeNet-53 卷积 2 全连接手写数字识别经典模型Conv2d提取图像特征控制通道与尺寸Linear分类输出映射为 10 个数字类别训练流程数据加载 → 前向传播 → 计算损失 → 反向更新 → 评估效果MNIST 上轻松达到 98% 准确率

更多文章