(cnn-ablation-experiment)=
# 实验设计

{doc}`introduction`中我们介绍了消融研究的基本思想：通过控制变量法，逐一移除或修改模型组件，量化每个组件对性能的贡献。本节我们将**设计具体的消融实验**，包括基线模型构建、实验方案规划和评估指标选择。

```{admonition} 重要提示
:class: warning

本章中的实验数据（准确率、参数量、训练时间等）均为**示例数据**，用于演示消融研究的方法论。

**你的实际实验结果可能不同**，这取决于：
- 随机种子
- 硬件环境（CPU/GPU）
- PyTorch版本
- 数据加载顺序

**建议**：将本章作为**实验设计指南**，自己动手复现每个实验，获得属于你自己的真实数据。
```

## 基线模型

我们设计一个简单的CNN作为基线模型，用于CIFAR-10图像分类任务。CIFAR-10包含10个类别的32×32彩色图像，适合快速实验。

```{tikz} 基线CNN架构：数据流与参数量
\begin{tikzpicture}[scale=0.9]
    % 输入层
    \fill[green!20] (-3, 7) rectangle (3, 8);
    \draw[thick] (-3, 7) rectangle (3, 8);
    \node at (0, 7.5) {输入：32×32×3};
    \node[right] at (3.8, 7.5) {\scriptsize 原始图像};
    
    % Conv1层
    \fill[blue!20] (-3, 5.5) rectangle (3, 6.5);
    \draw[thick] (-3, 5.5) rectangle (3, 6.5);
    \node at (0, 6) {Conv1：32×32×32};
    \node[right] at (3.8, 6) {\scriptsize 3→32, 896参数};
    \draw[->, thick] (0, 7) -- (0, 6.5);
    
    % Pool1层
    \fill[cyan!20] (-2.5, 4) rectangle (2.5, 5);
    \draw[thick] (-2.5, 4) rectangle (2.5, 5);
    \node at (0, 4.5) {Pool1：16×16×32};
    \node[right] at (3.8, 4.5) {\scriptsize 2×2 MaxPool};
    \draw[->, thick] (0, 5.5) -- (0, 5);
    
    % Conv2层
    \fill[blue!30] (-2.5, 2.5) rectangle (2.5, 3.5);
    \draw[thick] (-2.5, 2.5) rectangle (2.5, 3.5);
    \node at (0, 3) {Conv2：16×16×64};
    \node[right] at (3.8, 3) {\scriptsize 32→64, 18,496参数};
    \draw[->, thick] (0, 4) -- (0, 3.5);
    
    % Pool2层
    \fill[cyan!30] (-2, 1) rectangle (2, 2);
    \draw[thick] (-2, 1) rectangle (2, 2);
    \node at (0, 1.5) {Pool2：8×8×64};
    \node[right] at (3.8, 1.5) {\scriptsize 2×2 MaxPool};
    \draw[->, thick] (0, 2.5) -- (0, 2);
    
    % Flatten层
    \fill[orange!20] (-2, -0.5) rectangle (2, 0.5);
    \draw[thick] (-2, -0.5) rectangle (2, 0.5);
    \node at (0, 0) {Flatten：4,096};
    \node[right] at (3.8, 0) {\scriptsize 64×8×8};
    \draw[->, thick] (0, 1) -- (0, 0.5);
    
    % FC1层
    \fill[red!20] (-1.5, -2) rectangle (1.5, -1);
    \draw[thick] (-1.5, -2) rectangle (1.5, -1);
    \node at (0, -1.5) {FC1：512};
    \node[right] at (3.8, -1.5) {\scriptsize 4,096→512, 2.1M参数};
    \draw[->, thick] (0, -0.5) -- (0, -1);
    
    % FC2层
    \fill[red!30] (-1.5, -3.5) rectangle (1.5, -2.5);
    \draw[thick] (-1.5, -3.5) rectangle (1.5, -2.5);
    \node at (0, -3) {FC2：10};
    \node[right] at (3.8, -3) {\scriptsize 512→10, 5,130参数};
    \draw[->, thick] (0, -2) -- (0, -2.5);
    
    % 输出
    \node at (0, -4.2) {输出：10类};
    \draw[->, thick] (0, -3.5) -- (0, -3.8);
    
    % 标注
    \draw[<->, gray, thick] (-4.5, 7) -- (-4.5, 8);
    \node[left, gray, font=\scriptsize] at (-4.5, 7.5) {空间维度};
\end{tikzpicture}
```

