1998卷积网络入门指南:从基础原理到实战应用

1次阅读
没有评论

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

image.webp

背景介绍

卷积神经网络(Convolutional Neural Network, CNN)是计算机视觉领域的基石技术。1998 年,Yann LeCun 提出的 LeNet- 5 架构首次将卷积操作(convolution)、下采样(subsampling,即现代所说的池化 /pooling)和全连接层(fully connected layer)有机结合,成功应用于手写数字识别。这个只有 5 层的 ” 浅 ” 网络,在当时 MNIST 数据集上达到了 99.2% 的惊人准确率。

1998 卷积网络入门指南:从基础原理到实战应用

LeNet- 5 的里程碑意义在于:

  • 首次证明了局部感受野(local receptive fields)和权值共享(weight sharing)的有效性
  • 确立了 ” 卷积 - 池化 - 非线性激活 ” 的基础架构范式
  • 为后来的 AlexNet、VGG 等现代 CNN 奠定了设计基础

架构详解

LeNet- 5 的原始论文中描绘的架构包含 7 层(实际可训练参数的是 5 层),其数据流如下图所示:

 输入 (32×32) → 卷积 C1(6@28×28) → 池化 S2(6@14×14) → 卷积 C3(16@10×10) → 池化 S4(16@5×5) → 卷积 C5(120@1×1) → 全连接 F6(84) → 输出 (10)

核心层解析

  1. 卷积层(Convolution Layer)
  2. 使用 5×5 卷积核(kernel)与输入做滑动窗口乘加运算
  3. 原始实现使用 sigmoid 激活函数:$\sigma(x) = \frac{1}{1+e^{-x}}$
  4. C1 层输出特征图(feature map)尺寸计算:$(32-5)/1 + 1 = 28$

  5. 池化层(Subsampling Layer)

  6. 当时的平均池化(average pooling),现代更多使用最大池化(max pooling)
  7. 2×2 窗口配合步长 (stride)2,实现 75% 的下采样
  8. 每个池化单元会乘以可训练权重再加偏置(现代架构通常省略)

  9. 全连接层(Fully Connected Layer)

  10. 将最后一个卷积层的输出展平后接传统神经网络
  11. 使用径向基函数(RBF)作为输出层(现代架构已弃用)

PyTorch 实现

网络定义

import torch
import torch.nn as nn

class LeNet5(nn.Module):
    def __init__(self):
        super().__init__()
        # 输入 1×32×32(现代实现常改为 28×28)self.conv1 = nn.Conv2d(1, 6, kernel_size=5, padding=2)  # 输出 6@28×28
        self.pool1 = nn.AvgPool2d(kernel_size=2, stride=2)      # 输出 6@14×14
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)            # 输出 16@10×10
        self.pool2 = nn.AvgPool2d(kernel_size=2, stride=2)      # 输出 16@5×5
        self.conv3 = nn.Conv2d(16, 120, kernel_size=5)          # 输出 120@1×1
        self.fc1 = nn.Linear(120, 84)
        self.fc2 = nn.Linear(84, 10)

    def forward(self, x):
        x = torch.sigmoid(self.conv1(x))
        x = self.pool1(x)
        x = torch.sigmoid(self.conv2(x))
        x = self.pool2(x)
        x = torch.sigmoid(self.conv3(x))
        x = x.view(x.size(0), -1)  # 展平
        x = torch.sigmoid(self.fc1(x))
        x = self.fc2(x)
        return x

训练代码

from torchvision import datasets, transforms

# 数据预处理
transform = transforms.Compose([transforms.Resize(32),
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_set = datasets.MNIST('./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)

model = LeNet5()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 训练循环
for epoch in range(10):
    for images, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')

现代 CNN 对比

指标 LeNet-5 ResNet-18
参数量 60k 11M
感受野 14×14 483×483
典型准确率 99.2% 99.7%
计算量 (FLOPs) 0.5M 1.8G

虽然 LeNet- 5 在性能上已被超越,但其设计理念仍值得学习:

  • 通过堆叠小卷积核(而非大卷积核)实现层次化特征提取
  • 交替使用卷积和池化逐步压缩空间维度
  • 末端使用全连接层完成分类决策

避坑指南

  1. 学习率设置
  2. 浅层网络对学习率更敏感,建议初始值设为 0.01-0.1
  3. 可配合线性 warmup 策略:前 5 个 epoch 逐渐增大学习率

  4. 梯度消失缓解

  5. 原始论文使用 sigmoid 激活函数,容易引发梯度消失
  6. 现代实现可替换为 ReLU:nn.ReLU()

  7. 参数初始化

  8. 卷积层建议使用 Xavier 初始化:
    nn.init.xavier_uniform_(self.conv1.weight)
  9. 避免全零初始化导致对称性问题

延伸思考

为什么现代 CNN 不再使用 LeNet- 5 的某些设计?

  • sigmoid 激活函数 :存在梯度消失问题,计算开销大(需要指数运算)
  • 平均池化 :最大池化能更好保留纹理特征
  • RBF 输出层 :softmax+ 交叉熵的组合更易优化
  • 全连接层 :被全局平均池化(GAP)取代以减少参数量

扩展阅读

  1. 原始论文:Gradient-Based Learning Applied to Document Recognition
  2. PyTorch 官方教程:LeNet- 5 实现
  3. 现代改进版:LeNet-5 with BatchNorm

通过复现这个经典架构,我们能更深刻地理解 CNN 的设计哲学。虽然现代网络更加复杂,但特征层次化提取的核心思想从未改变。建议初学者在掌握 LeNet- 5 后,逐步过渡到 AlexNet、VGG 等更深的架构。

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