从LeNet到AlexNet,见证了深度学习在计算机视觉的革命。本课回顾这两个里程碑网络,复现它们的架构和训练过程。
Yann LeCun提出的LeNet-5是第一个成功的卷积神经网络,用于手写数字识别(MNIST)。它奠定了CNN的基本范式:卷积→池化→全连接。
| 层 | 类型 | 输入 | 输出 |
|---|---|---|---|
| 1 | Conv 5×5 | 32×32×1 | 28×28×6 |
| 2 | AvgPool 2×2 | 28×28×6 | 14×14×6 |
| 3 | Conv 5×5 | 14×14×6 | 10×10×16 |
| 4 | AvgPool 2×2 | 10×10×16 | 5×5×16 |
| 5 | FC | 400 | 120 |
| 6 | FC | 120 | 84 |
| 7 | FC | 84 | 10 |
Alex Krizhevsky等人在ImageNet竞赛中以巨大优势夺冠,开启了深度学习时代。关键创新:ReLU激活、Dropout、GPU训练、数据增强。
AlexNet包含5个卷积层和3个全连接层,约6000万参数。使用ReLU代替Sigmoid,训练速度快6倍。
import torch
import torch.nn as nn
import torch.nn.functional as F
# LeNet-5实现
class LeNet5(nn.Module):
def __init__(self):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 6, 5), # 32→28
nn.Sigmoid(),
nn.AvgPool2d(2), # 28→14
nn.Conv2d(6, 16, 5), # 14→10
nn.Sigmoid(),
nn.AvgPool2d(2), # 10→5
)
self.classifier = nn.Sequential(
nn.Linear(16*5*5, 120),
nn.Sigmoid(),
nn.Linear(120, 84),
nn.Sigmoid(),
nn.Linear(84, 10),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
return self.classifier(x)
# AlexNet简化版
class AlexNetSimple(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 64, 3, padding=1), nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 192, 3, padding=1), nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(192, 384, 3, padding=1), nn.ReLU(),
nn.Conv2d(384, 256, 3, padding=1), nn.ReLU(),
nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(),
nn.MaxPool2d(2),
)
self.classifier = nn.Sequential(
nn.Linear(256*4*4, 4096), nn.ReLU(), nn.Dropout(0.5),
nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
return self.classifier(x)
# 对比
models = {"LeNet-5": LeNet5(), "AlexNet(简化)": AlexNetSimple()}
for name, model in models.items():
x = torch.randn(1, 1, 32, 32)
out = model(x)
params = sum(p.numel() for p in model.parameters())
print(f"{name}: 输入{list(x.shape)} → 输出{list(out.shape)}, 参数量={params:,}")
# 训练测试
X = torch.randn(100, 1, 32, 32)
y = torch.randint(0, 10, (100,))
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
loss_fn = nn.CrossEntropyLoss()
for epoch in range(0, 51, 25):
optimizer.zero_grad()
loss = loss_fn(model(X), y)
loss.backward()
optimizer.step()
if epoch % 25 == 0:
acc = (model(X).argmax(1) == y).float().mean()
print(f" Epoch {epoch}: loss={loss.item():.4f}, acc={acc.item():.2%}")
AlexNet最持久的贡献是证明了ReLU的优越性。Sigmoid/Tanh在深层网络中梯度消失严重,而ReLU在正区间梯度恒为1,使得深层训练成为可能。
AlexNet首次使用双GPU并行训练,训练时间从数周缩短到5-6天。这开启了GPU加速深度学习的时代。
| 年份 | 模型 | Top-5错误率 | 创新 |
|---|---|---|---|
| 2012 | AlexNet | 16.4% | ReLU, Dropout, GPU |
| 2013 | ZFNet | 11.2% | 反卷积可视化 |
| 2014 | VGG | 7.3% | 小卷积核,更深层 |
| 2014 | GoogLeNet | 6.7% | Inception模块 |
| 2015 | ResNet | 3.6% | 残差连接 |
| 2017 | SeNet | 2.3% | 通道注意力 |
💡 推荐资源:
下载MNIST数据集,训练LeNet-5,报告测试集精度。
将AlexNet的Sigmoid换为ReLU,对比训练速度。
提取第一个卷积层的滤波器,可视化它们学到的模式。
从LeNet到ResNet,CNN遵循一个共同模式:
理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:
建立正确的直觉比记住公式更重要:
1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)
2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的
3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构
4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)
本课作为CNN阶段的核心内容,与前后课程紧密关联:
| 关联课程 | 关联点 | 协同效应 |
|---|---|---|
| 前序课程 | 提供了本课的基础知识 | 循序渐进的理解 |
| 后续课程 | 本课内容是后续的基础 | 逐步构建能力 |
| 平行课程 | 同一阶段的互补知识 | 多角度深入理解 |
| 实战项目 | 综合运用所有知识 | 理论与实践结合 |
💡 准备面试时,确保能回答以下问题:
掌握本课内容后,可以通过以下方式继续深入:
将本课涉及的关键公式整理如下,方便回顾和记忆。理解每个公式背后的直觉比死记硬背更重要——试着用自然语言解释每个公式在做什么。
| 概念A | 概念B | 关键区别 |
|---|---|---|
| 参数 | 超参数 | 参数通过训练学习,超参数需要手动设定 |
| 训练误差 | 泛化误差 | 训练误差衡量拟合程度,泛化误差衡量预测能力 |
| 偏差 | 方差 | 偏差是系统性误差,方差是随机波动 |
| L1正则 | L2正则 | L1产生稀疏解,L2产生平滑解 |
| BatchNorm | LayerNorm | BN沿batch维度,LN沿特征维度 |
以下是本课核心概念的标准PyTorch实现模板,可以直接用于实际项目:
💡 调试建议:当结果不符合预期时,先检查数据,再检查损失函数,最后检查模型结构。90%的问题出在前两个环节。
从LeNet到AlexNet,你了解了CNN的革命性发展!