### 参数量计算

理解参数量对消融研究至关重要——我们需要知道**移除某个组件节省了多少参数**。

**逐层计算**：

| 层 | 计算公式 | 参数量 | 占比 |
|---|---------|--------|------|
| Conv1 | $(3 \times 3 \times 3 + 1) \times 32$ | 896 | 0.07% |
| Conv2 | $(3 \times 3 \times 32 + 1) \times 64$ | 18,496 | 1.5% |
| FC1 | $(4,096 + 1) \times 512$ | 2,097,664 | **85.4%** |
| FC2 | $(512 + 1) \times 10$ | 5,130 | 0.2% |
| **总计** | - | **2,122,186** | 100% |

**关键发现**：
- 卷积层参数量很小（仅占 1.6%），但承担了主要的**特征提取**任务
- 全连接层占绝大部分参数（85%+），主要用于**分类决策**
- 这也是为什么我们可以放心地冻结卷积层进行迁移学习——特征提取器本身很轻量

### 消融研究流程

```{mermaid}
flowchart TD
    A[基线模型<br/>准确率: 78.3%] --> B{实验1: 移除组件?}
    B -->|移除卷积层| C[模型A: 1层卷积<br/>准确率: 65.7%]
    B -->|移除池化层| D[模型B: 无池化<br/>准确率: 72.1%]
    B -->|更换激活函数| E[模型C: Sigmoid<br/>准确率: 62.7%]
    B -->|移除BN| F[模型D: 无BN<br/>准确率: 78.3%]
    B -->|移除Dropout| G[模型E: 无Dropout<br/>准确率: 78.3%]
    
    C --> H[分析: 卷积层<br/>贡献 +12.6%]
    D --> I[分析: 池化层<br/>贡献 +6.2%]
    E --> J[分析: ReLU<br/>贡献 +15.6%]
    F --> K[分析: BN<br/>加速收敛]
    G --> L[分析: Dropout<br/>防止过拟合]
```

**流程说明**：
1. **建立基线**：先跑通完整模型，记录性能
2. **逐一消融**：每次只修改一个组件，保持其他不变
3. **对比分析**：计算性能变化，评估组件重要性

## 消融实验设计

我们将进行以下消融实验：

1. **实验1**：移除卷积层（减少特征提取能力）
2. **实验2**：移除池化层（保持空间分辨率）
3. **实验3**：更换激活函数（Sigmoid/Tanh vs ReLU）
4. **实验4**：移除批归一化（训练稳定性）
5. **实验5**：移除Dropout（过拟合风险）
6. **实验6**：改变卷积核大小（1×1, 3×3, 5×5）
7. **实验7**：改变池化类型（最大池化 vs 平均池化）

每个实验保持其他组件不变，仅修改目标组件，在相同训练条件下比较性能。

## 评估指标

- **准确率**：测试集上的分类准确率
- **损失曲线**：训练和验证损失的变化
- **收敛速度**：达到特定准确率所需的epoch数
- **模型大小**：参数数量和计算量（FLOPs）
- **训练时间**：每个epoch的平均训练时间

## 消融实验结果（示例数据）

### 实验1：卷积层的影响

我们通过减少卷积层数量来研究卷积层的作用：

```{admonition} 实验设置
:class: tip

- **模型A**：基线模型（2个卷积层）
- **模型B**：仅1个卷积层（移除conv2）
- **模型C**：3个卷积层（增加conv3）
```

