阶段 2 · 看懂图像

感受野:一层只看 3 个像素
怎么认出整只猫

上一章《CNN 卷积神经网络》只留下一枚 3×3 的小印章, 连一只眼睛都看不全。但堆到 20 层之后,最上面一个神经元却能看到整张图。 这背后是一次「换地图」:放大镜还是同一把,换一张更粗的地图,同样的挪动就盖住更大的地方—— 这场"从局部到全局"的交换怎么发生,就是这一章要回答的。

1

感受野:一个神经元能看多大

感受野 = 某个输出位置,在原始输入上依赖的区域大小。 第一层是 3×3,第二层就是 5×5,第三层 7×7……每加一层 3×3 卷积,感受野涨 2。

先认三个词:下采样 = 把特征图缩小(常见做法:2×2 池化只留 1 个,或步长 2 的卷积每隔一格算一次); 图里的 ↓ 表示这一层做了下采样;j 是「这一层挪一格,等于原图挪几格」。

核心大图 · 亲手堆层,看感受野怎么扩张

剖面图 · 同一个神经元,对着同一条输入带,一层比一层盖得宽

第 1 层 视野 3 第 2 层 视野 5 第 3 层 视野 7 第 4 层 视野 9 同一个输出位置 输入 这张剖面图不做下采样:每层只涨 2,第 4 层是 9。上面那张表默认每 3 层下采样一次,第 4 层已经是 11。
💡 这是"深度"的第一层意义

如果只有一层,网络永远只能看到 3×3 的局部。 深度不是为了"更强",是为了"看得更远"。
但注意:纯粹靠堆 3×3 来扩大感受野,代价是层数线性增长。 纯堆 3×3 要 112 层才能罩住一张 224×224 的图(ImageNet 常用的输入尺寸;感受野 = 2n+1,解 2n+1 ≥ 224 得 n = 112),所以必须引入下采样。

2

下采样:让感受野指数级扩张

下采样(池化或步长卷积)把图变小。这一步有个不直观但极其重要的后果: 后面每一层在原图上的"步长"被放大了,于是感受野开始成倍增长。 也不是一次缩到最小就好——缩太猛,细节还没来得及提取就丢了;实际网络是「缩一点、卷积几层、再缩一点」。

r = 感受野 k = 卷积核大小 d = 膨胀率(核里相邻格隔开几格) j = 跳跃距离(当前层一个像素对应原图多少像素) s = 步长

把鼠标停在公式里的 k、d、j、s 上——有滑块的会亮起来。膨胀率 d = 核里相邻两个格子之间隔开几格;d = 1 就是普通的紧挨着(第 4 节会把它调大)。j 和 s 挂在同一个滑块上:s 是「这一层跳几格」,j 是「到这一层为止,前面所有步长乘起来」。d = 1(普通卷积)时,加号后面那一项就是 (k−1)·jin。

关键在于那个 jin:它就是「到这一层为止,前面所有步长乘起来」,会累积。 每次下采样让 j 翻倍,之后每个卷积层的贡献也跟着翻倍——于是感受野变成指数增长。

互动 · 对比"只堆卷积" vs "加下采样"

🎯 类比

像看地图。你手里永远是一把 3×3 的放大镜,但换地图的缩放层级之后, 同样一次放大镜移动,覆盖的真实距离就变了。
省城地图上的 3 厘米移动和小区地图上的 3 厘米移动,完全是两回事。 下采样就是"换地图"。

M

数学 · 把神经元摊回原图

上面说了两句话:「每加一层 3×3,感受野涨 2」和「一旦下采样,感受野就翻倍」。 两张图就能把这两句话变成看得见的东西: 把最上面那个神经元摊回原图上,看它到底盖住了哪几个像素。

动画 · 顶层那个神经元在原始输入上盖住了多大一片(每一步都当场递推)

公式 · 感受野递推式,每一个符号在图上都有一块

🎬 自己验一遍

把「下采样间隔」从 0 拖到 3:同一组卷积核、同样的层数,感受野就从加法涨变成乘法涨, 而右侧的 j 也跟着翻倍——j 就是那个把线性变指数的旋钮。
再把「膨胀率 d」拖大:参数量一个字都没变,感受野却变宽了(回扣第 4 节)。
感受野从来不是靠参数买来的,是靠「排列」和「少看一半像素」买来的。

