当前位置: 首页 > article >正文

用PyTorch复现LeNet:从MNIST手写数字识别到理解卷积神经网络(保姆级代码解析)

用PyTorch实战LeNet从零构建经典CNN模型并理解其设计哲学在深度学习的世界里LeNet就像是一本启蒙读物——它简单到足以让初学者理解却又深刻到能揭示卷积神经网络(CNN)的核心思想。1998年由Yann LeCun提出的这个架构不仅成功应用于支票手写数字识别更为现代深度学习奠定了基础框架。今天我们不再满足于跑通代码而是要亲手用PyTorch重建这个里程碑同时思考为什么30年前的架构设计至今仍有教学价值它的哪些部分已被时代淘汰哪些依然闪耀智慧光芒1. 环境准备与数据加载工欲善其事必先利其器。在开始构建LeNet之前我们需要配置好开发环境。推荐使用Python 3.8和PyTorch 1.12版本这些组合既能保证功能完整又避免最新版本可能存在的兼容性问题。安装PyTorch只需一行命令pip install torch torchvision matplotlibMNIST数据集作为深度学习界的Hello World包含60,000张28x28像素的手写数字训练图片和10,000张测试图片。PyTorch的torchvision已经内置了这个数据集让我们可以轻松加载import torch from torchvision import datasets, transforms # 定义数据预处理管道 transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) # MNIST的均值和标准差 ]) # 加载数据集 train_set datasets.MNIST(root./data, trainTrue, downloadTrue, transformtransform) test_set datasets.MNIST(root./data, trainFalse, transformtransform) # 创建数据加载器 train_loader torch.utils.data.DataLoader(train_set, batch_size64, shuffleTrue) test_loader torch.utils.data.DataLoader(test_set, batch_size1000, shuffleFalse)这里有几个关键细节值得注意Normalize参数0.1307和0.3081是MNIST数据集预先计算好的全局像素平均值和标准差Batch Size选择训练时使用64的小批量平衡内存占用和梯度稳定性测试时使用1000的大批量提升评估效率Shuffle策略训练数据需要打乱以避免模型学习到顺序特征而测试数据无需打乱提示在Jupyter Notebook中可以使用matplotlib快速可视化数据集样本import matplotlib.pyplot as plt figure plt.figure(figsize(8, 8)) for i in range(1, 10): img, label train_set[i] figure.add_subplot(3, 3, i) plt.title(label) plt.axis(off) plt.imshow(img.squeeze(), cmapgray) plt.show()2. LeNet架构的现代实现原始LeNet论文中使用的架构与今天PyTorch教科书中的实现略有不同。我们将实现一个现代化的LeNet-5变体保持其核心思想的同时采用了一些当代最佳实践。2.1 网络结构解析LeNet的精妙之处在于它的层次设计让我们逐层拆解import torch.nn as nn import torch.nn.functional as F class ModernLeNet(nn.Module): def __init__(self): super(ModernLeNet, self).__init__() self.conv1 nn.Conv2d(1, 6, 5, padding2) # 保持28x28分辨率 self.conv2 nn.Conv2d(6, 16, 5) self.fc1 nn.Linear(16 * 5 * 5, 120) self.fc2 nn.Linear(120, 84) self.fc3 nn.Linear(84, 10) def forward(self, x): # 第一卷积层128x28 - 628x28 x F.relu(self.conv1(x)) # 平均池化628x28 - 614x14 x F.avg_pool2d(x, 2) # 第二卷积层614x14 - 1610x10 x F.relu(self.conv2(x)) # 平均池化1610x10 - 165x5 x F.avg_pool2d(x, 2) # 展平16x5x5 - 400 x x.view(-1, 16 * 5 * 5) # 全连接层 x F.relu(self.fc1(x)) x F.relu(self.fc2(x)) x self.fc3(x) return x与原始实现相比我们做了几处关键改进激活函数用ReLU替代Sigmoid解决梯度消失问题填充策略第一层卷积添加padding2保持空间分辨率模块化设计将各层分开定义而非使用Sequential便于中间调试平均池化更接近原始论文设计而非现代常用的最大池化2.2 维度变化详解理解CNN的关键在于掌握数据在各层的形状变化。让我们用表格清晰展示这个过程层类型参数配置输入形状输出形状计算说明输入图像-1×28×281×28×28原始MNIST图像Conv16 filters, 5×51×28×286×28×28(28-5)/1 1 24 → 但padding2使输出保持28ReLU1-6×28×286×28×28逐元素非线性激活AvgPool12×2, stride26×28×286×14×1428/2 14Conv216 filters, 5×56×14×1416×10×10(14-5)/1 1 10ReLU2-16×10×1016×10×10逐元素激活AvgPool22×2, stride216×10×1016×5×510/2 5Flatten-16×5×540016×5×5400FC1400→120400120矩阵乘法ReLU3-120120非线性变换FC2120→8412084矩阵乘法ReLU4-8484非线性变换FC384→108410输出10个类别的logits注意原始LeNet使用tanh而非ReLU且第一层卷积后输出是628x28有padding还是624x24无padding存在不同实现。这里我们选择带padding的版本以便教学。3. 训练策略与超参数调优有了模型架构接下来需要设计训练流程。现代深度学习框架让训练代码变得简洁但每个参数选择背后都有其道理。3.1 训练循环实现import torch.optim as optim device torch.device(cuda if torch.cuda.is_available() else cpu) model ModernLeNet().to(device) optimizer optim.SGD(model.parameters(), lr0.01, momentum0.9) criterion nn.CrossEntropyLoss() def train(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() if batch_idx % 100 0: print(fTrain Epoch: {epoch} [{batch_idx * len(data)}/{len(train_loader.dataset)} f({100. * batch_idx / len(train_loader):.0f}%)]\tLoss: {loss.item():.6f}) def test(): 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(dim1, keepdimTrue) correct pred.eq(target.view_as(pred)).sum().item() test_loss / len(test_loader.dataset) print(f\nTest set: Average loss: {test_loss:.4f}, Accuracy: {correct}/{len(test_loader.dataset)} f({100. * correct / len(test_loader.dataset):.2f}%)\n)3.2 关键超参数分析LeNet虽然简单但超参数选择依然影响性能。以下是经过实验验证的推荐配置超参数推荐值可尝试范围影响分析学习率0.010.001-0.1太大导致震荡太小收敛慢批量大小6432-256小批量带来正则化效果动量(Momentum)0.90.85-0.95加速收敛减少震荡权重衰减0.00010-0.001防止过拟合训练周期105-20LeNet在MNIST上收敛快在实际训练中可以观察到前2-3个epoch准确率快速上升约5个epoch后验证准确率趋于稳定使用ReLU时学习率可比Sigmoid时更大而不发散3.3 学习率调度策略为了进一步提升性能可以引入学习率调度scheduler optim.lr_scheduler.StepLR(optimizer, step_size5, gamma0.1) for epoch in range(1, 11): train(epoch) test() scheduler.step()这种配置表示前5个epoch使用初始学习率0.01第6个epoch开始学习率降为0.001第11个epoch降为0.0001如果继续训练4. 模型评估与可视化理解训练完成后我们需要深入分析模型表现和行为特征这比单纯看测试准确率更有教学价值。4.1 性能指标分析在10个epoch训练后典型的结果可能是训练准确率99.2%测试准确率98.7%这表明模型具有很好的泛化能力训练和测试准确率接近仍有提升空间现代CNN在MNIST上可达99.5%混淆矩阵能揭示更多细节from sklearn.metrics import confusion_matrix import seaborn as sns def plot_confusion_matrix(): model.eval() all_preds [] all_targets [] with torch.no_grad(): for data, target in test_loader: data data.to(device) output model(data) pred output.argmax(dim1) all_preds.extend(pred.cpu().numpy()) all_targets.extend(target.cpu().numpy()) cm confusion_matrix(all_targets, all_preds) plt.figure(figsize(10,8)) sns.heatmap(cm, annotTrue, fmtd, cmapBlues) plt.xlabel(Predicted) plt.ylabel(Actual) plt.show() plot_confusion_matrix()常见的错误模式包括4和9相互混淆7和1误判5和6识别错误4.2 特征可视化理解CNN工作的最佳方式是可视化其学到的特征。我们可以绘制第一层卷积核def visualize_filters(): filters model.conv1.weight.data.cpu().numpy() fig, axes plt.subplots(2, 3, figsize(10, 6)) for i, ax in enumerate(axes.flat): ax.imshow(filters[i, 0], cmapgray) ax.set_title(fFilter {i1}) ax.axis(off) plt.tight_layout() plt.show() visualize_filters()典型的LeNet第一层滤波器可能显示不同方向的边缘检测器中心-周围对比度检测斑点检测模式4.3 现代改进方案虽然LeNet具有历史意义但我们知道许多后续改进可以提升其性能Dropout层在全连接层间添加防止过拟合self.fc1 nn.Sequential( nn.Linear(16*5*5, 120), nn.ReLU(), nn.Dropout(0.5) )Batch Normalization加速训练并提升性能self.conv1 nn.Sequential( nn.Conv2d(1, 6, 5, padding2), nn.BatchNorm2d(6), nn.ReLU() )学习率预热前几个epoch逐步提高学习率实验表明仅添加BatchNorm就能将测试准确率提升约0.5个百分点。而完整现代化改造后的LeNet甚至可以达到99.3%的测试准确率——这提醒我们经典架构与现代技巧的结合往往能产生意想不到的效果。

