文章目录

  • LeNet-5(详解)—— 从原理到 PyTorch 实现(含训练示例)
    • 简介
    • LeNet-5 的核心思想
    • LeNet-5 逐层结构详解
    • 逐层计算举例
      • 📌 输入层
      • 📌 C1 卷积层
      • 📌 S2 池化层
      • 📌 C3 卷积层
      • 📌 S4 池化层
      • 📌 C5 卷积层
      • 📌 F6 全连接层
      • 📌 输出层
    • 关键设计点解析
    • PyTorch 实现 LeNet-5
    • 训练与评估
    • 实验扩展
    • 总结
    • 参考资料


LeNet-5(详解)—— 从原理到 PyTorch 实现(含训练示例)

简介

LeNet-5 是 Yann LeCun 在 1998 年提出的一种经典卷积神经网络(CNN),最早用于 手写数字识别(MNIST 数据集)。它是深度学习的奠基网络之一,对后续的 AlexNet、VGG、ResNet 等深度网络有重要启发。
论文:Gradient-based learning appl ied to document re cognition
中文可参考:论文
👉 本文目标:通过 逐层解析 LeNet-5 的思想,并在 PyTorch 中实现与训练,让你从 理论 → 实践 → 实验扩展 全面理解这一经典网络。


LeNet-5 的核心思想

  1. 局部感受野(Local Receptive Field)
    每个神经元只连接输入图像的一小块区域,减少计算量并提取局部特征。

  2. 权值共享(Weight Sharing)
    卷积层使用相同的卷积核(Filter)在整张图像上滑动,极大减少参数数量。

  3. 下采样(Subsampling / Pooling)
    使用平均池化降低特征图尺寸,保留关键信息,减少过拟合。


LeNet-5 逐层结构详解

输入为 32×32 灰度图像(MNIST 原本是 28×28,论文中补 0 填充到 32×32)。一共七层,3个卷积层,2个池化层,2个全连接层
在这里插入图片描述

层级类型输入尺寸核心操作输出尺寸参数量
输入层Image32×32×1-32×32×10
C1卷积层32×32×16 个 5×5 卷积核,stride=128×28×6156
S2池化层28×28×66 个 2×2 平均池化,stride=214×14×612
C3卷积层14×14×616 个 5×5 卷积核(部分连接)10×10×16≈1516
S4池化层10×10×1616 个 2×2 平均池化,stride=25×5×1632
C5卷积层5×5×16120 个 5×5 卷积核(全连接方式)1×1×12048120
F6全连接120全连接到 84 个神经元8410164
输出层Softmax84全连接到 10 类10850

逐层计算举例

卷积与池化的计算公式:

  • 卷积层公式

    O=W−F+2PS+1O = \frac{W - F + 2P}{S} + 1 O=SWF+2P+1

    其中:

    • WWW:输入特征图大小
    • FFF:卷积核大小
    • PPP:Padding
    • SSS:步长 (stride)
    • OOO:输出特征图大小
  • 池化层公式:同卷积公式,只是用池化窗口替换卷积核。


📌 输入层

输入:32×32×1(单通道灰度图)


📌 C1 卷积层

  • 输入:32×32×1

  • 卷积核:6 个 5×5,stride=1,padding=0

  • 计算:

    O=32−5+01+1=28O = \frac{32 - 5 + 0}{1} + 1 = 28 O=1325+0+1=28

  • 输出:28×28×6


📌 S2 池化层

  • 输入:28×28×6

  • 池化窗口:2×2,stride=2

  • 计算:

    O=28−22+1=14O = \frac{28 - 2}{2} + 1 = 14 O=2282+1=14

  • 输出:14×14×6


📌 C3 卷积层

  • 输入:14×14×6

  • 卷积核:16 个 5×5,stride=1,padding=0(部分连接)

  • 计算:

    O=14−51+1=10O = \frac{14 - 5}{1} + 1 = 10 O=1145+1=10

  • 输出:10×10×16


