经典架构:站在巨人的肩膀上
深度学习的发展史上有几个里程碑式的网络架构,它们不仅在当时取得了突破性的成果,其设计思想也深刻地影响了后续的研究。了解它们,就是理解现代深度学习的演进之路。
LeNet-5 (1998):CNN 的开山鼻祖
核心贡献:由 Yann LeCun 提出,首次成功应用于手写数字识别。LeNet-5 奠定了现代 CNN 的基础结构:卷积层 -> 池化层 -> 卷积层 -> 池化层 -> 全连接层 -> 输出层。这个“卷积-池化”交替堆叠的范式至今仍被广泛使用。
输入
→
卷积
→
池化
→
卷积
→
池化
→
全连接
→
输出
from tensorflow import keras
from keras import layers
model = keras.Sequential([
layers.Conv2D(6, kernel_size=5, activation='tanh', input_shape=(32, 32, 1)),
layers.AveragePooling2D(pool_size=2),
layers.Conv2D(16, kernel_size=5, activation='tanh'),
layers.AveragePooling2D(pool_size=2),
layers.Flatten(),
layers.Dense(120, activation='tanh'),
layers.Dense(84, activation='tanh'),
layers.Dense(10, activation='softmax')
])
AlexNet (2012):深度学习革命的点燃者
核心贡献:在 2012 年的 ImageNet 图像识别竞赛中以碾压性优势夺冠,宣告了深度学习时代的到来。它的成功归功于几个关键创新:
- 使用了更深的网络结构(8层)。
- 首次采用 ReLU 作为激活函数,有效解决了梯度消失问题。
- 引入了 Dropout 层来防止过拟合。
- 利用 GPU 进行并行计算,大大加快了训练速度。
输入
→
卷积 x5
→
池化 x3
→
全连接 x3
→
输出
# 简化版 AlexNet 结构
model = keras.Sequential([
layers.Conv2D(96, 11, strides=4, activation='relu', input_shape=(227, 227, 3)),
layers.MaxPooling2D(3, strides=2),
layers.Conv2D(256, 5, padding='same', activation='relu'),
layers.MaxPooling2D(3, strides=2),
# ... more conv layers ...
layers.Flatten(),
layers.Dense(4096, activation='relu'),
layers.Dropout(0.5),
layers.Dense(4096, activation='relu'),
layers.Dropout(0.5),
layers.Dense(1000, activation='softmax')
])
VGGNet (2014):深度与简洁的艺术
核心贡献:VGGNet 探索了网络深度的重要性。它的结构非常规整、优雅,证明了通过重复堆叠非常小的 3x3 卷积核,可以构建出非常深(如 VGG-16, VGG-19)且性能强大的网络。两个 3x3 卷积的堆叠等效于一个 5x5 卷积的感受野,但参数更少,非线性更强。
输入
→
[3x3卷积] xN
→
池化
→
[3x3卷积] xN
→
...
# VGG-16 块的简化示例
def vgg_block(num_convs, num_filters):
block = keras.Sequential()
for _ in range(num_convs):
block.add(layers.Conv2D(num_filters, kernel_size=3, padding='same', activation='relu'))
block.add(layers.MaxPooling2D(pool_size=2, strides=2))
return block
# model = keras.Sequential([
# vgg_block(2, 64),
# vgg_block(2, 128),
# ...
# ])
ResNet (2015):突破深度极限的残差网络
核心贡献:当网络变得非常深时,会出现“退化”问题(训练误差反而上升)。ResNet 通过引入革命性的残差块 (Residual Block) 解决了这个问题。残差块允许信息通过“跳线连接 (Skip Connection)”直接跳过多层,使得网络更容易学习恒等映射,从而可以构建出前所未有的深度(如 152 层甚至更深)并取得极佳性能。
输入 x
卷积层
卷积层
跳线连接
+
输出 F(x) + x
# ResNet 块的简化示例
def residual_block(x, filters):
# 主路径
fx = layers.Conv2D(filters, 3, padding='same', activation='relu')(x)
fx = layers.Conv2D(filters, 3, padding='same')(fx)
# 跳线连接
out = layers.add([x, fx])
out = layers.ReLU()(out)
return out