相关文章:

用PyTorch复现LeNet:从MNIST手写数字识别到理解卷积神经网络(保姆级代码解析)

用PyTorch实战LeNet:从零构建经典CNN模型并理解其设计哲学 在深度学习的世界里,LeNet就像是一本启蒙读物——它简单到足以让初学者理解,却又深刻到能揭示卷积神经网络(CNN)的核心思想。1998年由Yann LeCun提出的这个架构,不仅成功…...

OpenBoardView:完全免费的.brd电路板文件查看终极指南

OpenBoardView:完全免费的.brd电路板文件查看终极指南 【免费下载链接】OpenBoardView View .brd files 项目地址: https://gitcode.com/gh_mirrors/op/OpenBoardView 还在为昂贵的电路板设计软件而烦恼吗?想要一款真正免费、跨平台、功能强大的.…...

免费开源AMD Ryzen处理器终极调试指南:SMUDebugTool完整教程

免费开源AMD Ryzen处理器终极调试指南:SMUDebugTool完整教程 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: http…...

CSS如何控制placeholder文字的颜色_使用--placeholder伪元素

Chrome/Firefox中::placeholder颜色不生效,主因是CSS优先级覆盖、浏览器兼容性差异或框架样式重置;需用双冒号语法、兼顾各浏览器前缀、避免内联样式干扰,并通过class而非style动态控制。Chrome/Firefox里::placeholder颜色不生效&#xff1f…...

