本讲涵盖两大主题: - 如何构建 CNN? 层组件、激活函数、经典架构、权重初始化 - 如何训练 CNN? 数据预处理、数据增强、迁移学习、超参数选择


$\large\star$ Part I:如何构建 CNN

一、CNN 组件回顾

1.1 基本组件

组件 作用 关键点
卷积层 空间局部特征提取 可学习滤波器,权重共享
池化层 下采样 无参数,Max/Avg Pool
全连接层 全局信息综合 展平后线性变换
激活函数 引入非线性 置于线性层后
归一化层 稳定训练 LayerNorm / BatchNorm
Dropout 正则化 随机置零,防止过拟合

1.2 归一化层:LayerNorm

核心思想:学习可调参数来缩放/平移数据。

$$\hat{x} = \frac{x - \mu}{\sigma}, \quad y = \gamma \hat{x} + \beta$$

  • μ, σ:从数据计算(均值、标准差)
  • γ, β:可学习的缩放和平移参数
归一化类型 统计量计算维度 常见用途
BatchNorm 沿 Batch 维度 CNN 常用(Assign 2 中实现)
LayerNorm 沿特征维度(每个样本独立) Transformer 常用
GroupNorm BatchNorm 和 LayerNorm 的折中 小 batch 场景

1.3 Dropout

训练时:每个前向传播随机将一部分神经元置零(概率 p,常用 p = 0.5)

为什么有效? 1. 冗余表示:强制网络学到冗余特征,不能依赖任何单个神经元 2. 集成学习:每次 dropout 产生不同的子网络,相当于训练了一个庞大模型集合的共享参数版本

一个 4096 单元的 FC 层有 24096 ≈ 101233 种可能的 dropout 掩码——远超宇宙原子总数!

测试时:所有神经元保持激活,需要缩放输出以匹配训练时的期望值。

训练:随机丢 p 的神经元   测试:保留所有,乘以 p

一般模式:训练时加随机性 → 测试时”平均”掉随机性


二、激活函数

2.1 激活函数总览

函数 公式 优点 缺点
Sigmoid $\sigma(x) = \frac{1}{1+e^{-x}}$ 有界 [0,1],历史意义 饱和→梯度消失;非零中心
tanh tanh (x) 零中心 仍会饱和
ReLU max (0, x) 计算快,不饱和(正半轴),实践中收敛比 sigmoid 快 ~6 倍 非零中心;x < 0 梯度为零→Dead ReLU
Leaky ReLU max (0.01x, x) 缓解 Dead ReLU 负半轴超参数需手动设
ELU x(x ≥ 0), α(ex − 1)(x < 0) 更平滑,接近零中心 计算代价更高
GELU x ⋅ Φ(x) 行为平滑,接近 0 时梯度和缓 计算代价高于 ReLU

2.2 Sigmoid 的问题

σ′(x) = σ(x)(1 − σ(x))

  • x 很大或很小时,梯度趋近 0 → 梯度消失
  • 多层 sigmoid 叠加 → 梯度越来越小,深层无法训练

2.3 ReLU:默认首选

f(x) = max (0, x)

  • 正半轴不饱和 → 梯度可以一直流动
  • 计算极简(一个阈值操作)
  • Dead ReLU 问题:x < 0 时梯度为 0,若进入该区域且无法恢复,对应神经元”死亡”
  • 实践中通过合适的权重初始化缓解

2.4 GELU:现代替代方案

f(x) = x ⋅ Φ(x)  (Φ 是标准正态 CDF)

  • 在 0 附近平滑过渡(而非 ReLU 的硬截断)
  • 负半轴也保留微小梯度
  • 现代 Transformer 模型(如 ViT、GPT)广泛使用

放置位置:激活函数通常置于线性算子之后(FC 后、Conv 后)。


三、CNN 经典架构

3.1 CNN经典模型

