文章目录
卷积神经网络(三):LeNet-5(经典卷积神经网络入门)
一、LeNet-5 总览
LeNet-5 是由 Yann LeCun 等人在 1998 年提出的经典卷积神经网络(CNN)结构,专为手写数字识别设计。它是最早实现工业化应用的 CNN 之一,结构简单易懂,不仅是深度学习入门的核心案例,也为后续复杂 CNN(如 AlexNet、ResNet)提供了架构灵感,被誉为 “CNN 的基石”。
二、历史贡献(为何 LeNet-5 重要?)
- 开创 CNN 工业化先河:是最早证明 “卷积神经网络可解决实际问题” 的模型,打破了当时传统机器学习(如 SVM、决策树)在图像识别领域的垄断;
- 验证反向传播的有效性:首次将反向传播算法(Backpropagation) 稳定应用于 CNN 训练,为后续深度学习优化算法奠定基础;
- 确立 CNN 核心架构范式:提出 “卷积→池化→全连接” 的经典流程,后续所有 CNN(包括 AlexNet、VGG)均延续了这一核心逻辑;
- 激发学界兴趣:在深度学习 “寒冬期” 证明了神经网络的潜力,间接推动了 2012 年后深度学习的爆发式发展。
三、LeNet-5 核心网络特点
LeNet-5 的成功源于其简洁且高效的设计,核心特点可总结为 6 点:
- 结构极简:仅含 7 层(3 卷积 + 2 池化 + 2 全连接),无复杂分支,易于理解和实现;
- 反向传播训练:通过反向传播更新所有可训练参数(卷积核权重、全连接层权重等);
- 卷积层 “三段式” 设计:每个卷积模块均包含 “卷积(特征提取)→池化(降维去噪)→非线性激活(引入非线性)”,兼顾特征表达与计算效率;
- 卷积核提取局部特征:利用小尺寸卷积核(5×5)捕捉图像局部特征(如数字的边缘、拐角),符合图像的局部相关性规律;
- 平均池化降维:早期采用 “带参数的平均池化”(权重 + 偏置),现代框架中简化为 “无参数平均池化”,核心作用是:
- 降低特征图尺寸(减少计算量和过拟合风险);
- 提升模型对图像位移的鲁棒性(轻微偏移不影响池化结果);
- 全连接层收尾分类:通过多层感知机(MLP)将卷积提取的 “局部特征” 整合为 “全局特征”,最终输出类别概率。
原始论文的图:

四、LeNet-5 完整架构表(汇总)
| 层序号 | 层类型 | 输入尺寸 | 输出尺寸 | 核心参数(卷积核 / 池化核) | 参数量 | 激活函数 |
|---|---|---|---|---|---|---|
| 1 | 输入层 | 32×32×1 | 32×32×1 | - | 0 | - |
| 2 | 卷积层 1 | 32×32×1 | 28×28×6 | 6 个 5×5 卷积核,步幅 1,无填充 | 156 | tanh |
| 3 | 池化层 1 | 28×28×6 | 14×14×6 | 2×2 池化核,步幅 2,无填充 | 0(现代) | - |
| 4 | 卷积层 2 | 14×14×6 | 10×10×16 | 16 个 5×5 卷积核,步幅 1,无填充 | 2416 | tanh |
| 5 | 池化层 2 | 10×10×16 | 5×5×16 | 2×2 池化核,步幅 2,无填充 | 0(现代) | - |
| 6 | 卷积层 3(FC) | 5×5×16 | 120 维向量 | 120 个 5×5 卷积核(或 Flatten+FC) | 48120 | tanh |
| 7 | 全连接层 1 | 120 维向量 | 84 维向量 | 120→84 全连接 | 10164 | tanh |
| 8 | 输出层 | 84 维向量 | 10 维向量 | 84→10 全连接 | 850 | Softmax |
我这里最后的输出并没有使用softmax进行激活,我直接输出的10个值
五、代码实现
from torch import nn
class LeNet5(nn.Module):
def __init__(self):
super().__init__()
# 卷积层
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
self.conv3 = nn.Conv2d(16, 120, 5)
# 全连接
self.fc1 = nn.Linear(120, 84)
# 输出层全连接
self.fc2 = nn.Linear(84, 10)
# 平均池化
self.avgpool = nn.AvgPool2d(2)
self.tanh = nn.Tanh()
self.flatten = nn.Flatten(start_dim=1)
# x 形状 (N, C=1, 32, 32)
def forward(self, x):
x = self.conv1(x)
# N x 6 x 28 x 28
# 激活
x = self.tanh(x)
# x = nn.functional.tanh(x)
# 池化
x = self.avgpool(x)
# N x 6 x 14 x 14
# 第二层卷积
x = self.conv2(x)
# N x 16 x 10 x 10
#激活
x = self.tanh(x)
# 第二层池化
x = self.avgpool(x)
# N x 16 x 5 x 5
# 第三层卷积
x = self.conv3(x)
# N x 120 x 1 x 1
#激活
x = self.tanh(x)
# 展平
x = self.flatten(x)
# x = torch.flatten(x, start_dim=1)
# N x 120
x = self.fc1(x)
# N x 84
x = self.tanh(x)
y = self.fc2(x)
# N x 10
return y
if __name__ == '__main__':
import torch
x = torch.rand(5, 1, 32, 32)
model = LeNet5()
y = model(x)
print(y.shape)
这一个模型就可以直接替换我们上一个手写数字识别所用的模型,但注意替换的途中需要注意,我们MNIST数据集的图片大小需要Resize一下,因为MNIST数据集都是28x28的图片,而LeNet5模型的图片输入的大小是32x32的。
14万+

被折叠的 条评论
为什么被折叠?