| 模型 | 测试准确率 | 参数量 | 训练时间/epoch | 收敛epoch |
|------|------------|--------|----------------|-----------|
| 基线（2层） | 78.3% | 1.2M | 45s | 15 |
| 1层卷积 | 65.7% | 0.8M | 38s | 20 |
| 3层卷积 | 79.1% | 1.8M | 52s | 12 |

```{admonition} 分析
:class: important

- **层数不足**：1层卷积无法提取足够特征，准确率下降12.6%
- 参见 {doc}`../neural-network-basics/cnn-basics` 中特征提取层次分析
- **层数增加**：3层卷积略有提升，但参数量和计算量增加
- **边际收益递减**：超过2层后提升有限，可能出现过拟合
```

### 实验2：池化层的影响

池化层的作用是降低空间分辨率，增加平移不变性。参见 {doc}`../neural-network-basics/cnn-basics` 中池化操作详解。

| 池化类型 | 测试准确率 | 特征图尺寸 | 参数量 | 过拟合程度 |
|----------|------------|------------|--------|------------|
| 最大池化（基线） | 78.3% | 8×8 | 1.2M | 中等 |
| 平均池化 | 77.8% | 8×8 | 1.2M | 中等 |
| 步长卷积（无池化） | 76.5% | 16×16 | 1.5M | 高 |
| 无池化（保持尺寸） | 72.1% | 32×32 | 4.8M | 很高 |

```{admonition} 池化的作用
:class: tip

- **降维**：减少计算量和参数量，参见参数量计算表
- **平移不变性**：对输入的小平移具有鲁棒性
- **防止过拟合**：减少空间细节，增强泛化能力
- **最大 vs 平均**：最大池化更关注显著特征，平均池化更平滑
```

### 实验3：激活函数的影响

激活函数引入非线性，参见 {doc}`../math-fundamentals/activation-functions` 中激活函数理论分析。

| 激活函数 | 测试准确率 | 训练速度 | 梯度问题 | 死亡神经元 |
|----------|------------|----------|----------|------------|
| ReLU（基线） | 78.3% | 快 | 无梯度消失 | 可能 |
| Leaky ReLU | 78.5% | 快 | 无梯度消失 | 无 |
| Sigmoid | 62.7% | 慢 | 梯度消失严重 | 无 |
| Tanh | 70.4% | 中等 | 梯度消失 | 无 |
| Swish {cite}`ramachandran2017swish` | 78.8% | 中等 | 无梯度消失 | 无 |

```{admonition} 激活函数选择建议
:class: important

- **默认选择**：ReLU（简单、高效）
- **深层网络**：Leaky ReLU或Swish（避免死亡神经元）
- **避免使用**：Sigmoid（梯度消失严重），详见 {ref}`sigmoid-gradient-vanish`
```

### 实验4：批归一化的影响

批归一化（Batch Normalization）通过标准化层输入来加速训练并提高稳定性 {cite}`ioffe2015batch`。参见 {doc}`../neural-network-basics/neural-training-basics` 中批归一化原理。

| 配置 | 最终准确率 | 收敛epoch | 训练稳定性 | 学习率敏感性 |
|------|------------|-----------|------------|--------------|
| 无BN | 78.3% | 15 | 低 | 高 |
| 有BN | 81.2% | 8 | 高 | 低 |
| BN + 更大学习率 | 82.1% | 6 | 高 | 低 |

```{admonition} 批归一化的优势
:class: tip

- **加速收敛**：减少内部协变量偏移，收敛速度提高约50%
- **允许更大学习率**：训练更稳定，可以使用更大的学习率
- **轻微正则化效果**：减少对Dropout的依赖
- **改善梯度流动**：缓解梯度消失/爆炸问题
```

### 实验5：Dropout的影响

Dropout是一种正则化技术，通过在训练过程中随机丢弃神经元来防止过拟合 {cite}`srivastava2014dropout`。参见 {doc}`../neural-network-basics/neural-training-basics` 中正则化方法。

