CNN 全面详解(含计算过程与图示)
目标:写给未来的自己,每次回看都能 从概念→公式→实现→调参 一条龙回忆起来。
- ✅ 公式与详细计算过程(输出尺寸、参数量、FLOPs、感受野)
- ✅ ASCII/mermaid 图示(卷积滑窗、网络结构、残差块)
- ✅ PyTorch 代码(可直接跑:模型、训练、评估、形状追踪)
- ✅ 经典 CNN 架构清单(LeNet、AlexNet、VGG、ResNet)
- ✅ 常见坑与调参 checklist
1. 卷积到底在做什么?(直觉 + 数学)
1.1 直觉
- 卷积核(filter/kernel)像一个可学习的模板,在图像上滑动,计算局部“相似度”,输出 特征图(feature map)。
- 两个关键理念:局部连接(只看小窗口)+ 参数共享(同一核在全图复用)。
1.2 符号与公式(二维卷积)
给定输入张量 (X\in\mathbb{R}^{H\times W\times C_{in}}),卷积核 (W\in\mathbb{R}^{k\times k\times C_{in}\times C_{out}}),步幅 (S),填充 (P):
- 输出空间尺寸(无空洞/dilation=1):
- 参数量:
- 一次前向的乘加 FLOPs(近似):
空洞卷积(dilation=d)时的等效核大小:(k_{eff}=k+(k-1)(d-1))。把上式的 (k) 换成 (k_{eff})。
1.3 数值例子:5×5 输入 ⨉ 3×3 卷积核
输入(单通道)(X) 与卷积核 (K):
1 | X = 5x5 |
设 (S=1, P=0)。输出尺寸:(H_{out}=W_{out}=\lfloor(5-3)/1\rfloor+1=3)。
左上角位置 (0,0) 的输出 y[0,0] 计算:
同理可算出 3×3 输出:
1 | y ≈ |
(因为该核检测“竖直边缘”,此示例是等差矩阵,响应相同。)
多通道输入时:先对每个通道做相同核尺寸的互相关(cross-correlation),再对通道求和,再加偏置,得到一个输出通道;重复 (C_{out}) 个核得到全部输出通道。
2. 形状/参数/感受野/计算量 —— 一次搞懂
2.1 输出形状速算表
| 层 | 公式 | 备注 |
|---|---|---|
| Conv2d(k,S,P) | (H’ = \lfloor (H+2P-k)/S\rfloor+1) | 宽同理;dilation 用 (k_{eff}) 替换 |
| MaxPool2d(k,S) | (H’ = \lfloor (H - k)/S\rfloor+1) | 宽同理;常用 k=2,S=2 |
| UpSample(×2) | (H’ = 2H) | 语义分割上采样常用 |
2.2 参数量 & MACs 速算
- Conv 参数 = (k^2 C_{in} C_{out} + C_{out})。
- Conv MACs = (H’W’ C_{out} (k^2 C_{in}))。
- FC 参数 = 输入维度 × 输出维度 + 输出偏置。
粗略显存估算(激活占主):(\sim\sum_l B\cdot H_l W_l C_l \cdot 4) bytes(float32),双向回传约×2。
2.3 感受野(Receptive Field)递推
设第 (l) 层核大小 (k_l)、步幅 (s_l),定义:
- 有效步距(jump)(j_l = j_{l-1}\cdot s_l),初始 (j_0=1)
- 感受野 (r_l = r_{l-1} + (k_l-1)\cdot j_{l-1}),初始 (r_0=1)
例:Conv3×3(s=1) → Pool2×2(s=2) → Conv3×3(s=1)
- 层1:(r_1=1+(3-1)\cdot1=3),(j_1=1)
- 层2:(r_2=3+(2-1)\cdot1=4),(j_2=1\cdot2=2)
- 层3:(r_3=4+(3-1)\cdot2=8),(j_3=2)
解释:第3层的一个像素,看到输入图的 8×8 区域。
ASCII 感受野示意:
1 | Input (· 为像素) |
3. 反向传播(轻量推导备忘)
3.1 卷积层梯度
- 设损失对输出梯度为 (\delta=\partial L/\partial Y)。
- 对权重:(\partial L/\partial W = X \star \delta)(与前向相同“互相关”形式,对 batch 与空间求和)。
- 对输入:(\partial L/\partial X = \delta * \text{rot180}(W))(* 为卷积,核旋转180°,并考虑 stride/pad 对齐)。
3.2 ReLU / Pooling
- ReLU:(\frac{\partial L}{\partial x}=\mathbf{1}[x>0]\cdot\frac{\partial L}{\partial y})。
- MaxPool:把前向位置的 argmax mask 传回,非最大位置梯度为0;AvgPool 把梯度 均分 回窗口内每个元素。
3.3 BatchNorm(2d)(推导要点)
- 以通道维做均值/方差:(\hat{x}=(x-\mu)/\sqrt{\sigma^2+\epsilon}),(y=\gamma\hat{x}+\beta)。
- 梯度:(\partial L/\partial \gamma=\sum(\delta\cdot\hat{x})),(\partial L/\partial \beta=\sum\delta)。对 (x) 的梯度需链式法则展开(略)。
3.4 Softmax + CrossEntropy(数值稳定)
- (p_i=\frac{e^{z_i}}{\sum_j e^{z_j}}),(L= -\sum_i y_i\log p_i)。
- 经典结果:(\partial L/\partial z = p - y)(避免手写 Softmax + Log 的梯度细节,框架已实现)。
4. 经典网络结构与图示
4.1 结构速览(Mermaid 可选,Hexo 需装 mermaid 插件)
graph LR I[Input HxWxC] --> C1[Conv3x3 + ReLU] C1 --> P1[MaxPool2x2] P1 --> C2[Conv3x3 + ReLU] C2 --> P2[MaxPool2x2] P2 --> F[Flatten] F --> FC1[FC 128 + ReLU] FC1 --> FC2[FC num_classes] FC2 --> SM[Softmax]
4.2 残差块(ResNet Basic Block)
graph LR x((x)) --> A[Conv3x3 + BN + ReLU] A --> B[Conv3x3 + BN] x -->|identity/1x1| add((+)) B --> add add --> relu[ReLU]
4.3 ASCII 版(不依赖 mermaid)
1 | Input -> [Conv3x3]->[ReLU]->[Pool2x2]->[Conv3x3]->[ReLU]->[Pool2x2]->[Flatten]->[FC]->[Softmax] |
4.4 LeNet / AlexNet / VGG / ResNet(形状追踪示例)
以 VGG-16 为例(输入 224×224×3):
- Block1: Conv3×3@64 → Conv3×3@64 → MaxPool2×2 → (112×112×64)
- Block2: Conv3×3@128 → Conv3×3@128 → MaxPool2×2 → (56×56×128)
- Block3: Conv3×3@256 ×3 → MaxPool2×2 → (28×28×256)
- Block4: Conv3×3@512 ×3 → MaxPool2×2 → (14×14×512)
- Block5: Conv3×3@512 ×3 → MaxPool2×2 → (7×7×512)
- Flatten → FC4096 → FC4096 → FC1000 → Softmax
形状变化靠 输出公式 一步步核对即可;感受野可用第 2.3 节递推。
5. PyTorch 实战:可直接运行的最小 CNN(含形状追踪)
环境:Python 3.8+,PyTorch,torchvision。若无 GPU 也可在 CPU 跑 MNIST。
1 | import torch |
6. 典型计算题(带完整过程)
题 1:输出尺寸与参数量
已知:输入 224×224×3;Conv7×7@64,S=2,P=3;后接 MaxPool3×3,S=2。
- Conv 输出:(H’ = \lfloor(224+2\cdot3-7)/2\rfloor+1 = 112),同理 (W’=112),通道 64 → 112×112×64。
- Conv 参数:(7\cdot7\cdot3\cdot64 + 64 = 9{,}472)。
- Pool 输出:(H’’ = \lfloor(112-3)/2\rfloor+1 = 55)(若 P=0),→ 55×55×64。
题 2:感受野
堆叠:Conv3×3(s=1) → Conv3×3(s=1) → Pool2×2(s=2) → Conv3×3(s=1)
- 递推((r_0=1, j_0=1)):
- L1:(r_1=1+(3-1)\cdot1=3,\ j_1=1)
- L2:(r_2=3+(3-1)\cdot1=5,\ j_2=1)
- L3:(r_3=5+(2-1)\cdot1=6,\ j_3=2)
- L4:(r_4=6+(3-1)\cdot2=10,\ j_4=2)
→ 第4层每个像素看输入 10×10 区域。
题 3:FLOPs 估算
输入 56×56×64,Conv3×3@128,S=1,P=1 → 输出 56×56×128。
- MACs = (56\cdot56\cdot128\cdot(3\cdot3\cdot64)) ≈ 231M;FLOPs ≈ 462M。
7. 常见坑与调参清单
- 形状对不上:逐层用输出公式核对;在 PyTorch 里加 shape hook(上文提供)。
- 数值爆炸/梯度消失:用 ReLU/LeakyReLU、BatchNorm;学习率热身 + 余弦退火;权重衰减。
- 过拟合:数据增强(翻转、裁剪、颜色抖动)、Dropout、Weight Decay、早停。
- 训练慢:用更大的 batch(显存允许)、混合精度(
torch.cuda.amp)、少用过大的 k/通道数。 - 内存不够:减小分辨率/批大小;检查中间激活是否被意外保存;
with torch.no_grad()包裹评估。 - 检测/分割任务:单阶段(YOLO/SSD)vs 两阶段(Faster R-CNN);分割常用 FCN/U-Net/DeepLab(空洞卷积、ASPP)。
8. 附录:可复制图示(Markdown/ASCII)
8.1 卷积滑窗(3×3, stride=1)
1 | ┌────────────── 5x5 输入 ──────────────┐ |
8.2 VGG Block(ASCII)
1 | [Input] -> Conv3x3 -> ReLU -> Conv3x3 -> ReLU -> MaxPool2x2 |
8.3 ResNet 残差(ASCII)
1 | x ── Conv3x3 ─ BN ─ ReLU ─ Conv3x3 ─ BN ──▶ (+) ─ ReLU |
使用建议:
- Hexo 若需渲染公式,请启用
hexo-math或katex插件;- Mermaid 图需安装
hexo-filter-mermaid-diagrams或同类插件;- 若不装插件,本文已提供 ASCII 备选图 与完整公式文本,不影响阅读。