3

池化 vs 步长卷积:选哪个

对比项最大池化 Max Pool平均池化 Avg Pool步长卷积 Stride Conv
怎么做窗口里取最大值窗口里取平均卷积核一次跳 2 格
有没有参数没有没有有(要训练)
平移不变性最强——挪一格通常最大值不变中等较弱
信息保留只留最强的那个让所有值参与,更平滑边下采样边提取特征
今天用得多吗经典 CNN 常用少了现代网络(ResNet:2015 年一种很深的卷积网络,靠残差连接能叠到上百层,详见《CNN 家族》)主流

互动 · 同一块 2×2 数字,三种下采样各吐出什么

所以下采样丢掉的主要是「精确在哪」,也丢掉一部分内容(最大值池化只留一个数,另外三个直接扔)。

⚠️ 一个历史转折

ResNet 之后,越来越多的网络用步长卷积替代池化: 它能在降维的同时学出"该保留什么"。
今天最常保留池化的是网络开头的 maxpool(一上来先把图快速缩小一半) 和结尾把整张特征图取平均、压成 1×1 做分类的全局平均池化。

4

空洞卷积:不降分辨率也扩视野

有时候你不想把图变小(比如分割任务,输出必须和输入同尺寸), 但又需要更大的感受野。这时用空洞卷积:把卷积核"隔开放"。

互动 · 同一个 3×3 核,不同膨胀率

膨胀率 d核的实际覆盖参数量感受野用在哪
13×393普通卷积
25×5(但只取 9 个点)95DeepLab v3、实时分割
49×9(只取 9 个点)99需要大视野但保持分辨率
817×17(只取 9 个点)917语音合成(WaveNet)

示意 · 为什么连续用同一个膨胀率会漏像素

连续两层都用 d = 2 粉色 = 从来没人看 混合 1、2、5 每个像素都被看到 同一排输入像素:每个小方块就是一个像素

这是二维网格效应的一维剖面。两层都用 d = 2 时,采样点落在完全相同的偶数位置上, 奇数位置永远进不了任何一层——这就是那个“棋盘格”。把膨胀率混起来用就不会漏了(Wang et al. 2018 那篇论文专门讨论过这个坑)。

那能不能用空洞卷积代替下采样?不能:图还是那么大,计算量一点没省(第 6 节那张表),连续用还会漏像素——它只解决「看得远」,不解决「算得省」。

5

上采样:放大回去,但找不回

分割(给每个像素贴标签)、生成(造一张图)这类任务,需要把特征图放大回原尺寸, 这是前面每一步下采样的逆操作。但先把话说死:没有任何一种放大能把丢掉的位置找回来。 插值是按固定规则把剩下的值铺开(最近邻复制 = 直接抄旁边那个;双线性 = 按距离加权平均), 转置卷积是学一个铺法;内容都是猜的、位置都是借的。所以分割网络还得靠 U-Net 的跳连:把下采样之前那层清晰的特征图, 直接接到后面同一个尺寸的地方——那才是还债的部分。

具体就这四种:最近邻、双线性、转置卷积、PixelShuffle(把通道重排成更大的图,本身不学参数)——区别只在「怎么把值铺开」,谁也找不回位置。

这四种各怎么算?

逐个当场算给你看,在《语义分割》那一章。

6

完整速查表

扩大感受野、或者在保持视野的前提下换算力,一共就这几条路。要挑哪条先看这张表;哪条会亏,看下一节。 参数量一列含偏置(每个输出通道 +Cout),与《MLP》《CNN》章口径一致。

操作空间尺寸通道数感受野参数量
3×3 卷积,stride 1不变可指定+29×Cin×Cout + Cout
3×3 卷积,stride 2÷2可指定+ (2×j)同上
2×2 最大池化÷2不变略增0
3×3 空洞卷积,d=2不变可指定+49×Cin×Cout + Cout
1×1 卷积不变可升可降+0Cin×Cout + Cout
全局平均池化→1×1不变全图0

账本 · 分辨率减半、通道翻倍、j 翻倍(ResNet-50 的那条路线)

224×224 112×112 56×56 28×28 14×14 3 通道 64 通道 256 通道 512 通道 1024 通道 j = 1 j = 2 j = 4 j = 8 j = 16