| Dropout率 | 训练准确率 | 测试准确率 | 过拟合差距 | 收敛epoch |
|-----------|------------|------------|------------|-----------|
| 0.0（无Dropout） | 95.2% | 78.3% | 16.9% | 15 |
| 0.3 | 91.8% | 79.5% | 12.3% | 16 |
| 0.5（基线） | 88.7% | 78.3% | 10.4% | 17 |
| 0.7 | 84.3% | 76.9% | 7.4% | 19 |

```{admonition} Dropout的作用与权衡
:class: important

- **正则化效果**：Dropout有效减少过拟合，训练-测试差距从16.9%降至7.4%
- **训练速度**：Dropout增加训练时间，需要更多epoch收敛
- **最佳值**：Dropout率0.3-0.5通常效果最佳
- **与BN的交互**：批归一化也有正则化效果，两者结合需谨慎
```

### 实验6：卷积核大小的影响

卷积核大小决定感受野大小，影响特征提取能力。参见 {doc}`../neural-network-basics/cnn-basics` 的 {ref}`receptive-field` 中感受野定义与计算。

| 卷积核大小 | 测试准确率 | 参数量 | 计算量（FLOPs） | 感受野 |
|------------|------------|--------|----------------|--------|
| 1×1 | 72.5% | 0.9M | 0.8G | 1×1 |
| 3×3（基线） | 78.3% | 1.2M | 1.2G | 3×3 |
| 5×5 | 79.1% | 1.8M | 2.1G | 5×5 |
| 7×7 | 78.9% | 2.5M | 3.5G | 7×7 |

```{admonition} 卷积核选择建议
:class: tip

- **小卷积核（1×1）**：用于降维和升维，减少参数量
- **中等卷积核（3×3）**：平衡感受野和计算量，最常用
- **大卷积核（5×5, 7×7）**：可用多个3×3卷积替代，减少参数量
- **现代趋势**：使用小卷积核堆叠（如VGG、ResNet）
```

### 实验7：池化类型的影响

我们进一步比较最大池化和平均池化在不同任务上的表现：

| 任务类型 | 最大池化准确率 | 平均池化准确率 | 优势类型 |
|----------|----------------|----------------|----------|
| 图像分类（CIFAR-10） | 78.3% | 77.8% | 最大池化 |
| 目标检测（边界框） | 71.2% | 72.5% | 平均池化 |
| 语义分割（像素级） | 68.7% | 70.3% | 平均池化 |
| 纹理分类 | 76.4% | 74.1% | 最大池化 |

```{admonition} 池化类型选择指南
:class: important

- **分类任务**：最大池化更关注显著特征，通常表现更好
- **定位任务**：平均池化保留更多空间信息，适合需要位置信息的任务
- **现代架构**：许多网络使用步长卷积替代池化，提供更多灵活性
- **混合使用**：某些网络在不同层使用不同类型的池化
```

## 综合分析与设计原则

### 组件重要性排序

基于消融实验结果，我们可以对CNN组件的重要性进行排序：

```{admonition} CNN组件重要性（从高到低）
:class: tip

1. **卷积层**：特征提取的核心，不可或缺
2. **激活函数**：提供非线性，ReLU类函数效果最佳
3. **批归一化**：显著加速训练，提高稳定性
4. **池化层**：降低计算量，增加平移不变性
5. **Dropout**：正则化，防止过拟合
6. **卷积核大小**：3×3是最佳平衡点
7. **池化类型**：任务依赖性较强
```

### 组件贡献可视化

