共计 2524 个字符,预计需要花费 7 分钟才能阅读完成。
卷积神经网络在计算机视觉中的核心地位
卷积神经网络(CNN)已成为计算机视觉领域的基石技术,其局部连接和权重共享的特性使其特别适合处理图像数据。在众多 CNN 架构中,LeNet 和 AlexNet 因其里程碑意义而成为必学经典:

- LeNet-5(1998):首个成功应用于数字识别的 CNN,证明了卷积结构的有效性
- AlexNet(2012):在 ImageNet 竞赛中以绝对优势夺冠,推动了深度学习复兴
选择这两个模型进行对比,既能看到 CNN 的基础设计思想,又能观察网络深度增加带来的性能变化。
模型架构对比
| 特性 | LeNet-5 | AlexNet |
|---|---|---|
| 提出时间 | 1998 | 2012 |
| 网络深度 | 7 层(2 卷积) | 8 层(5 卷积) |
| 参数量 | ~60K | ~60M |
| 激活函数 | Sigmoid | ReLU |
| 正则化 | – | Dropout(0.5) |
| 输入尺寸 | 32×32 | 224×224 |
PyTorch 实现详解
数据预处理
import torch
from torchvision import transforms, datasets
# 通用数据增强策略
train_transforms = transforms.Compose([transforms.RandomHorizontalFlip(), # 水平翻转增强
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # CIFAR-10 单通道归一化
])
test_transforms = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
LeNet- 5 模型定义
import torch.nn as nn
class LeNet(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 6, 5) # 输入 1 通道,输出 6 通道,5x5 卷积核
self.pool = nn.MaxPool2d(2, 2) # 2x2 最大池化
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10) # CIFAR-10 共 10 类
def forward(self, x):
x = self.pool(torch.sigmoid(self.conv1(x)))
x = self.pool(torch.sigmoid(self.conv2(x)))
x = torch.flatten(x, 1) # 展平特征图
x = torch.sigmoid(self.fc1(x))
x = torch.sigmoid(self.fc2(x))
x = self.fc3(x)
return x
AlexNet 关键改进点
class AlexNet(nn.Module):
def __init__(self):
super().__init__()
self.features = nn.Sequential(nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2), # 适应 224 输入
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),
# 后续卷积层省略...
)
self.classifier = nn.Sequential(nn.Dropout(0.5), # 防止过拟合
nn.Linear(256*6*6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, 10),
)
性能对比(CIFAR-10)
| 指标 | LeNet-5 | AlexNet |
|---|---|---|
| 训练时间 /epoch | 45s | 210s |
| 测试准确率 | 68.2% | 75.6% |
| 显存占用 (MB) | 780 | 2900 |
测试环境:NVIDIA T4 GPU, batch_size=128
实战避坑指南
- 输入尺寸不匹配 :AlexNet 原始设计输入为 224×224,直接用于 32×32 的 CIFAR 会报错。解决方案:
- 修改首层卷积参数:
nn.Conv2d(3,64,kernel_size=3,stride=1,padding=1) -
或使用插值 resize:
nn.Upsample(scale_factor=7) -
梯度消失问题 :LeNet 使用 Sigmoid 时深层网络难以训练。改进方案:
- 替换为 ReLU 激活函数
-
使用 Xavier 初始化:
nn.init.xavier_uniform_(self.conv1.weight) -
过拟合处理 :AlexNet 参数量大易过拟合。应对措施:
- 增加数据增强:随机裁剪、色彩抖动
-
早停机制:验证集 loss 连续 3 轮不降则停止
-
显存不足 :AlexNet 需要调整 batch_size。折中方案:
- 使用梯度累积:每 4 个 batch 更新一次参数
-
混合精度训练:
scaler = torch.cuda.amp.GradScaler() -
现代优化器选择 :原始论文使用 SGD with momentum。推荐升级:
- Adam 优化器:
optim.Adam(model.parameters(), lr=0.001) - 学习率预热:前 5epoch 线性增加 lr
延伸思考
- 模型轻量化:如何在不显著降低准确率的前提下,将 AlexNet 参数量压缩到 1 /10?
- 跨架构融合:能否将 LeNet 的浅层结构与 AlexNet 的 ReLU/Dropout 设计结合?
- 硬件适配:针对边缘设备(如树莓派),哪些优化策略最有效?
通过本实验可以观察到,虽然 AlexNet 准确率更高,但其计算代价是 LeNet 的 4 - 5 倍。在实际项目中,需要根据硬件条件和实时性要求进行权衡选择。后续可尝试将 ResNet 的残差连接等现代设计融入这些经典架构,探索更多可能性。
正文完
发表至: 未分类
近一天内