年份 模型 层数 核心创新
2012 AlexNet 8 首个在大规模数据上的深度 CNN
2014 VGG 16-19 小滤波器 (3×3) + 更深网络
2014 GoogLeNet 22 Inception 模块
2015 ResNet 152 残差连接,深度革命

3.2 VGGNet:小而深的滤波器

核心哲学:全部使用 3×3 conv,stride=1, pad=1 + 2×2 max pool, stride=2

为什么使用小滤波器(3×3)?

三层 3×3 conv (stride 1) 的有效感受野 = 一个 7×7 conv:

1
2
输入 → Conv1(3×3) → Conv2(3×3) → Conv3(3×3)
有效感受野 = 7 × 7

小滤波器的优势: - 更深 + 更多非线性:每个 conv 后跟 ReLU → 3 个 3×3 比 1 个 7×7 多 2 次 ReLU - 更少参数:3 × (32C2) = 27C2 vs 72C2 = 49C2(近一半的参数) - 相同感受野 + 更强表达力 + 更省内存

版本 层数 结构
VGG16 16 13 Conv + 3 FC
VGG19 19 16 Conv + 3 FC

VGG 将 ILSVRC top-5 错误率从 ZFNet 的 11.7% 降至 7.3%

3.3 ResNet:残差连接与深度革命

问题:更深的”plain”网络表现反而更差?

  • 56 层网络的训练误差和测试误差均高于 20 层
  • 不是过拟合——是优化问题!深层模型更难优化

关键洞察: - 更深的模型理应至少和更浅的一样好(可以将额外层设为恒等映射) - 但 SGD 学不出这样的恒等映射

解决方案:残差块(Residual Block)

H(x) = F(x) + x

  • 让网络层拟合残差 F(x) = H(x) − x,而不是直接拟合目标映射 H(x)
  • 若最优映射接近恒等,只需让 F(x) → 0,这比让权重学到恒等矩阵容易得多
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──────────────────────┐
│ x (identity) │ ← 跳跃连接 (skip connection)
└──────┬───────────────┘
│ ↑
┌──────▼──────────┴─────┐
│ Conv → ReLU → Conv │ ← 拟合残差 F(x)
└──────────────────────┘
│
┌──────▼──────┐
│ F(x) + x │ ← 元素相加
└──────┬──────┘
│
ReLU

ResNet 架构设计: - 残差块内两个 3×3 conv - 周期性加倍通道数 + 空间下采样(stride 2) - 开头的 stem:7×7 conv + 池化 - 结尾:全局平均池化 + FC

成果: - ImageNet 上训练 152 层 - ILSVRC’15 分类冠军(3.57% top-5 错误率) - 横扫 ILSVRC’15 和 COCO’15 所有分类和检测任务

💡 ResNet 的核心贡献:残差连接使优化极深网络成为可能——它为梯度提供了一条”高速公路”(恒等映射),缓解了深层网络的梯度消失问题。


四、权重初始化

问题:权重的初始值直接影响训练稳定性。

情况 后果
太小(如 std=0.01) 激活值逐层趋近 0,梯度消失
太大(如 std=0.05) 激活值爆炸,梯度爆炸

解决方案:Kaiming / MSRA 初始化(He et al., ICCV 2015)

$$W \sim \mathcal{N}\left(0, \frac{2}{D_{in}}\right)$$

  • Din:该层输入维度
  • $\sqrt{2}$ 因子:补偿 ReLU 将一半输入置零导致的方差衰减
  • 效果:各层激活值保持均匀分布,即”刚刚好”

不同激活函数对应不同初始化策略——Kaiming 初始化专为 ReLU 设计;对于其他激活函数(如 GELU),现代框架通常有对应的自适应版本。


$\large\star$ Part II:如何训练 CNN

五、数据预处理

TLDR:对每个通道做中心化 + 缩放:

1
2
# 对每个通道分别计算(如 RGB: 3 个均值, 3 个标准差)
x_normalized = (x - per_channel_mean) / per_channel_std
  • 几乎所有现代模型都采用此方式
  • 统计量在整个训练集上预计算