盒子高度 = 特征图分辨率,j = 当前一个像素对应原图多少像素。 同样一块 3×3 卷积,在最后那个盒子里贡献的感受野是第一个盒子里的 16 倍,参数量却一模一样。(图只画到 14×14;ResNet-50 最后还有一段 7×7、2048 通道,j 继续涨到 32。)

💡 1×1 卷积值得单独说一句

它看起来毫无意义:核只有 1 个像素,能卷出什么? 但它做的是跨通道的信息融合:对每个位置,把 Cin 个通道线性组合成 Cout 个。 它不改变空间尺寸,只改变通道数,而且几乎没有计算成本。
ResNet 的瓶颈结构(先用 1×1 把通道数压低,做一次 3×3 卷积,再用 1×1 升回来)就是靠它省参数: 同样输入输出通道下,参数量只有直接用一块 3×3 卷积的约 1/8。

7

什么时候不该用:四条路的付款单

前面把「怎么变大」讲完了。这一节只回答一个问题:什么时候这条路是亏的。

这条路什么时候用什么时候别用付的是什么
只堆 3×3
不降分辨率
图小、要精确定位、不想丢任何像素 想看整张 224×224(要 112 层) 层数线性涨:算力、显存、反向传播的路径一起线性涨
下采样
池化 / 步长卷积
分类、要全局视野、要省钱 小目标、精细边界 位置精度不可逆:20 像素的目标经 32× 下采样只剩 0.6 像素 (FPN 是一种把不同尺寸的特征图组合起来的检测网络,整篇都在治这个病)
空洞卷积 不能降分辨率(语义分割) 连续几层用同一个膨胀率 网格效应(第 4 节):一半像素永远没人看
上采样 把特征图放大回原尺寸 指望把丢掉的位置找回来 内容是猜的;还债要靠跳连(第 5 节 + 《分割》章)

最后留个底:公式算出的 19×19 是「理论感受野」——理论上能影响到的范围;实际起作用的,往往只集中在中间一小块(Luo et al. 2016)。

公式算出感受野 19×19,网络就真的把这一片看全了?

没有。上面那句说的是理论范围:实际影响力从中心向边缘近似高斯衰减,边缘几乎影响不到输出(「有效感受野」,Luo et al. 2016)。

8

小结

这一章全是能直接算出来的几何。但它藏着一笔和常识相反的交易。

它对应哪条线 ⑥ 层层组合——感受野是一层层拼出来的: 每叠一层只把上一层的局部结果再拼一次,叠得越深、能拼到的范围越大 (第 2 节那条曲线,层数翻倍就涨了近千倍)。
一句话 这笔交易叫「分辨率换视野」: 每把图缩小一半,后面每一层卷积的覆盖范围就翻一倍,感受野从加法学变成乘法。
它牺牲了什么 牺牲了位置精度,而且不可逆:上采样只是把剩下的值铺回去, 找不回丢掉的位置——所以分割任务要靠跳连"当初就别丢"(回扣暗线 B)。

一笔交易 · 一边付掉位置精度,一边买回视野

分辨率减半 ↓ 视野翻倍 ↑ 同一块 3×3 卷积,参数量一模一样:一边付掉位置精度,一边买回视野 位置精度(付出去) 感受野(买回来)

天平两头坐的是同一个操作:下采样。它不是“有得也有失”那种笼统的话, 而是一笔具体、可算、而且不可逆的交易:买视野的钱,付出去就收不回。

💡 检验一下:你现在能指着哪个互动说这句话

回到第 2 节那张图,把「层数」滑块从 30 拖到 60:橙色虚线(不下采样)61 → 121, 绿色实线(每 3 层下采样一次)6,139 → 6,291,451,涨了约 1000 倍。 两条曲线用的是完全同一套 3×3 卷积核,唯一的差别是中间有没有把图变小——感受野不是靠"看得更仔细"换来的,是靠"少看一半像素"换来的。

它在暗线里站在哪