别再傻傻分不清!EPLAN里连接定义点和电位定义点的核心区别与实战用法

EPLAN电气设计实战:连接定义点与电位定义点的深度解析与应用指南 在EPLAN电气设计软件中,连接定义点(Connection Definition Point)和电位定义点(Potential Definition Point)是两种看似相似却功能迥异的核心元素。许多工程师在使用过程中容易混淆两者&a…...

免费CAD软件LitCAD:3分钟上手的轻量级绘图解决方案终极指南

免费CAD软件LitCAD:3分钟上手的轻量级绘图解决方案终极指南 【免费下载链接】LitCAD A very simple CAD developed by C#. 项目地址: https://gitcode.com/gh_mirrors/li/LitCAD 还在为高昂的CAD软件费用而烦恼吗?或者被复杂的设计工具搞得晕头转…...

别再死记硬背了!用C语言递归搞定二叉树遍历转换(PTA真题7-1保姆级解析)

从手算到代码:二叉树遍历转换的思维跃迁 当你在PTA或LeetCode上遇到"已知后序和中序遍历求先序遍历"这类题目时,是否也曾陷入"先建树再遍历"的思维定式?实际上,这类问题的核心在于发现遍历序列间的隐藏规律&a…...

如何在macOS上高效使用HSTracker:炉石传说智能助手与卡组管理实战指南

