← 全部章节

P29 · 第 29 讲

卷积神经网络

55:40

本章目录(9 节)
  1. 1. 这一讲解决什么问题
  2. 2. 机制一:感受野——每个神经元只看一小块
  3. 3. 机制二:参数共享——同一组权重扫过整张图
  4. 4. 机制三:pooling——把局部统计聚合
  5. 5. 为什么可以这样砍:归纳偏置与适用边界
  6. 6. 伪代码与形状
  7. 7. 常见误区
  8. 8. 自测(先自己想,再展开)
  9. 9. 30 秒速记

课程版本:李宏毅《機器學習 2021》spring,CNN 讲(2021-03-12) 官方讲义:cnn_v4.pdf,35 页 — https://speech.ee.ntu.edu.tw/~hylee/ml/ml2021-course-data/cnn_v4.pdf 分P:BV1ou411N7X3?p=29,55:40 来源边界:B 站匿名 API 无字幕(subtitle.list=[]、need_login_subtitle=true),YouTube 官方源也没有 captionTracks。因此本文不引用逐字台词、不标注分钟时间戳;范围是 cnn_v4.pdf 全部 35 个物理页的页内标题与图示,加上明确标注的【补充】。本讲是单支完整 CNN 课,不涉及上下讲切分。


1. 这一讲解决什么问题

把一张 100×100 的彩色图拉平,是 30000 维向量;接一个 1000 类输出层,光这一层就是 \(30000\times1000+1000=3.0\times10^7\) 个参数(讲义 p4 写 \(3\times10^7\))。参数多本身不是致命问题,致命的是图像的两个先验完全没被用上:

  1. pattern 比整张图小。识别鸟不必先看全图,可以先找鸟嘴、眼睛、翅膀(p5–p7)。所以一个神经元不需要连到全部 30000 个像素,只看一个小窗口就够。
  2. 同一个 pattern 会出现在不同位置。鸟嘴可能在左上也可能在右下(p11)。如果每个位置都训一个"鸟嘴检测器",既浪费参数,也学不到"位置无关"这件事。
  3. 下采样不改变物体是什么。把图缩小一半,还是鸟(p27)。所以局部统计可以聚合,不必保留每个像素。

CNN 就是把这三点分别写成:感受野(receptive field)、参数共享(parameter sharing)、池化(pooling)。讲义 p16 用一句话概括代价:卷积层相对于全连接层是 "Larger model bias (for image)",也就是人为收窄了假设空间——在图像上这是好事,换成别的任务就未必。


2. 机制一:感受野——每个神经元只看一小块

对一个 3 通道输入,一个神经元的感受野取 \(3\times3\times3\):3×3 的空间窗口,深度等于输入通道数。它连到 27 个输入值,加 1 个 bias,共 28 个参数(p8;本文用 Python 复核:\(3\cdot3\cdot3+1=28\))。

典型设置(p10):

输出边长由同一个式子决定:

$$ H_{\text{out}}=\left\lfloor \frac{H+2P-K}{S}\right\rfloor+1 $$

代入本讲几个具体数(Python 计算):\(H=100,K=3,P=1,S=1\Rightarrow100\);\(H=100,K=3,P=0,S=2\Rightarrow49\)(不是 50,因为最后剩 1 行不够一个窗口);\(H=6,K=3,P=0,S=1\Rightarrow4\)——正好是 p19 特征图的 4×4。

注意"感受野变大"不等于"核必须变大":两层 3×3、stride 1 的堆叠,第二层一个神经元的有效感受野是 5×5,而参数是 \(2\times9C^2=18C^2\),比一层 5×5 的 \(25C^2\) 少。这是"用小核堆深"的标准理由,属于【补充】,讲义没有展开。


3. 机制二:参数共享——同一组权重扫过整张图

p12–p15 的推理很干净:如果两个神经元在不同位置、但做的是同一件事(找鸟嘴),那就让它们共用同一组权重和 bias。这样"检测器"只有一个,位置变了参数不变。

于是可以换一个叙事(p17–p20):不再讲"每个位置一组神经元",而讲"一个 filter 在整张图上滑动"。两个故事是同一件事(p24–p26 明确写 "They are the same story"):

