从AlexNet到LeNet:卷积神经网络模型搭建实战与性能对比

1次阅读
没有评论

共计 2524 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

卷积神经网络在计算机视觉中的核心地位

卷积神经网络(CNN)已成为计算机视觉领域的基石技术,其局部连接和权重共享的特性使其特别适合处理图像数据。在众多 CNN 架构中,LeNet 和 AlexNet 因其里程碑意义而成为必学经典:

从 AlexNet 到 LeNet:卷积神经网络模型搭建实战与性能对比

  • 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

实战避坑指南

  1. 输入尺寸不匹配 :AlexNet 原始设计输入为 224×224,直接用于 32×32 的 CIFAR 会报错。解决方案:
  2. 修改首层卷积参数:nn.Conv2d(3,64,kernel_size=3,stride=1,padding=1)
  3. 或使用插值 resize:nn.Upsample(scale_factor=7)

  4. 梯度消失问题 :LeNet 使用 Sigmoid 时深层网络难以训练。改进方案:

  5. 替换为 ReLU 激活函数
  6. 使用 Xavier 初始化:nn.init.xavier_uniform_(self.conv1.weight)

  7. 过拟合处理 :AlexNet 参数量大易过拟合。应对措施:

  8. 增加数据增强:随机裁剪、色彩抖动
  9. 早停机制:验证集 loss 连续 3 轮不降则停止

  10. 显存不足 :AlexNet 需要调整 batch_size。折中方案:

  11. 使用梯度累积:每 4 个 batch 更新一次参数
  12. 混合精度训练:scaler = torch.cuda.amp.GradScaler()

  13. 现代优化器选择 :原始论文使用 SGD with momentum。推荐升级:

  14. Adam 优化器:optim.Adam(model.parameters(), lr=0.001)
  15. 学习率预热:前 5epoch 线性增加 lr

延伸思考

  1. 模型轻量化:如何在不显著降低准确率的前提下,将 AlexNet 参数量压缩到 1 /10?
  2. 跨架构融合:能否将 LeNet 的浅层结构与 AlexNet 的 ReLU/Dropout 设计结合?
  3. 硬件适配:针对边缘设备(如树莓派),哪些优化策略最有效?

通过本实验可以观察到,虽然 AlexNet 准确率更高,但其计算代价是 LeNet 的 4 - 5 倍。在实际项目中,需要根据硬件条件和实时性要求进行权衡选择。后续可尝试将 ResNet 的残差连接等现代设计融入这些经典架构,探索更多可能性。

正文完
 0
评论(没有评论)