LeNet - 开创性的卷积神经网络
历史背景
LeNet 是最早的卷积神经网络之一,由 Yann LeCun 在 1989 年提出,主要用于手写数字识别(MNIST 数据集)。在深度学习复兴之前,LeNet 就已经在商业应用中取得了成功,例如在 ATM 机上识别支票数字。
虽然现在看来它的结构相对简单,但 LeNet 奠定了现代卷积神经网络的基础架构,是深度学习历史上的里程碑。
网络结构
LeNet-5 由两部分组成:卷积编码器和全连接层
完整架构
输入 (1×28×28)
↓
Conv1 (6个5×5卷积核) → Sigmoid → AvgPool (2×2)
↓ (6×14×14)
Conv2 (16个5×5卷积核) → Sigmoid → AvgPool (2×2)
↓ (16×5×5)
Flatten → FC1 (120) → Sigmoid
↓
FC2 (84) → Sigmoid
↓
FC3 (10个输出)
层级详解
-
第一个卷积块
- 输入:1 通道(灰度图像)28×28
- 卷积层:6 个 5×5 卷积核,输出 6×28×28
- 激活函数:Sigmoid
- 平均池化:2×2,输出 6×14×14
-
第二个卷积块
- 卷积层:16 个 5×5 卷积核,输出 16×10×10
- 激活函数:Sigmoid
- 平均池化:2×2,输出 16×5×5
-
全连接层
- 展平:16×5×5 = 400
- FC1:400 → 120(Sigmoid)
- FC2:120 → 84(Sigmoid)
- FC3:84 → 10(输出层,10个数字类别)
PyTorch 实现
import torch
from torch import nn
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
# 卷积编码器
self.conv1 = nn.Conv2d(1, 6, kernel_size=5, padding=2)
self.sigmoid = nn.Sigmoid()
self.avgpool = nn.AvgPool2d(kernel_size=2, stride=2)
self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
# 全连接层
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 卷积块 1
x = self.sigmoid(self.conv1(x))
x = self.avgpool(x)
# 卷积块 2
x = self.sigmoid(self.conv2(x))
x = self.avgpool(x)
# 展平
x = x.view(x.size(0), -1)
# 全连接层
x = self.sigmoid(self.fc1(x))
x = self.sigmoid(self.fc2(x))
x = self.fc3(x)
return x
# 创建模型
net = LeNet()
print(net)
查看每层输出形状
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
X = layer(X)
print(layer.__class__.__name__, 'output shape: \t', X.shape)
输出:
Conv2d output shape: torch.Size([1, 6, 28, 28])
Sigmoid output shape: torch.Size([1, 6, 28, 28])
AvgPool2d output shape: torch.Size([1, 6, 14, 14])
Conv2d output shape: torch.Size([1, 16, 10, 10])
Sigmoid output shape: torch.Size([1, 16, 10, 10])
AvgPool2d output shape: torch.Size([1, 16, 5, 5])
Flatten output shape: torch.Size([1, 400])
Linear output shape: torch.Size([1, 120])
Sigmoid output shape: torch.Size([1, 120])
Linear output shape: torch.Size([1, 84])
Sigmoid output shape: torch.Size([1, 84])
Linear output shape: torch.Size([1, 10])
核心设计思想
1. 保留空间结构
与传统的多层感知机不同,LeNet 使用卷积层而非全连接层处理图像,避免了将图像展平导致的空间信息丢失。