📌 S4 池化层

  • 输入:10×10×16

  • 池化窗口:2×2,stride=2

  • 计算:

    O=10−22+1=5O = \frac{10 - 2}{2} + 1 = 5 O=2102+1=5

  • 输出:5×5×16


📌 C5 卷积层

  • 输入:5×5×16

  • 卷积核:120 个 5×5(全连接形式)

  • 计算:

    O=5−51+1=1O = \frac{5 - 5}{1} + 1 = 1 O=155+1=1

  • 输出:1×1×120


📌 F6 全连接层

  • 输入:120
  • 输出:84

📌 输出层

  • 输入:84
  • 输出:10(分类类别:0~9)

关键设计点解析

  1. C3 的部分连接

    • 并非所有 16 个卷积核都连接前一层的 6 个通道,而是选择部分组合,减少参数。
    • 这是因为早期计算能力有限,同时也有助于增加特征多样性。
  2. S 层的带学习系数平均池化

    • 与现代的 MaxPool 不同,LeNet-5 的平均池化包含一个可训练的缩放系数 + 偏置。

    • 即:

      y=a⋅avg(x)+by = a \cdot \text{avg}(x) + b y=aavg(x)+b

  3. 激活函数 tanh

    • LeNet-5 使用 tanh / sigmoid 激活,而不是现代 CNN 常用的 ReLU
    • 这导致梯度可能更容易消失,但在小规模网络上问题不大。

PyTorch 实现 LeNet-5

import torch
import torch.nn as nn
import torch.nn.functional as Fclass LeNet5(nn.Module):def __init__(self, num_classes=10):super(LeNet5, self).__init__()# C1: 卷积层 1self.conv1 = nn.Conv2d(1, 6, kernel_size=5, stride=1, padding=0)# S2: 平均池化self.pool1 = nn.AvgPool2d(kernel_size=2, stride=2)# C3: 卷积层 2self.conv2 = nn.Conv2d(6, 16, kernel_size=5, stride=1, padding=0)# S4: 平均池化self.pool2 = nn.AvgPool2d(kernel_size=2, stride=2)# C5: 卷积层 3self.conv3 = nn.Conv2d(16, 120, kernel_size=5, stride=1, padding=0)# F6: 全连接层self.fc1 = nn.Linear(120, 84)# 输出层self.fc2 = nn.Linear(84, num_classes)def forward(self, x):x = torch.tanh(self.conv1(x))   # C1x = self.pool1(x)               # S2x = torch.tanh(self.conv2(x))   # C3x = self.pool2(x)               # S4x = torch.tanh(self.conv3(x))   # C5x = x.view(x.size(0), -1)       # 展平x = torch.tanh(self.fc1(x))     # F6x = self.fc2(x)                 # 输出层return x

训练与评估

import torch.optim as optim
from torchvision import datasets, transforms# 数据准备(MNIST)
transform = transforms.Compose([transforms.Pad(2),   # MNIST 28x28 → 32x32transforms.ToTensor()
])
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 = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False)# 模型、优化器、损失函数
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = LeNet5().to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()# 训练
for epoch in range(5):model.train()for data, target in train_loader:data, target = data.to(device), target.to(device)optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")# 测试
model.eval()
correct = 0
with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)pred = output.argmax(dim=1)correct += pred.eq(target).sum().item()print("Test Accuracy: {:.2f}%".format(100. * correct / len(test_dataset)))

实验扩展

我们可以对比 原版 LeNet-5 与现代改进版

模型版本激活函数池化方式归一化数据增强测试准确率
原版 LeNet-5tanhAvgPool~99.0%
改进版ReLUMaxPoolBatchNorm随机旋转、平移~99.3%

👉 结论:现代改进提升了训练收敛速度与泛化性能。


总结

  • LeNet-5 开创了 卷积、池化、全连接 的网络结构范式。
  • 逐层计算公式 能帮助我们直观理解输入输出维度的变化。
  • 其思想(局部感受野、权值共享、下采样)成为后续 CNN 的基石。
  • PyTorch 实现与 MNIST 训练能直观感受这一网络的简洁与高效。
  • 现代改进(ReLU、MaxPool、BN、数据增强)进一步提升效果。