神经元版本 filter 版本
每个神经元只看一个感受野 每个 filter 检测一个小 pattern
不同感受野的神经元共享参数 每个 filter 卷积扫过整张图

输出通道数 = filter 个数;每个 filter 的深度 = 输入通道数。所以 64 个 3×3×3 的 filter,参数量是 \(64\times(3\cdot3\cdot3)+64=1792\)(Python 复核),而不是三千万。

玩具数值例(与讲义 p19/p20 逐格对齐)

讲义 p18 给了一张 6×6 二值图和两个 3×3 filter:

图像 X =             Filter 1 =        Filter 2 =
1 0 0 0 0 1          1 -1 -1           -1  1 -1
0 1 0 0 1 0         -1  1 -1           -1  1 -1
0 0 1 1 0 0         -1 -1  1           -1  1 -1
1 0 0 0 1 0
0 1 0 0 1 0
0 0 1 0 1 0

stride=1、无 padding,用 Python 做 4×4 次乘加,得到

$$ X*F_1=\begin{bmatrix} 3&-1&-3&-1\\ -3&1&0&-3\\ -3&-3&0&1\\ 3&-2&-2&-1 \end{bmatrix},\qquad X*F_2=\begin{bmatrix} -1&-1&-1&-1\\ -1&-1&-2&1\\ -1&-1&-2&1\\ -1&0&-4&3 \end{bmatrix} $$

两式与讲义 p19、p20 的数字逐项相同(脚本里 matches_slide_p19=True、matches_slide_p20=True)。这说明卷积不是"差不多"的比喻:左上角 \(3\) 就是 \(1\cdot1+0\cdot(-1)+\cdots+0\cdot1\) 算出来的。

平移等变【术语补充】

讲义 p11 说的是"同一 pattern 出现在不同区域",没有用"等变"这个词。用术语讲:卷积对平移是**等变(equivariant)**的——输入平移 \(k\) 格,特征图也平移 \(k\) 格,数值不变。原因是同一个 filter 在所有位置用同一组权重。等变不是不变:特征图仍然记得位置,只是跟着一起移。真正把位置信息抹掉的是后面的 pooling 或全局池化。


4. 机制三:pooling——把局部统计聚合

p27 的观察是"subsampling the pixels will not change the object"。p28–p29 用 max pooling 实现:每个 2×2 窗口取最大值,窗口不重叠、无参数。

拿上面 \(X*F_1\) 的 4×4 特征图做 2×2 max pooling(Python 计算):

$$ \begin{bmatrix}3&-1\\-3&1\end{bmatrix}\to 3,\quad \begin{bmatrix}-3&-1\\0&-3\end{bmatrix}\to 0,\quad \begin{bmatrix}-3&-3\\3&-2\end{bmatrix}\to 3,\quad \begin{bmatrix}0&1\\-2&-1\end{bmatrix}\to 1 $$

结果 \(\begin{bmatrix}3&0\\3&1\end{bmatrix}\),与 p29 的 pooling 输出一致。

这里必须精确一点:pooling 给的是局部近似不变,不是严格不变。窗口内平移一两格,max 可能不变;平移超过窗口,输出就变了。讲义 p27 的 "will not change the object" 是任务层面的说法,不是数学定理。

整网结构(p30):Convolution → Pooling → Convolution → Pooling → Flatten → Fully Connected → Softmax。


5. 为什么可以这样砍:归纳偏置与适用边界

卷积层用两个假设换来了参数量的骤降:

这两个假设在图像上成立,所以 p16 说这是"for image"的 bias。换到 Go(p31–p33):19×19 棋盘看成 19×19×48 的输入,AlphaGo 第一层用 5×5,没有用 pooling——因为落子位置的全局关系重要,pooling 的"下采样不变"假设不成立(p33 直接写 "Alpha Go does not use Pooling …… How to explain this???")。这是讲义自己留下的开放问题,也提醒我们:CNN 的三件套不是必须捆绑。

边界还有一条(p35):CNN 对缩放和旋转不等变。把鸟放大或转 30°,同样的 filter 未必响应。讲义给的解法是 data augmentation,或引入 Spatial Transformer Layer。这句话很重要,它防止我们把"卷积=视觉万能"当成结论。


6. 伪代码与形状

