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