📘 动手学深度学习 - 卷积神经网络 - 7.6 卷积神经网络(LeNet)
我们现在拥有组装功能齐全所需的所有要素,来构建卷积神经网络(CNN)。在之前的章节中,我们使用 softmax 回归和多层感知机(MLP)处理图像分类问题,它们都将二维图像展平为一维向量。但现在,我们可以借助卷积操作,保留图像的空间结构,并显著减少参数数量。
在本节中,我们将介绍 LeNet,它是最早发布的 CNN 架构之一,由 Yann LeCun 于 1990 年代在 AT&T 贝尔实验室提出,用于识别手写数字图像。该模型是第一个成功使用反向传播训练的 CNN 系统。LeNet 在当时取得了与支持向量机(SVM)相当的效果,且在 ATM 机等系统中获得实际部署,直到今天部分设备仍在使用。
7.6.1 LeNet
LeNet-5 架构分为两部分:
-
卷积编码器(Convolutional Encoder):两个卷积层,每层后接 sigmoid 激活与平均池化(AvgPool)
-
全连接分类器(Dense Block):三个全连接层,最终输出 10 类概率
图 7.6.1 显示了数据从输入图像流向输出预测的过程。
卷积层配置如下:
-
Conv2d(6, kernel=5, padding=2) → Sigmoid → AvgPool2d(2, 2)
-
Conv2d(16, kernel=5) → Sigmoid → AvgPool2d(2, 2)
然后展平成一维向量,并依次通过:
-
Linear(120) → Sigmoid
-
Linear(84) → Sigmoid
-
Linear(10) → 输出概率
🧠 理论理解
LeNet-5 模型由两大模块组成:
-
卷积编码器部分(Convolutional Encoder)
-
两个卷积层 + 平均池化层 + Sigmoid 激活
-
输出空间逐渐变小,通道逐渐增加(6 → 16)
-
-
全连接分类器部分(Dense Block)
-
三个全连接层,输出为 120 → 84 → 10(对应十分类问题)
-
LeNet 的典型输入是 28×2828 \times 2828×28 的灰度图(如 MNIST 手写数字图像),其结构如下:
Input → Conv(6) → AvgPool → Conv(16) → AvgPool → Flatten → FC(120) → FC(84) → FC(10)
卷积层提取空间特征,全连接层完成最终分类。
🏭 企业实战理解(字节跳动、英伟达、Google)
-
字节跳动火山引擎:在移动端 OCR 模型压缩中,仍保留了 LeNet 风格结构作轻量版本参考。
-
英伟达 Jetson Nano:用于边缘部署的简化模型参考 LeNet 架构,极大节省运算资源。
-
Google Cloud AI:教育产品 TensorFlow Playground 使用 LeNet 作为初学者理解 CNN 的演示基础。
7.6.2 训练
在 PyTorch 中,定义模型并初始化参数:
class LeNet(d2l.Classifier):
def __init__(self, lr=0.1, num_classes=10):
super().__init__()
self.net = nn.Sequential(
nn.LazyConv2d(6, kernel_size=5, padding=2), nn.Sigmoid(),
nn.AvgPool2d(kernel_size=2, stride=2),
nn.LazyConv2d(16, kernel_size=5), nn.Sigmoid(),
nn.AvgPool2d(kernel_size=2, stride=2),
nn.Flatten(),
nn.LazyLinear(120), nn.Sigmoid(),
nn.LazyLinear(84), nn.Sigmoid(),
nn.LazyLinear(num_classes)
)
训练流程与 MLP 类似,仍使用交叉熵损失函数与随机梯度下降优化器(SGD):
trainer = d2l.Trainer(max_epochs=10, num_gpus=1)
data = d2l.FashionMNIST(batch_size=128)
model = LeNet(lr=0.1)
model.apply_init([next(iter(data.get_dataloader(True)))[0]], init_cnn)
trainer.fit(model, data)
训练过程中模型逐渐收敛,输出准确率持续上升。
🧠 理论理解
我们将 LeNet 应用到 Fashion-MNIST 数据集,使用交叉熵损失 + 随机梯度下降进行训练,训练 10 个 epoch 后准确率逐步收敛。
训练代码如下:
trainer = d2l.Trainer(max_epochs=10, num_gpus=1)
data = d2l.FashionMNIST(batch_size=128)
model = LeNet(lr=0.1)
model.apply_init([next(iter(data.get_dataloader(True)))[0]], init_cnn)
trainer.fit(model, data)
训练过程中模型收敛良好,val_acc 稳步提升,体现出 CNN 在图像任务上的优越性。
🏭 企业实战理解(百度、OpenAI)
-
百度 EasyDL:早期图像分类 API 模板采用 LeNet 结构快速验证用户上传数据是否有效;
-
OpenAI 内部教学模型:在 GPT vision 视觉教学体系中,LeNet 被用作最简 CNN 结构向员工解释卷积神经网络的构建方式。
7.6.3 小结
LeNet 是 CNN 领域的重要基础架构,其结构至今仍被广泛借鉴。它启示我们:
-
卷积 + 池化的特征提取方法比展平输入更有效
-
参数少、计算量适中,便于部署
-
是理解更复杂架构(如 ResNet)的前置基础
同时,LeNet 也是可快速实现与实验的经典入门模型。
🧠 理论理解
LeNet 是 CNN 历史上的奠基之作,其关键价值:
-
引入了端到端学习的思想(从输入像素直接到分类结果)
-
替代了传统手工特征提取方式
-
尽管较老,结构简洁,对初学者极友好
它也证明了“特征学习 + 空间不变性”这一范式的可行性,后来者如 AlexNet、VGG、ResNet 均从其汲取灵感。
🏭 企业实战价值总结(现代演进)
-
LeNet 虽已“退休”,但在工业界大量演化版本依旧延续其 卷积 → 池化 → 全连接 的结构思路;
-
很多工业模型在边缘部署、模型压缩(如 TinyML)、知识蒸馏等场景中仍以 LeNet 为结构基准;
7.6.4 练习
-
将 AvgPool 改为 MaxPool
-
将 Sigmoid 改为 ReLU
-
增大或减小卷积核大小
-
改变输出通道数量
-
增加或减少卷积层数
-
修改全连接层的数量和大小
-
在 MNIST 上测试改进后的网络
-
可视化第一、二层的特征图响应
-
输入不同类型图片(如猫/车/随机噪声)观察激活差异