参考资料

  1. Yann LeCun - LeNet-5 原始论文 (1998)
  2. PyTorch 官方文档:https://pytorch.org/docs/stable/nn.html
  3. 深度学习经典模型讲解 - CSDN 博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921797.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921797.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921797.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器视觉的手机柔性屏贴合应用

在智能手机制造领域,柔性屏逐渐成为智能手机的主流选择,柔性屏因其轻便、易于弯曲的特性,已成为现代电子设备的重要组成部分,但同时也带来了前所未有的制造挑战。柔性屏与传统刚性玻璃屏有本质区别,它容易形变&#xf…

贪心算法应用:数字孪生同步问题详解

Java中的贪心算法应用:数字孪生同步问题详解 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。下面我将全面详细地讲解贪心算法在数字孪生同步问题中的应用。…

UOS20系统安装与 SSH/XRDP 远程访问功能配置指南

UOS20系统安装与 SSH/XRDP 远程访问功能配置指南 一、UOS 20 系统安装​ ​1. 下载系统镜像​ 访问统信官网下载 UOS 20 专业版镜像(推荐适配当前硬件的版本): https://www.chinauos.com/resource/download-professional 2. 系统安装与硬件配…

【Python】S1 基础篇 P5 字典模块指南

目录字典的本质与底层实现基础语法结构使用字典访问字典中的值添加键值对修改字典中的值删除键值对使用 get() 来访问值遍历字典遍历所有键值对遍历字典中的所有键遍历字典中的所有值嵌套字典列表在字典中存储列表字典(Dictionary)是Python中灵活且强大的…

计算机视觉之多模板匹配

简介 计算机视觉第一课opencv(四)保姆级教学 之前说过模糊匹配只是对于单个目标进行匹配,今天我们就来学习一下如何对多个目标进行匹配 一、多目标匹配 对于这个图片我们要匹配下面那个箭头,我们可以发现图中是有两个位置相同的…

封装日期选择器组件,带有上周,下周按钮

ui图组件代码如下&#xff1a; <template><div><el-date-pickerv-model"dateRange"type"daterange"align"right"size"mini":editable"false"unlink-panelsrange-separator"至"start-placeholder&q…

基于SpringBoot+MYSQL开发的AI智能大数据医疗诊断平台

角色&#xff1a; 管理员、医生、居民 技术&#xff1a; SpringBoot、MyBatis、MySQL、Shiro、Beetl、Swagger、jQuery、Bootstrap 核心功能&#xff1a; 这是一个基于SpringBoot的社区医疗管理平台&#xff0c;旨在为管理员提供用户、角色、部门、菜单、日志等系统管理功能&am…

【MFC 小白日记】对话框编辑器里“原型图像”到底要不要勾?3 分钟看懂!

摘要&#xff1a;本文解析了MFC中Picture Control的"原型图像(Prototype Image)"属性的真实作用。该属性仅在设计时提供可视化的占位图预览&#xff0c;方便UI布局&#xff0c;运行时不会影响程序表现。文章通过对比实验验证&#xff0c;勾选后会在对话框编辑器中显示…

微信开放平台第三方平台,可以管理多个微信小程序

大家好&#xff0c;我是小悟。 这个系统可以帮助服务商更好地管理多个商家小程序&#xff0c;无需管理多个商家小程序的账号密码或者appId和secret&#xff0c;大大提升效率。 不需要频繁登录小程序后台就能完成上传代码、认证、备案、提交代码审核、发布小程序等操作。 这里录…

Java全栈学习笔记32

-- drop table t_stu;-- unique 唯一约束的列允许为null-- 如果在之后的操作中。需要某列必须为key&#xff0c;才能做一些操作的情况下。也可以使用唯一约束代替主键约束-- create table t_stu(-- studId int,-- tel varchar(11) unique,-- sex varchar(1),-- addr va…