```{tikz} 消融实验：组件贡献度对比
\begin{tikzpicture}[scale=0.85]
    % Y轴
    \draw[thick, ->] (0, 0) -- (0, 5.5);
    \node[rotate=90] at (-1.5, 2.75) {性能影响 (\%)};
    
    % Y轴刻度
    \foreach \y/\label in {0/0, 1/5, 2/10, 3/15, 4/20} {
        \draw (0, \y) -- (-0.2, \y);
        \node[left] at (-0.2, \y) {\small \label};
        \draw[gray, very thin] (0, \y) -- (13, \y);
    }
    
    % 柱状图数据
    \fill[blue!70] (0.5, 0) rectangle (1.5, 2.52);
    \fill[red!70] (2.2, 0) rectangle (3.2, 3.12);
    \fill[green!70] (3.9, 0) rectangle (4.9, 1.24);
    \fill[orange!70] (5.6, 0) rectangle (6.6, 0.58);
    \fill[purple!70] (7.3, 0) rectangle (8.3, 0.24);
    \fill[cyan!70] (9.0, 0) rectangle (10.0, 0.16);
    \fill[brown!70] (10.7, 0) rectangle (11.7, 0.10);
    
    % 数值标签
    \node[above, font=\small] at (1, 2.52) {12.6};
    \node[above, font=\small] at (2.7, 3.12) {15.6};
    \node[above, font=\small] at (4.4, 1.24) {6.2};
    \node[above, font=\small] at (6.1, 0.58) {2.9};
    \node[above, font=\small] at (7.8, 0.24) {1.2};
    \node[above, font=\small] at (9.5, 0.16) {0.8};
    \node[above, font=\small] at (11.2, 0.10) {0.5};

    % X轴标签和柱状图
    \def\components{{"卷积层", "激活函数", "池化层", "批归一化", "Dropout", "卷积核大小", "池化类型"}}
    \def\values{{12.6, 15.6, 6.2, 2.9, 1.2, 0.8, 0.5}}
    \def\colors{{"blue!70", "red!70", "green!70", "orange!70", "purple!70", "cyan!70", "brown!70"}}
    
    % X轴标签（旋转45度）
    \node[rotate=45, anchor=east, font=\small] at (1, -0.3) {卷积层};
    \node[rotate=45, anchor=east, font=\small] at (2.7, -0.3) {激活函数};
    \node[rotate=45, anchor=east, font=\small] at (4.4, -0.3) {池化层};
    \node[rotate=45, anchor=east, font=\small] at (6.1, -0.3) {批归一化};
    \node[rotate=45, anchor=east, font=\small] at (7.8, -0.3) {Dropout};
    \node[rotate=45, anchor=east, font=\small] at (9.5, -0.3) {卷积核大小};
    \node[rotate=45, anchor=east, font=\small] at (11.2, -0.3) {池化类型};
    
    % 说明文字
    \node[anchor=west, font=\scriptsize, text width=5cm] at (-0.5, -3) {
        \textbf{注：}数值表示移除该组件\\导致的准确率下降
    };
\end{tikzpicture}
```

**图表解读**：
- **纵轴**：移除该组件导致的准确率下降（百分比）
- **越高表示越重要**：激活函数（15.6%）和卷积层（12.6%）是核心组件
- **稳定性组件**：批归一化对准确率影响小（2.9%），但能显著加速训练

### CNN设计检查清单

基于消融研究，我们提出以下CNN设计检查清单：

```{admonition} CNN设计检查清单
:class: important

- **卷积层数**：至少2层，根据任务复杂度增加
- **激活函数**：默认使用ReLU，深层网络考虑Leaky ReLU或Swish
- **批归一化**：除非有特殊原因，否则应该使用
- **池化策略**：分类任务用最大池化，定位任务考虑平均池化
- **Dropout率**：0.3-0.5，在全连接层使用
- **卷积核大小**：默认3×3，可用多个小卷积核替代大卷积核
- **参数初始化**：使用He初始化 {cite}`he2015delving`（配合ReLU）或Xavier初始化 {cite}`glorot2010understanding`
- **学习率调度**：使用余弦退火或ReduceLROnPlateau
```

### 消融研究的最佳实践