# x: [C_in, H, W]   W: [C_out, C_in, K, K]   b: [C_out]
for f in range(C_out):
    for i in range(H_out):
        for j in range(W_out):
            s = b[f]
            for c in range(C_in):
                for ki in range(K):
                    for kj in range(K):
                        s += W[f, c, ki, kj] * x[c, i*S + ki - P, j*S + kj - P]
            y[f, i, j] = s

7. 常见误区

  1. "卷积是平移不变"——是平移等变。不变性要靠 pooling/global average pooling 才近似得到。
  2. "参数共享=所有神经元权重一样"——只有同一个 filter 在空间上共享;不同 filter 的参数不同,否则 64 个 filter 就等于 1 个。
  3. "pooling 是 CNN 必需"——AlphaGo 不用(p33);现代网络也常用 stride>1 的卷积代替 pooling。它是归纳偏置,不是定义。
  4. "输出尺寸直接除 stride"——\(100/2=50\),但 \(K=3,S=2,P=0\) 的实际输出是 49。边界不整除时要取下整。
  5. "核越大越好"——大核参数平方增长;两层 3×3 能得到 5×5 感受野且参数更少。

8. 自测(先自己想,再展开)

Q1. 输入 32×32×3,用 16 个 5×5 的 filter,stride=1,padding=2,输出 shape 和参数量各是多少?

答案

输出边长 \((32+4-5)/1+1=32\),shape 为 16×32×32。每个 filter 有 \(5\cdot5\cdot3=75\) 个权重加 1 个 bias,16 个共 \(16\times76=1216\) 个参数。注意输出通道数由 filter 个数决定,与输入通道数无关。

Q2. 为什么 p19 的特征图是 4×4,而不是 6×6?

答案

因为 3×3 的窗口在 6×6 图上以 stride=1 滑动,横向可放的位置是 \(6-3+1=4\) 个,纵向同理,所以是 4×4。每个输出值对应一个完整的 3×3 窗口,边界像素无法作为窗口中心,因而没有被单独覆盖。

Q3. 如果把 p18 的 filter 换成它的转置(或旋转 180°),特征图会怎样?这说明卷积的什么性质?

答案

数值会变(相当于检测相反方向的pattern),但仍然是同一组权重扫过全图,平移等变性不变。深度学习里的"卷积"实际是互相关(不翻转核),翻转与否只影响学到的核长什么样,不影响参数共享与等变性质。

Q4. 一个任务里"同一个物体可能出现在任意位置,且尺寸固定、方向固定",CNN 的哪些假设匹配、哪些不匹配?

答案

匹配:局部性、平移共享(位置任意);不匹配:缩放/旋转不变性——讲义 p35 明确说 CNN 对 scaling/rotation 不等变,需要数据增强或 Spatial Transformer。若尺寸变化很大,固定 kernel 的感受野也不够,需要多尺度或金字塔结构。


9. 30 秒速记

图像太大 → 全连接参数 \(3\times10^7\)。两个观察:pattern 比图小 → 感受野;同一 pattern 到处出现 → 参数共享(= filter 滑窗)。第三个观察:下采样不改变物体 → pooling。三件套把参数压到 1792,代价是引入图像专用的强 bias;因此 CNN 对缩放/旋转不等变,也不是所有任务都该用 pooling(AlphaGo 就不用)。

跨 P 连接:P36/P37 会把"CNN 是在一个感受野内做 attention"讲成 self-attention 的特例——那时回看 p16 的 "model bias" 会更清楚:CNN 是把手写的邻域先验塞进 attention,Transformer 则把这个先验交还给数据和位置编码。P38 的 RNN 提供另一种"看上下文"的方式(串行、带记忆),P47/P48 的 Transformer 则用 self-attention 同时解决并行与长距离。


引用页(PDF 物理页,1 起)

p4(参数量)、p7–p8(观察一与感受野 28 参数)、p10(kernel/stride/padding/64 neurons)、p11–p15(观察二与参数共享)、p16(model bias)、p17–p20(filter 叙事与 6×6 数值例)、p24–p26(两个故事等价)、p27–p30(pooling 与整网)、p31–p33(Go,无 pooling)、p35(缩放/旋转边界)。

来源与说明

基于对应官方讲义整理,未取到完整视频字幕;不冒充逐字稿。