CNN 为什么适合图像?
输出尺寸和参数量怎么算?
先弄清楚:每个概念是什么
- Convolution
- kernel 在图上滑,每个位置和底下的像素对应相乘再求和。库里不翻转 kernel,严格说是 cross-correlation。例:输入 0, 0, 1, 1,kernel (−1, 1) → 0, 1, 0,只在明暗交界处亮(edge detector)。
- Local connectivity 与 parameter sharing
- 每个输出只看 k×k 的一小块,同一个 kernel 在所有位置复用,所以参数量和图片大小无关。例:32×32×3 → 32×32×16,FC 要约 5000 万个 weight,3×3 conv 只要 448 个参数。
- Stride 与 padding
- Stride 是每次挪几格,stride 2 让边长约减半;padding 是四周补 0,让边缘也被扫到。
- Pooling
- 每个小窗口只留一个数(max 或 average),尺寸变小,没有参数。
- Equivariance 与 invariance
- 输入平移,conv 的 feature map 跟着平移(equivariance)。再 pooling,小的平移基本不改变输出(invariance)。
30 秒回答
Images have local structure, and the same pattern can appear anywhere. Conv layers exploit this with local connectivity, where each output sees only a k-by-k window, and parameter sharing, where one kernel slides over every position. So a layer has (k²·C_in + 1)·C_out parameters regardless of image size, and it's translation equivariant; pooling adds invariance to small shifts. The output size is floor((n + 2p − k)/s) + 1. Architectures went from AlexNet to VGG's stacked 3×3 convs, Inception's 1×1 bottlenecks, ResNet's residual connections, MobileNet's depthwise separable convs, and ViT, a Transformer on image patches.
关键公式
\(n\) 输入边长,\(k\) kernel 大小,\(p\) 每边 padding,\(s\) stride;stride 1 时 \(p = (k-1)/2\) 尺寸不变。
\[ \text{params} = (k^2 C_{\text{in}} + 1)\, C_{\text{out}} \]每个输出 channel 一个 \(C_{\text{in}}\times k\times k\) 的 kernel 加一个 bias,和 \(n\) 无关。
手算例子
输入 32×32×3,尺寸按公式逐层往下推:
| 层 | 设置 | 输出尺寸 | 参数量 |
|---|---|---|---|
| conv1 | 16 个 5×5,s = 1,p = 0 | (32 − 5)/1 + 1 = 28 → 28×28×16 | (5·5·3 + 1)·16 = 1216 |
| max pool | 2×2,s = 2 | (28 − 2)/2 + 1 = 14 → 14×14×16 | 0 |
| conv2 | 32 个 3×3,s = 2,p = 1 | ⌊13/2⌋ + 1 = 7 → 7×7×32 | (3·3·16 + 1)·32 = 4640 |
| FC | 1568 → 10 类 | 10 | (1568 + 1)·10 = 15690 |
共 21,546 个参数,最后的 FC 占七成多。AlexNet 的 60M 参数也主要在 FC 层。
经典架构
| 架构 | 关键点 |
|---|---|
| AlexNet(2012) | 比 LeNet 深,ReLU、dropout、GPU;ImageNet top-5 error 26% → 15% |
| VGG | 全用 3×3 conv 堆叠 |
| Inception | 一个 block 并行跑多种 kernel 再拼接,先用 1×1 conv 降 channel |
| ResNet | residual connection \(x_{l+1} = \varphi(x_l + F(x_l))\),训到 152 层(为什么) |
| MobileNet | depthwise separable conv,3×3 时计算量少 8–9 倍 |
| ViT | 图片切 patch 当 token 进 Transformer;没有 CNN 的 inductive bias,在 14M–300M 张图上 pre-train 才追平或超过 |
必答点
- local connectivity + parameter sharing → 参数少,与图片大小无关
- conv 是 translation equivariant;pooling 带来对小平移的 invariance
- 输出尺寸 \(\lfloor (n+2p-k)/s \rfloor + 1\);参数量 \((k^2C_{\text{in}}+1)\,C_{\text{out}}\)
- 架构主线:AlexNet → VGG → Inception → ResNet → MobileNet → ViT
追问
VGG 为什么全用 3×3?
三个 3×3 叠起来的 receptive field 等于一个 7×7,参数 \(27C^2\) 对 \(49C^2\),中间还多了两层 ReLU(VGG §2.3)。
1×1 conv 有什么用?
相当于在每个像素上做同一个 FC,只混合 channel,参数 \(C_{\text{in}}C_{\text{out}}\)。用来改 channel 数。
一层 conv 的计算量怎么算?
每个输出元素做 \(k^2C_{\text{in}}\) 次乘加,共 \(n_{\text{out}}^2 k^2 C_{\text{in}} C_{\text{out}}\) 次(MACs),FLOPs 约是它的 2 倍。上表 conv1:\(28^2\cdot 25\cdot 3\cdot 16 = 940{,}800\)。
来源Goodfellow et al. §9.1–9.3(pp.329–339)· d2l §7.3 eq. 7.3.2 · Murphy, PML1 §14.2.1(pp.468–474)、§14.3(pp.479–484)、§13.4.4(p.451)· VGG §2.3 · MobileNets §3.1 · ViT §1