如何在macOS上高效使用HSTracker:炉石传说智能助手与卡组管理实战指南 【免费下载链接】HSTracker A deck tracker and deck manager for Hearthstone on macOS 项目地址: https://gitcode.com/gh_mirrors/hs/HSTracker HSTracker是macOS平台上一款专业的炉石…...

告别三极管!用CH340X/C直连搞定CH32/STM32一键下载(附完整电路图与驱动版本避坑)

极简主义嵌入式开发:CH340直连实现CH32/STM32一键下载全攻略 当你在深夜调试一个嵌入式项目,反复插拔USB线、手动切换BOOT跳线、按复位按钮时,是否想过——这些繁琐操作真的有必要吗?传统的一键下载电路通常需要两个三极管构成的逻…...

Docker部署避坑:OpenClaw容器内无法使用代理?网络模式选择建议

“在本地跑得好好的OpenClaw,一放到Docker容器里,代理就不生效了……”“明明docker-compose.yml里配了环境变量,容器里curl也能通,但OpenClaw就是不走代理……”“更离谱的是,容器能ping通外网,但OpenClaw…...

如何免费快速将网页小说转换为EPUB电子书:WebToEpub完整教程

如何免费快速将网页小说转换为EPUB电子书:WebToEpub完整教程 【免费下载链接】WebToEpub A simple Chrome (and Firefox) Extension that converts Web Novels (and other web pages) into an EPUB. 项目地址: https://gitcode.com/gh_mirrors/we/WebToEpub …...

从module变量到intent参数:手把手教你写出更安全、更地道的Fortran子程序

从module变量到intent参数:手把手教你写出更安全、更地道的Fortran子程序 Fortran作为科学计算领域的常青树,其独特的模块化设计和参数传递机制常常让从C/Python转来的开发者感到困惑。本文将带你深入理解module变量的作用域陷阱、参数传递的底层逻辑&am…...

小程序富文本组件mp-html:打破微信原生限制的终极解决方案

小程序富文本组件mp-html:打破微信原生限制的终极解决方案 【免费下载链接】mp-html 小程序富文本组件,支持渲染和编辑 html,支持在微信、QQ、百度、支付宝、头条和 uni-app 平台使用 项目地址: https://gitcode.com/gh_mirrors/mp/mp-html…...

如何在3分钟内为视频添加专业字幕:开源工具终极指南

如何在3分钟内为视频添加专业字幕:开源工具终极指南 【免费下载链接】video-srt-windows 这是一个可以识别视频语音自动生成字幕SRT文件的开源 Windows-GUI 软件工具。 项目地址: https://gitcode.com/gh_mirrors/vi/video-srt-windows 想象一下,…...

IPXWrapper终极指南:5分钟让经典游戏在现代电脑上联机重生

IPXWrapper终极指南:5分钟让经典游戏在现代电脑上联机重生 【免费下载链接】ipxwrapper 项目地址: https://gitcode.com/gh_mirrors/ip/ipxwrapper 你是否怀念那些经典老游戏的局域网对战乐趣?《红色警戒2》、《暗黑破坏神》、《星际争霸》这些承…...

终极指南:如何用Office Custom UI Editor打造专属办公界面

终极指南:如何用Office Custom UI Editor打造专属办公界面 【免费下载链接】office-custom-ui-editor Standalone tool to edit custom UI part of Office open document file format 项目地址: https://gitcode.com/gh_mirrors/of/office-custom-ui-editor …...

考研数学二极限计算:避开等价无穷小使用陷阱的3个实战技巧

考研数学二极限计算:避开等价无穷小使用陷阱的3个实战技巧 极限计算是考研数学二的核心考点,也是考生最容易失分的模块之一。其中,等价无穷小的使用更是"重灾区"——看似简单的替换规则,在实际解题中却暗藏诸多陷阱。本…...

3大技术方案构建无国界AO3镜像:开源社区如何守护全球创作自由

3大技术方案构建无国界AO3镜像:开源社区如何守护全球创作自由 【免费下载链接】AO3-Mirror-Site 项目地址: https://gitcode.com/gh_mirrors/ao/AO3-Mirror-Site 在数字时代,当创作自由遭遇地域限制,技术的力量成为连接全球创作者与读…...

