第 11 天 · 不降分辨率,也能看得更远
一句话
论文用空洞卷积在不降采样、不增加参数的前提下让感受野指数增长,并设计了一个可插在任何分割网络后面的上下文模块。它还发现,删掉分类网络里为分类服务的池化层后,分割反而更准。
论文讲了什么
结论先行:语义分割要给每个像素一个标签,既需要大感受野看清上下文,又需要高分辨率保住细节。空洞卷积(dilated convolution)能同时满足两者:感受野指数增长,特征图尺寸不变,参数量不变。
问题。分类网络靠池化和步长扩大感受野,代价是分辨率逐层下降。FCN 先降采样再用反卷积恢复;另一类方法把图片缩放成多个尺寸分别输入。作者问了一个更根本的问题:分类网络的哪些部件,对稠密预测(dense prediction)真的必要?
方法。
- 空洞卷积:卷积核的采样点之间隔开 d−1 个像素,d 叫空洞率。d = 1 就是普通卷积。3×3 核在 d = 2 时覆盖 5×5 区域,参数仍是 9 个。
- 指数扩张:逐层叠 3×3 核,空洞率取 1、2、4、8……。第 i 层之后,感受野是
(2^(i+2) − 1) × (2^(i+2) − 1),参数量只线性增长。 - 上下文模块(context module):7 层 3×3 卷积,空洞率依次是 1、1、2、4、8、16、1,最后接一个 1×1 卷积,共 8 层。输入和输出都是 C 通道、同尺寸的特征图,感受野 67×67。基础版每层 C 个通道;大版本逐层加宽。
- 恒等初始化(identity initialization):普通随机初始化效果不好。作者把每层初始化成原样传递输入,模块开始时“什么都不做”,再逐步学习加入上下文。
- 前端模块(front-end):改造 VGG-16:删掉最后两个池化层和对应的步长,把后续卷积的空洞率改成 2 和 4。作者还删掉了中间特征图的填充,这些填充原本服务于分类。
关键结果。
- 只用前端模块,在 Pascal VOC 2012 测试集上就比 FCN-8s 和 DeepLab 更准,结构却更简单。
- 在前端后面接上下文模块,三种配置的准确率都提升:单独使用、接 CRF、接 CRF-RNN。
- 在 CamVid、KITTI、Cityscapes 三个城市道路数据集上,方法同样有效。
关键概念
- 稠密预测(dense prediction)
- 给输入的每个像素都输出一个结果,语义分割就是典型例子。它和分类相反:输出不是一个标签,而是一张和原图对齐的标签图。
- 感受野(receptive field)
- 输出上一个点能“看到”的输入区域大小。感受野太小,模型只看局部纹理,分不清一块灰色是路面还是墙。
- 空洞卷积(dilated convolution)
- 采样点之间留空的卷积,也叫 atrous 卷积。空洞率为 d 的 k×k 核,有效尺寸是 k + (k − 1)(d − 1),参数量不变。
- 上下文模块(context module)
- 论文设计的 8 层模块,空洞率逐层翻倍。它不改变特征图尺寸和通道数,可以直接插到已有分割网络的输出后面。
- 恒等初始化(identity initialization)
- 把卷积核初始化成只在中心位置为 1、其余为 0,使每层开始时原样传递输入。这让新加的模块不会破坏前端已有的预测。
历史位置:为什么值得读
空洞卷积的数学并不新。信号处理里早有 “à trous” 算法(法语“带洞的”),1987 年就用于小波分解。同期的 DeepLab 也用了空洞卷积,但把它当作提高分辨率的技巧。这篇论文的贡献是把它作为系统设计的核心:专门用它聚合多尺度上下文,并说明分类网络里哪些部件可以删掉。
它影响了多个方向。分割领域,DeepLab 后续版本把多种空洞率并联,形成 ASPP 模块。音频领域,2016 年的 WaveNet 用因果空洞卷积生成语音,空洞率同样逐层翻倍,感受野随层数指数增长。序列建模领域,时间卷积网络(TCN)沿用了这个设计。2017 年作者本人又提出 Dilated Residual Networks,解决空洞卷积带来的网格伪影。
在这份清单里,它是“扩大感受野”的一种答案。第 9、10 天靠加深网络扩大感受野;这一天靠稀疏采样;第 13、14 天的注意力机制则让每个位置一步看到全局。三种思路对比着读,收获最大。
学前准备
- 先看第 8 天,熟悉卷积和池化
- 能手算多层卷积叠加后的感受野
- 了解语义分割任务和 mIoU 指标
- 知道 FCN 怎样把分类网络改成分割网络
在原仓库怎么学
- 读 README.md 的目录,它依次讲稠密预测、感受野、上下文模块和前端模块,再扩展到 ASPP。注意 ASPP 来自 DeepLab,不属于本文。
- 读 implementation.py。它包含空洞卷积和感受野分析工具,还有 ASPP 和 WaveNet 风格的结构。先只看感受野分析和上下文模块。
- 运行 train_minimal.py,它演示分割训练、多尺度特征和 WaveNet 风格的序列建模。分割数据集的存放位置见 data/README.md。
- 用 visualization.py 画感受野随空洞率增长的图。notebook.ipynb 从“分辨率和感受野的矛盾”讲起,逐步引出空洞卷积。
- 做 exercises/ 的 5 个练习:01 可视化感受野;02 搭上下文模块;03 实现 ASPP;04 对比不同空洞率排列;05 用空洞卷积做音频。答案在 exercises/solutions/。
- 进阶题在 assessments/exercises.md,包括感受野对比、多尺度融合、感受野与准确率的取舍,答案在 assessments/solutions.md。
今天再看
分割的主流已经换成 Transformer。SegFormer、Mask2Former、SAM 这些模型靠注意力获得全局上下文,不再依赖空洞卷积。但 DeepLab 系列仍是常用的分割基线,空洞卷积也仍在其中。
“稀疏采样换大视野”的思路进入了长序列建模。注意力的计算量随序列长度平方增长。2020 年的 Longformer 用了“空洞滑动窗口”注意力;2023 年的 LongNet 提出“空洞注意力”,按指数间隔采样 token。这和本文的空洞率翻倍是同一个想法。
音频和时间序列里,空洞卷积仍然活跃。WaveNet 之后的很多语音模型和时序预测模型,都用它在低成本下覆盖很长的历史。
容易卡住的地方
- 感受野要手算一遍:从 1 开始,每层加上(有效尺寸 − 1)。空洞率 1、1、2、4、8、16、1 依次得到 3、5、9、17、33、65、67。算对了,后面的代码就好懂。
- 空洞率全部相同时,例如连续 3 层 d = 2,输出只依赖棋盘格上的输入点,会出现网格伪影。建议用递增的空洞率,并在最后接一层 d = 1。
- 要保持特征图尺寸,3×3 核的 padding 必须等于空洞率 d。PyTorch 里写 padding=dilation,否则每层都会缩小。
- 练习 05 的 WaveNet 用因果卷积,只能在左侧填充。两侧都填充会让模型看到未来的采样点,训练损失很低,生成却失败。
延伸阅读
- 原论文:Multi-Scale Context Aggregation by Dilated Convolutions
- 原仓库第 11 天目录:11_dilated_convolutions/ —— 代码、笔记本、练习与答案(英文)
- Fully Convolutional Networks for Semantic Segmentation —— FCN,本文的主要对比对象
- DeepLab(v2,含 ASPP) —— 空洞卷积加多尺度并联
- WaveNet: A Generative Model for Raw Audio —— 因果空洞卷积生成语音
- Dilated Residual Networks —— 作者后续工作,处理网格伪影