```{admonition} 进行消融研究的最佳实践
:class: tip

1. **定义明确基线**：选择一个性能良好的模型作为基线
2. **一次只改变一个变量**：确保结果可归因于特定修改
3. **控制随机性**：使用固定随机种子，确保可重复性
4. **充分训练**：每个实验都训练到收敛，避免过早停止
5. **多指标评估**：不仅看准确率，还要看损失、收敛速度等
6. **统计显著性**：多次运行取平均，报告标准差
7. **可视化结果**：使用图表直观展示性能变化
8. **记录实验细节**：保存超参数、随机种子、环境信息
```

## 高级话题

### 现代CNN架构的消融研究

现代CNN架构（如ResNet、DenseNet、EfficientNet）引入了更多复杂组件：

| 架构 | 关键组件 | 消融研究发现 |
|------|----------|--------------|
| ResNet {cite}`he2016deep` | 残差连接 | 残差连接使训练极深网络成为可能 |
| DenseNet {cite}`huang2017densely` | 密集连接 | 特征重用显著减少参数量 |
| EfficientNet {cite}`tan2019efficientnet` | 复合缩放 | 平衡深度、宽度、分辨率效果最佳 |
| MobileNet {cite}`howard2017mobilenets` | 深度可分离卷积 | 大幅减少计算量，精度损失小 |
| Vision Transformer {cite}`dosovitskiy2020image` | 自注意力 | 在大数据集上超越CNN，小数据集不如CNN |

### 自动化消融研究

随着AutoML的发展，自动化消融研究成为可能：

```{admonition} 自动化消融研究工具
:class: tip

- **Neural Network Intelligence (NNI)**：微软开发的AutoML工具包
- **AutoGluon**：亚马逊开发的自动机器学习工具
- **Optuna**：超参数优化框架，可用于消融研究
- **Weight & Biases (W&B)**：实验跟踪和超参数调优
```

### 消融研究的局限性

```{admonition} 消融研究的局限性
:class: important

- **组件交互**：组件之间可能存在交互效应，单独移除可能低估其重要性
- **任务依赖性**：组件重要性可能因任务而异
- **数据集偏差**：结果可能依赖于特定数据集
- **计算成本**：全面的消融研究需要大量计算资源
- **局部最优**：可能只探索了设计空间的一小部分
```

## 结论

本文通过系统的消融研究，深入分析了CNN中各个组件的作用。主要发现包括：

```{admonition} 主要结论
:class: tip

1. **卷积层是CNN的核心**，至少需要2层才能有效提取特征
2. **ReLU是最实用的激活函数**，在大多数情况下表现最佳
3. **批归一化显著加速训练**，应成为标准配置
4. **池化层的作用因任务而异**，分类任务偏好最大池化，定位任务偏好平均池化
5. **Dropout有效防止过拟合**，但会减慢收敛速度
6. **3×3卷积核是最佳平衡点**，大卷积核可用多个小卷积核替代
7. **组件之间存在交互效应**，设计时需要综合考虑
```

### 实践建议

基于本文的研究结果，我们提出以下实践建议：

```{admonition} CNN设计实践建议
:class: important

- **从简单开始**：先构建一个简单的基线模型
- **逐步添加组件**：根据消融研究结果逐步优化
- **关注组件交互**：不同组件组合可能产生协同效应
- **任务导向设计**：根据具体任务特点选择组件
- **持续实验**：深度学习是实验科学，不断尝试才能找到最佳设计
```

### 未来工作

消融研究仍有许多值得探索的方向：

- **跨架构消融研究**：比较不同架构中相同组件的作用
- **跨任务消融研究**：研究组件重要性如何随任务变化
- **自动化消融研究**：开发自动化的消融研究框架
- **理论分析**：从理论角度解释消融研究结果
- **新组件评估**：评估新兴组件（如注意力机制、动态卷积等）的作用

消融研究是理解深度学习模型的重要工具，希望本文能为读者提供有价值的 insights，并激发更多深入的研究。

### 下一步

完成实验设计后，下一节{doc}`implementation`我们将动手实现这些消融实验，编写完整的PyTorch代码来训练基线模型和各个消融变体，并收集实验数据。

---

## 参考文献

```{bibliography}
:filter: docname in docnames
```