linux升级系统,重启出现Minimal BASH-like line editingis supported

文章目录一.问题背景二.解决步骤2.1确认系统分区2.2手动引导2.3 重建grub引导2.4 还原软件包 一.问题背景 闲来无事&#xff0c;把ubuntu25.04通过sudo do-release-upgrade命令升级到了ubuntu25.10.在升级的过程会出现以下问题 1.自动替换flatpak程序为snap2.请求是否清除旧依赖…

type(类型别名)和 interface的区别和最佳实践

核心结论在大多数情况下&#xff0c;它们可以互换使用&#xff0c;都能描述对象的结构。它们的区别更多在于设计和扩展能力上。主要区别总结表特性interface (接口)type (类型别名)扩展方式使用 extends 继承interface A extends B {}使用 & 交叉类型type A B & C合并…

vscode中使用git、githup的基操

一、git提交 配置账户密码 查看用户信息 git config --global user.name # 查看用户名 git config --global user.email # 查看邮箱账户配置 # 设置全局用户名和邮箱 git config --global user.name "你的用户名" git config --global user.email "你的邮箱&q…

jsBridge接入流程

import deviceInfo from ./deviceInfo import { setRefreshToken } from ./token// 设备判断 const u navigator.userAgent export const isAndroid u.indexOf(Android) > -1 || u.indexOf(Adr) > -1 export const isIOS !!u.match(/\(i[^;];( U;)? CPU.Mac OS X/)…

【C++】19. 封装红⿊树实现set和map

文章目录一、源码及框架分析二、模拟实现map和set1、insert的实现2、iterator的实现3、map⽀持[ ]4、模拟实现的完整源代码1&#xff09;RBTree.h2&#xff09;Myset.h3&#xff09;Mymap.h4&#xff09;Test.cpp一、源码及框架分析 SGI-STL30版本源代码&#xff0c;map和set的…

面试不会问题

1. 什么是表锁&#xff1f;什么是行锁&#xff1f;什么情况下会使用表锁&#xff1f;InnoDB引擎通过“索引”实现行锁&#xff08;锁定满足条件的行&#xff09;&#xff0c;但如果操作无法通过索引定位行&#xff0c;会导致行锁失效&#xff0c;进而升级为表锁。常见的表现为&…

达梦数据库-用户,权限,角色

达梦数据库-用户,权限,角色 在达梦数据库(DM8)中,用户(User)、权限(Privilege)和角色(Role) 是数据库安全体系的核心组成部分,用于控制谁可以访问数据库、能访问哪些对象以及能执行哪些操作。 下面为你提供一份全面、详细、结构化的说明,帮助你深入理解达梦数据…

uniapp原生插件 TCP Socket 使用文档

uniapp原生插件 TCP Socket 使用文档 试了插件市场几个TCP Socket插件都不能实现监听服务器主动断开&#xff0c;于是闲来无事就开发了一款&#xff0c;本插件是一个基于 Netty 实现的 TCP 通信模块&#xff0c;用于在 UniApp 插件中提供 TCP 连接、数据发送和连接管理功能。以…

VM中CentOS 7密码重置

重启虚拟机点击e进入内核处理向下划找到UTF-8在后面输入rd.breakctrl X进入单用户模式mount -o remount,rw/sysroot进行挂盘 chroot /sysroot访问系统&#xff0c;并使用passwd修改root密码 出现乱码 输入LANGen touch /.autorelabel 保存配置 exit exit退出等待系统重新打开&…

车规级MOS管AEC-Q101认证的关键参数解读与失效模式-深圳阿赛姆

摘要本文拆解AEC-Q101认证的7大关键测试项&#xff08;UIS/温度循环/THB等&#xff09;&#xff0c;结合M120N06JC等型号实测数据&#xff0c;解析雪崩失效/栅氧击穿/绑定线脱落等故障机理&#xff0c;附选型核查表一、AEC-Q101认证核心测试项与参数解读1.1 非钳位电感开关测试…