暗线这一章的回答
A 信息流动 数据形状在这个阶段做两件相反的事:感受野沿深度变大,特征图尺寸沿下采样变小—— 典型路线是 224×224 →112 →56 →28,分辨率每减半、通道数一路变多 (ResNet-50:64 → 256 → 512 → 1024 → 2048,除第一步外每次翻倍),于是“每层携带的信息总量”大致守恒。
反向的上采样把 (H/8, W/8, C′) 推回 (H, W, C)(H、W 是高和宽,C′、C 是通道数): 但推回的只是形状,不是内容(对应第 5 节的“不可逆”)
B 什么被牺牲了 空间分辨率换感受野,而且这笔交易在本章的四个小节里反复出现: 下采样买视野、空洞卷积买视野不花钱、上采样想把分辨率买回来但买不回内容。 两种付款方式——池化是现金(当场把像素扔掉),步长卷积是分期(把“丢什么”交给训练决定)
C 参数账本 感受野的扩张完全不靠参数,靠的是排列:一块 3×3 卷积在 C_in=C_out=C 时是 9C² + C 个参数,无论在第 1 层还是第 50 层都是这个数;但它贡献的增量是 2j——参数不变,收益乘累计下采样倍数。
ResNet-50 最后那一段(7×7、512 通道、j = 32)一块 3×3 就是 9 × 512 × 512 ≈ 2.36M 参数、贡献 64 像素; 同样参数放在输入层(j = 1)只贡献 2 像素——深层的“视野性价比”是浅层的 32 倍。
空洞卷积更极端:d=8 时参数和计算量都不变(9C²+C 个参数、9C²HW 次计算),增量却有 16 像素
D 跑在什么上 算力受限的那一类。而下采样首先是省钱手段,扩大感受野只是它免费的副产品。
ResNet-50 在 224×224 输入下约 41 亿次乘加(MACs:一次乘法加一次加法算一次;4.1 G,不同工具的统计口径有差异)。 把 14×14 那一段强行保持 56×56,计算量就是 16 倍((56/14)²);分辨率减半,要留的中间结果(激活)也少 4 倍。
最贵的动作是高分辨率上的卷积,所以第一段(112×112)只放 64 个通道、参数也最少:7×7×3×64+64 = 9472 个(约 0.0095M)。完整的算力账(Roofline 模型)在 《硬件与算力账本》
E 它假设了什么 假设“多看几眼”可以代替“看得更广”:只要把相邻的局部信息一层层拼起来, 拼到足够深就能代表远处的信息(最后一层的一个 3×3,在原图上已经盖住整只猫) (回看 CNN 章的局部性假设,那条假设就是一种归纳偏置: 它把人类关于图像的先验直接焊进了结构里)。
这条假设对图像大致成立,但对“左上角的猫和右下角的球有关系”这种任意长程依赖不成立: 卷积要么堆到极深,要么必须先把图变小。把这条假设拆掉的方案只有一个: 让任意两个位置直接互相看见,这就是注意力(下一阶段)
F 违背了哪个直觉 “丢掉信息”通常是坏事,但在这里它是唯一便宜的付款方式。 更反直觉的是:一个没有参数、粗暴到只会取最大值的 2×2 池化, 对感受野的贡献比一块更“聪明”、可学习的 3×3 卷积更大: 因为它把 j 翻倍,于是后面每一层的贡献都翻倍。
在这个位置上,“更聪明”输给了“更粗暴”,而这也是 ResNet 之后大家改用步长卷积的真正理由: 既然要付这笔钱,不如让训练决定买什么
🎯 前后钩子

它接住了上一章的什么:《CNN 卷积神经网络》用 3×3 的小印章省下了参数, 却没回答这么小的窗口怎么可能认出整只猫——这一章补上这个缺口。

它给后面留了什么:下一章 《经典 CNN 家族》接着问:既然降下去有用,怎么堆才又深又准? 更后面的 《语义分割》要还这笔债(U-Net 跳连); 同一件事换到图数据上,是更后面的 《图神经网络》第 3 节:一个点传 k 轮,就听到 k 步以内的邻居。

一句话带走感受野

感受野 = 一个神经元在原始输入上能看到多大区域。 只堆 3×3 是线性增长;加进下采样(像换一张更粗的地图),跳跃距离累积,才变成指数增长。 代价是位置精度不可逆地丢掉——要么用池化(无参数)或步长卷积(可学习)接着付, 要么用空洞卷积不降分辨率地换(小心网格效应)。

9

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写

∑ 更严格的形式