六、数据增强

核心模式:训练时引入随机变换 → 测试时平均(有时近似)

6.1 水平翻转

最简单有效的方式——大多数自然图像翻转后仍是合理图像。

6.2 随机裁剪和缩放

训练时(ResNet 风格): 1. 在 [256, 480] 中随机选短边长度 L 2. 将训练图像缩放到短边 = L 3. 随机裁剪 224 × 224 patch

测试时:对固定的一组裁剪求平均 1. 以 5 种尺度缩放:{224, 256, 384, 480, 640} 2. 每种尺度取 10 个 224 × 224 裁剪:4 角 + 中心,及各自的水平翻转

6.3 颜色抖动(Color Jitter)

随机改变对比度和亮度——增强模型对光照变化的鲁棒性。

6.4 Cutout

训练时将随机图像区域置零,测试时使用完整图像。

在小数据集(如 CIFAR)上效果显著,大数据集(如 ImageNet)较少使用。


七、迁移学习

问题:没有大数据集怎么办?

解决方案:先在大型数据集上预训练,再迁移到目标任务。

7.1 三种策略

场景 数据量 与源任务相似度 策略
小数据 + 相似任务 很少 高 冻结卷积层,只训练最后的线性分类器
较多数据 + 相似任务 较多 高 从预训练模型初始化,微调所有层
小数据 + 不同任务 很少 低 尝试其他预训练模型,或收集更多数据
较多数据 + 不同任务 较多 低 微调全部或从头训练

7.2 实际建议(咕咕嘎嘎)

🧠 如果你有 < ~100 万张图像的数据集: 1. 找一个有相似数据的大数据集,在上面训练一个大模型 2. 迁移学习到你的数据集

深度学习框架提供”Model Zoo”,无需自己训练: - PyTorch: torchvision.models - HuggingFace: timm (pytorch-image-models)


八、超参数选择

8.1 调参流程

步骤 操作 说明
Step 1 检查初始损失 关闭正则化 → 损失应与随机猜测一致
Step 2 在小样本上过拟合 取少量数据 → 损失应能到 0,验证架构正确
Step 3 找能使 loss 下降的 LR 用全部数据,弱正则化,尝试 LR ∈ {1e-1, 1e-2, 1e-3, 1e-4, 1e-5}
Step 4 粗网格搜索,训练 1-5 epoch 缩小 LR 范围
Step 5 细化网格,训练更久
Step 6 观察 loss/accuracy 曲线 诊断过拟合/欠拟合
Step 7 回到 Step 5 迭代

8.2 诊断曲线

现象 诊断 对策
验证准确率仍在上升 训练还不够久 延长训练
训练和验证差距巨大 过拟合 增加正则化 / 收集更多数据
训练和验证几乎无差距 欠拟合 训练更长 / 使用更大模型

8.3 随机搜索 vs 网格搜索

Random Search ≫ Grid Search

当某些超参数对性能几乎无影响时,网格搜索会在不重要维度上浪费大量实验。随机搜索在每个重要维度上都能探索更多不同值。


$\large\star$ 九、总结

类别 总结
CNN 组件 Conv → Norm → ReLU 是标准配置;Dropout 偶尔使用
激活函数 ReLU 是简单有效的默认选择;GELU 在现代 Transformer 中更常见
经典架构 VGG:小滤波器加深网络;ResNet:残差连接使 152 层训练成为可能
权重初始化 Kaiming 初始化保证各层激活值分布稳定:$std = \sqrt{2/D_{in}}$
数据预处理 逐通道减均值除标准差
数据增强 翻转、裁剪、颜色抖动、Cutout → 训练加噪,测试平均
迁移学习 没有大数据 → 用 ImageNet 预训练模型微调
超参数 先过拟合小样本 → 粗搜索LR → 观曲线诊断 → 随机搜索更高效

下一讲:CS231n(柒)——循环神经网络