你的数字青春正在消失?GetQzonehistory帮你永久保存QQ空间珍贵记忆

你的数字青春正在消失?GetQzonehistory帮你永久保存QQ空间珍贵记忆 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字时代,QQ空间承载了无数人的青春记忆&am…...

别再写丑UI了!用Qt Quick的TabViewStyle,5分钟打造高颜值选项卡

用Qt Quick的TabViewStyle打造高颜值选项卡:从设计到实现的完整指南 在移动应用和桌面软件中,选项卡(TabView)是最常见的导航组件之一。一个设计精良的选项卡系统不仅能提升用户体验,还能为应用增添专业感。Qt Quick的TabViewStyle提供了强大…...

揭秘低查重AI教材编写秘籍,AI写教材工具助你高效完成专业教材!

在教材编写过程中,如何平衡原创性与合规性是一个新的挑战。许多创作者往往在借鉴优秀教材的内容时,难免担心查重率超出标准;而在尝试独立撰写知识点时,又会顾虑逻辑是否严谨、信息是否准确。更重要的是,当引用他人的研…...

Mac Mouse Fix终极指南:5分钟解锁鼠标隐藏功能,让普通鼠标在macOS上超越触控板

Mac Mouse Fix终极指南:5分钟解锁鼠标隐藏功能,让普通鼠标在macOS上超越触控板 【免费下载链接】mac-mouse-fix Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad! 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fi…...

解锁B站4K高清下载:Python工具完全指南与实战教程

解锁B站4K高清下载:Python工具完全指南与实战教程 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 你是否曾经因为网络波动…...

用STM32F103RCT6驱动4寸ST7796S屏,从接线到显示图片的保姆级教程

STM32F103RCT6驱动4寸ST7796S液晶屏全流程实战指南 第一次拿到STM32开发板和4寸液晶屏时,看着密密麻麻的引脚和陌生的专业术语,确实容易让人望而生畏。但别担心,本文将手把手带你完成从硬件连接到软件调试的全过程。不同于简单的代码复制粘贴…...

抖音下载器完整指南:从单视频到批量下载的一站式解决方案

抖音下载器完整指南:从单视频到批量下载的一站式解决方案 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…...

不止于TurtleBot3:在Isaac Sim中为你的自定义机器人模型搭建ROS通信桥梁

超越标准模型:在Isaac Sim中为自定义机器人构建ROS通信的全流程指南 当开发者尝试将实验室中的独特机器人设计接入仿真环境时,往往面临标准教程无法覆盖的挑战。本文将以工业级机器人开发流程为基础,详解如何突破TurtleBot3等预设模型的限制&…...

CUDA 13算子开发生死线:3张决定推理延迟的架构设计图,错过今天将多花200+ GPU小时调优

第一章:CUDA 13算子开发生死线:技术演进与性能临界点 CUDA 13 的发布标志着 GPU 算子开发进入高精度、低延迟与跨代兼容并重的新阶段。相较于 CUDA 12.x,其对 FP8 原生支持、统一内存访问模型重构、以及 Warp Matrix Instructions&#xff08…...

5分钟上手BilibiliDown:跨平台B站视频下载终极指南

5分钟上手BilibiliDown:跨平台B站视频下载终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/B…...

ABAQUS盾构管片:单环多环精细化建模CAE源文件及录屏讲解教程 ‘一环六块,环宽1.5m...

ABAQUS盾构管片精细化建模cae源文件及录屏讲解教程 包含单环和多环两种 一环6块,环宽1.5m,管片厚度350mm 可以进行计算最近在搞盾构隧道数值模拟,发现管片建模真是个体力活。今天就拿ABAQUS实操经验来说说,怎么快速搞定精细化建模…...

告别手动计数!STM32定时器主从模式新玩法:TIM3+TIM4自动发完脉冲就停

STM32定时器主从模式实战:精准脉冲控制的工程艺术 在嵌入式系统开发中,精确控制脉冲数量是许多应用场景的核心需求——从步进电机驱动到LED灯带控制,再到伺服系统定位。传统方案往往依赖CPU持续监控和软件计数,不仅占用宝贵的处理…...