本节摘要:LeNet-5 是第一套完整跑通"卷积、下采样、卷积、下采样、全连接、输出"的卷积流水线,1998 年前后已在美国的支票识别系统里商用。它只有 61,706 个参数,却把现代 CNN 的全部骨架要素提前二十年画好了图。本节用现代 PyTorch 复刻它、逐层对账它的参数,并提炼三条沿用至今的设计遗产。
上世纪九十年代,银行的支票自动处理系统要读的正是手写数字:金额一格一格的阿拉伯数字,字体五花八门。贝尔实验室的团队用卷积网络接下了这个活儿,成果就是 LeNet-5 及其家族——鼎盛时期,全美相当大比例的支票由它读取。这桩商用案例比"深度学习爆红"早了将近二十年,也解释了一个常被忽略的事实:CNN 的骨架早就成熟,差的只是数据规模与算力。
阅读完本节,你应当能够:
LeNet-5 吃 32×32 的灰度图,两轮"卷积加下采样"之后接三层全连接。把每层尺寸与参数列开,正好是一次 2.6 节式巡检的实战演练:
| 层 | 出口形状 | 参数量 | 备注 |
|---|---|---|---|
| 卷积一 5×5 | 6×28×28 | 156 | 尺寸 32 减到 28:不填充 |
| 平均池化 2×2 | 6×14×14 | 0 | 原版称下采样层 |
| 卷积二 5×5 | 16×10×10 | 2,416 | 6 通道进 16 核 |
| 平均池化 2×2 | 16×5×5 | 0 | |
| 全连接一 | 120 | 48,120 | 16×5×5=400 维进 |
| 全连接二 | 84 | 10,164 | |
| 输出层 | 10 | 850 | 手写数字十个类 |
手算复核:卷积一 5×5×1×6 加 6 得 156;卷积二 5×5×6×16 加 16 得 2,416;三个全连接分别 400×120 加 120、120×84 加 84、84×10 加 10。合计 61,706,分毫不差。注意那张熟悉的面孔:三个全连接贡献 59,134 个参数,占 95.8%——"分类头是大头"的病根,从第一代机型就确诊了。
import torch import torch.nn as nn class ModernLeNet(nn.Module): """按现代习惯复刻:平均池化换位置不变,激活用 ReLU 替原版的 tanh 系""" def __init__(self, num_classes=10): super().__init__() self.features = nn.Sequential( nn.Conv2d(1, 6, kernel_size=5), nn.ReLU(), nn.AvgPool2d(2), # 6×28×28 → 6×14×14 nn.Conv2d(6, 16, kernel_size=5), nn.ReLU(), nn.AvgPool2d(2), # 16×10×10 → 16×5×5 ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(400, 120), nn.ReLU(), nn.Linear(120, 84), nn.ReLU(), nn.Linear(84, num_classes), ) def forward(self, x): return self.classifier(self.features(x)) net = ModernLeNet() x = torch.randn(1, 1, 32, 32) print(tuple(net(x).shape)) # (1, 10) print("总参数量:", sum(p.numel() for p in net.parameters())) # 61706
第二段代码把参数按层摊开,确认账目与手算一致:
for name, p in net.named_parameters(): print(f"{name:18s}{str(tuple(p.shape)):20s}{p.numel():>7d}") # features.0.weight (6, 1, 5, 5) 150 # features.0.bias (6,) 6 # features.3.weight (16, 6, 5, 5) 2400 # features.3.bias (16,) 16 # classifier.1.weight (120, 400) 48000 # classifier.1.bias (120,) 120 # classifier.3.weight (84, 120) 10080 # classifier.3.bias (84,) 84 # classifier.5.weight (10, 84) 840 # classifier.5.bias (10,) 10
对账之外,LeNet-5 留下三条至今有效的遗产。其一,层级特征观:边缘在浅层、部件在中层、整体在高层,这套"由简到繁"的特征梯子是所有后续机型的骨架假设。其二,卷积与下采样交替的节奏:先提模式、再收尺寸,至今仍是 CNN 的标准节拍(只是下采样后来多交给步幅卷积)。其三,端到端:像素进、类别出,中间不再插手工特征的手,训练一把完成。
它的局限同样写在账上:输入只有 32×32 的灰度小图,两层卷积的容量也只够分十类。让它发挥不出全部实力的不是设计,而是当年没有 ImageNet 这样的百万级数据集,也没有够用的显卡——补齐这两块拼图的事,落在了 3.2 节的 AlexNet 头上。
💡 关键直觉:读老架构最省力的角度是"它在等什么"。LeNet-5 在等数据与算力;看懂这个,3.2 节 AlexNet 的每一项改动你都会觉得理所当然。