经典CNN模型之LeNet与AlexNet
1. LeNet-5:卷积神经网络的先驱
1.1 背景与历史意义
- 诞生时间:1998年由Yann LeCun提出
- 核心贡献:首次将卷积层、池化层和全连接层结合,成功应用于手写数字识别
- 里程碑地位:奠定了现代CNN的基础架构
1.2 网络架构详解
# 典型LeNet-5结构示意
Input(32x32) →
Conv1(6@5x5, stride=1) → AvgPool(2x2) →
Conv2(16@5x5) → AvgPool(2x2) →
FC(120) → FC(84) → Output(10)
关键设计特点:
- 卷积核:使用5×5的小型卷积核
- 降采样:采用平均池化(当时未使用最大池化)
- 激活函数:原始版本使用tanh(现代实现常用ReLU)
- 输入尺寸:32×32灰度图像(MNIST数据集)
1.3 实际应用与局限
- 成功案例:银行支票手写数字识别系统
- 历史局限:
- 仅支持小尺寸灰度图像
- 浅层网络(2个卷积层)特征提取能力有限
2. AlexNet:深度学习的复兴者
2.1 突破性进展
- ImageNet 2012冠军:将Top-5错误率从26%降至15.3%
- 技术革新:
- 首次证明深度CNN在大规模图像识别中的有效性
- 开启深度学习在计算机视觉的新时代
2.2 网络架构创新
# AlexNet核心结构(原始论文实现)
Input(227x227x3) →
Conv1(96@11x11, stride=4) → MaxPool → LocalRespNorm →
Conv2(256@5x5, pad=2) → MaxPool → LRN →
Conv3(384@3x3) → Conv4(384@3x3) → Conv5(256@3x3) →
MaxPool → FC(4096) → FC(4096) → Output(1000)
关键技术亮点:
- ReLU激活函数:解决梯度消失问题,训练速度比tanh快6倍
- 重叠池化:3×3池化窗口使用stride=2,提升特征多样性
- 局部响应归一化(LRN):增强泛化能力(后被BN取代)
- Dropout:在全连接层使用0.5丢弃率,防止过拟合
- 数据增强:随机裁剪、水平翻转等策略
2.3 工程实现突破
- 多GPU训练:首次在CNN中使用并行训练(GTX 580 3GB × 2)
- 训练技巧:
- 动量SGD(momentum=0.9)
- 权重衰减(L2正则化)
- 学习率动态调整
3. 对比分析与现代启示
| 特性 | LeNet-5 | AlexNet |
|---|---|---|
| 提出时间 | 1998 | 2012 |
| 深度 | 5层(2卷积) | 8层(5卷积) |
| 参数量 | ~60k | ~60M |
| 输入尺寸 | 32×32灰度 | 227×227 RGB |
| 计算设备 | CPU | 双GPU |
| 数据集 | MNIST(6万样本) | ImageNet(120万样本) |
3.1 历史传承关系
- AlexNet本质上是LeNet的"深度扩展版"
- 两者共享"卷积-池化-全连接"的基础范式
3.2 现代改进方向
- 小卷积核趋势:AlexNet的11×11卷积被VGG的3×3卷积取代
- 归一化演进:LRN → Batch Normalization
- 计算效率:从参数冗余设计到紧凑结构(如MobileNet)
4. 代码实现示例(PyTorch)
# AlexNet简化版实现
import torch.nn as nn
class AlexNet(nn.Module):
def __init__(self, num_classes=1000):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256*6*6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = torch.flatten(x, 1)
x = self.classifier(x)
return x
现代实践建议:实际使用时建议采用torchvision.models.alexnet(pretrained=True)的预训练版本,并针对具体任务进行微调。
