3.2 卷积运算:从单通道到多通道
3.1 节给出了结论:卷积用「核在图上滑动」处理图像。但这句话里的每个词都还没定义:「滑动」的步长是多少?边界怎么办?一张 RGB 图有三个通道,核该长什么样?输出有几个通道?
这一节把这些问号逐个变成公式,目标是让你具备一项不依赖任何代码的能力:给定输入形状与层配置,写出输出形状、参数量与计算量。这项能力在工程上的价值很难被高估——卷积网络里绝大多数维度报错、显存溢出、速度不达标,都可以先在一张纸上算出来。
3.2.1 卷积与互相关:框架算的其实是「互相关」
先澄清一个符号上的历史包袱。数学里的卷积要求把核翻转 180°,而深度学习框架里的 Conv2d 不翻转。
给定单通道输入 、核(卷积核 / 滤波器,filter / kernel)、偏置 、步幅 、填充 ,输出 的第 个元素为
越界的下标( 或 )在填零(zero padding)约定下取 。深度学习文献与所有主流框架把这个运算直接称为「卷积」,本章沿用这一习惯,但读者应知道公式 (3.1) 算的是互相关。
把公式 (3.1) 读成一句话:每个输出位置,取输入上的一个 窗口,与核逐元素相乘再求和,加上偏置。这个「逐元素相乘再求和」正是两个 维向量的内积——所以卷积核本质上是一组用来和图像局部做相似度比较的模板。
由此立刻得到两个直觉:① 核与窗口越相似(同号且数值大),输出越大——核是「模式探测器」;② 神经网络「学习」卷积层,学的就是这些模板的数值。第 1 层学到的往往是对比度、方向边缘这类低级模板,越深越抽象(3.4 节会把这个层次讲成一个演进故事)。
既然只差翻转,为什么还要专门澄清?三个原因:① 梯度回传公式在两种约定下不同,手推反向传播时忘记约定就会写错符号;② 卷积结合律在互相关约定下不成立(一般 下无法合并成单核),凡「把多层合并成一层」的等价变换都必须用数学卷积的约定;③ 与信号处理、控制理论的卷积公式对接时(本教程姊妹书大量使用),翻转必须显式写出。
定义翻转核 ,则对任意 有 。即互相关是核翻转后的数学卷积,两者在表达能力上完全等价。
数学卷积(离散、二维)定义为 。令 ,求和指标遍历同一范围:
设窗口左上角为 ,把输入下标写成「左上角 + 偏移 」的形式,与互相关 对照,只需核的取值满足 ,即「翻转 180° 后的核」。以 为例: 的左上角元素在数学卷积里乘的是窗口右下角的输入,在互相关里乘的是左上角——这正是翻转的效果。
∎设 、(数学卷积,单通道、无偏置、步幅 1、填充足够使尺寸不变),则 。
第二步用了换元 。这就是卷积的结合律。在框架的互相关约定下,合并时应把其中一个核翻转,否则得到的是翻转核的结果。
∎若两层之间没有非线性,它们在数学上就是两次线性运算,合并后完全等价:参数与计算量都下降。但训练时绝不能这么干——去掉一层等于去掉那一层的非线性与额外容量,表达能力直接下降。
正确的用法是训练之后:模型收敛、权重冻结,再把「卷积 → BatchNorm」或相邻的线性卷积融合成单个核,用更少的算子跑同样的函数。这是推理优化(TensorRT、torch.fx 的 conv-bn folding 等)里最常见的一类图优化,其合法性完全依赖这条定理。
3.2.2 步幅与填充:输出尺寸公式
- 填充(padding):在输入四周补 圈元素(通常补 ),用于控制输出尺寸、保住边缘信息。
- 步幅(stride):核每次移动的距离。 逐个位置滑; 相当于边卷积边下采样。
- 空洞 / 膨胀率(dilation):核元素之间插入 个空隙,等价于把 核撑成有效核 而不增加参数。
管「看多大」:核越大,单层覆盖范围越大,但参数按 涨、层内非线性变少。 管「边界与尺寸」:不填充时边缘像素被窗口覆盖的次数远少于中心像素,填充让边缘与中心视野次数趋于一致,同时让尺寸可控。 管「降不降分辨率」: 使输出变小、跳距被放大(3.2.5),感受野开始滚雪球,代价是空间精度损失。 是 的廉价替身:9 个参数得到 视野,代价是采样稀疏(会漏掉细结构,出现网格效应)。
一维情形(二维逐轴独立应用)为
两种常用命名:valid 指不填充(,输出变小);same 指输出与输入同尺寸( 且 为奇数时取 )。
滑动窗口的左边界只能取整数位置。设最后一个合法窗口的左边界为 ,其右边界 必须落在填充后的输入范围内(长度 ),故 。 从 出发、每次加 ,可取的个数为 。边界处剩余像素不足 个、放不下完整窗口时该位置被丢弃——这就是向下取整的来源。窗口必须完整落在填充后的范围内,框架(如 PyTorch 的 Conv2d)不会补齐最后一个不完整位置;若 则直接报错。有空洞时把 换成 即可,因为「核元素之间的空隙」等效于把核撑大。
① 填充把可用范围从 撑到 ;② 一个窗口占 格,所以 时有 个起始位置;③ 步幅 时起始点每 个取一个,于是 。两个常用特例随手可得: → 尺寸不变; → 精确减半(224 到 112 就靠这类配置)。
输入 ,求下列配置的输出尺寸:(a) ;(b) ;(c) ;(d) 。再求 。
(a) :valid 约定,边界处丢两圈信息。
(b) :same 约定,尺寸不变。
(c) :尺寸精确减半——骨干网络的降采样常用这组配置。
(d) ,:空洞卷积保尺寸、扩视野,参数仍是 9 个而视野变成 。
ResNet 首层:;再接 的最大池化得 。这就是 ResNet 各阶段入口为 的来源。
规律小结(背下来比推导快): 且 ( 奇)→ 尺寸不变; → 大致减半; → 核撑大而参数不变,用于不降分辨率地扩视野(分割网络常用,见 3.7 节)。
∎3.2.3 多通道卷积与 1×1 卷积
输入 ,输出通道数 。第 个输出通道由一个三维核 与偏置 给出:
两条要点:每个输出通道有自己的一整套核;每个核的深度必须等于输入通道数——它在 个输入通道上各取 权重,把结果求和成 1 个通道。
拆成两步看最清楚:一个核是一个 张量,同时看所有输入通道的同一空间邻域,做一次 维内积得到 1 个数——它回答「这一小块位置-通道组合里,有没有我关心的模式」;一套核( 个) 各自给出一张特征图,于是输出张量是 张特征图,通道维就是「模式维」。
一个有用的类比: 是「输入证据通道」, 是「输出假设通道」,卷积核是它们之间的权重矩阵——固定空间位置后,公式 (3.3) 与一次 的矩阵乘完全同构,这正是 3.2.8 中 im2col 实现的依据。 卷积是这个视角的极端情形:空间上什么都不做,纯粹在每个像素位置把 个通道线性组合成 个通道,即「逐像素的全连接层」,用来升降维、跨通道融合,并在不改空间尺寸的前提下加一层非线性。
一层卷积(含偏置)的参数与乘加次数(MACs,1 MAC = 1 次乘 + 1 次加)为
若按 FLOPs 计(一次乘加算 2 次浮点运算),。偏置项 在通道数很大时可以忽略( 对 ,约 ),工程口算时常直接写 ;但核对模型总参数量时必须把偏置与归一化层的参数加回来。
ResNet-50 的瓶颈块(bottleneck)在 上做三次卷积:()、(,)、(),全部 。求各自与整块的参数量、MACs,并与「单层 、」比较。
① ,:Params ;MACs 。 ② ,:Params ;MACs 。 ③ ,:Params ;MACs 。
瓶颈块合计:Params ,MACs 。 单层 、:Params ,MACs 。
结论:瓶颈设计把参数降到约 、计算量降到约 ,而表达方式更丰富(多两层非线性、通道可升可降)。把中间宽度 当参数扫一遍,可见这是计算预算的再分配:
| 结构 | 中间通道 | 参数量 | MACs(,) | 相对单层 |
|---|---|---|---|---|
| 直接 | 256 | 590,080 | 1.85×10⁹ | 1.000 |
| 瓶颈() | 64 | 69,016 | 2.18×10⁸ | 0.118 |
| 瓶颈() | 128 | 147,712 | 3.97×10⁸ | 0.215 |
| 瓶颈() | 256 | 295,168 | 7.55×10⁸ | 0.409 |
注意最后一行:即使把中间宽度设回 ,参数量仍只有单层 的一半——因为两个 卷积一共是 个参数,比一个 的 小。ResNet-50/101/152 采用 ,用省下的算力把深度做上去(3.4 节)。
∎3.2.4 参数量与计算量的速查表
| 模型 / 层 | 输入 | 参数量 | MACs(一次前向) | 备注 |
|---|---|---|---|---|
| 全连接 150528→1000 | 1×150528 | 1.51×10⁸ | 1.51×10⁸ | 3.1 节的对照基准 |
| 卷积 3×3,64→64 | 56×56×64 | 36,928 | 1.16×10⁸ | 参数省 4 个数量级、算力同量级 |
| 深度可分离 3×3,64→64 | 56×56×64 | 4,800 | 1.45×10⁷ | 约为标准卷积的 1/8 |
| 分组卷积 3×3,64→64() | 56×56×64 | 9,280 | 2.89×10⁷ | 约为 1/4 |
| ResNet 瓶颈块 | 56×56×256 | 69,016 | 2.18×10⁸ | |
| AlexNet(227²) | 3×227×227 | 6.16×10⁷ | — | 其中 5.86×10⁷ 在全连接层 |
| VGG16(224²) | 3×224×224 | 1.384×10⁸ | — | 其中 1.236×10⁸ 在全连接层 |
| ResNet-18(224²) | 3×224×224 | 1.17×10⁷ | 约 1.8×10⁹ | 无大全连接层 |
| ResNet-50(224²) | 3×224×224 | 2.55×10⁷ | 约 4.1×10⁹ | 与论文报告 25.6M 一致 |
| ViT-B/16(224²) | 3×224×224 | 8.65×10⁷ | 约 1.76×10¹⁰ | 无卷积,见 3.5.2 |
AlexNet / VGG16 的参数几乎全在全连接层——这正是它们在新的骨干出现后迅速退出主舞台的直接工程原因;ResNet / ViT 的参数分布在卷积 / 注意力层里,因此能在同量级参数下取得高得多的精度。表中 MACs 只统计主要乘加项(卷积、矩阵乘),忽略激活函数、归一化、偏置加法与显存搬运;真实耗时还要看算子效率与访存(3.3 节与本教程第 9 讲)。
3.2.5 感受野:堆叠为什么让视野变大
第 层某个输出神经元能追溯到原始输入的区域的大小,称为它的感受野 。第 层相邻两个神经元在原始输入上的中心间距,称为跳距(jump,也叫等效步幅)。
感受野回答「看多大」,跳距回答「隔多远一个采样点」。两者共同决定一件事:第 层的一张特征图相当于原图的什么分辨率。 意味着特征图上一个像素对应原图 块——做像素级分割时,这个 就是定位精度的上限(这也是分割网络要保住高分辨率特征的原因)。更实用的一条:把原图上某层的核换算到第 层时尺寸要乘 ,所以设计网络时「这一层相当于原图上看多大」必须用 而不是 。
在第 层之上再堆一层 、步幅 的卷积(或池化),则
初始条件:第一层直接作用于输入时 、。
感受野:第 层的输出是 个第 层神经元的加权和,这些神经元在原始输入上的中心依次相差 ,最外侧两个中心的跨度为 ;再把两端各自的半个视野(合起来正好是完整的一个 )算进来,得 。自检: 时 ,符合直觉。跳距:第 层相邻两个输出位置对应第 层上相差 个位置的窗口,这 个位置在原始输入上相隔 ,故 。初始条件:第一层直接看输入时窗口覆盖 个原始像素(),相邻窗口中心相差 个像素()。
∎(a) 层 、 的卷积;(b) 每两层 后接一次 最大池化;(c) ResNet 风格浅层骨架: → 最大池化 → 12 层 。分别求最终感受野。
(a) ,每层增量 :。2 层看 、3 层看 。线性增长,很慢。
(b) 从 出发,每阶段 = 两次 (各 )再一次池化( 后 翻倍):
| 阶段 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| 8 | 18 | 38 | 78 | 158 | |
| 2 | 4 | 8 | 16 | 32 |
感受野从 8 到 18、38、78、158——近似每阶段翻倍,与 (a) 的线性增长形成鲜明对比。
(c) 逐步套用 (3.6):
| 步骤 | 操作 | ||
|---|---|---|---|
| 1 | , | 7 | 2 |
| 2 | 最大池化, | 4 | |
| 3 | 12 层 , | 4 |
到 stage1 结束,感受野已达 (接近输入 224 的一半),跳距仍为 4——特征图分辨率 ,每个点对应原图约 见方的区域。
三个工程结论:① 想要大感受野,下采样比堆层划算得多——纯堆 要达到 需要 50 层,而按 (b) 的方式 10 层就到 ;② 感受野不是越大越好——分类偏好大感受野,分割 / 检测的定位分支需要小跳距,所以它们用空洞卷积或特征金字塔(3.7 节);③ 理论感受野 ≠ 有效感受野——理论值是能追溯的最大范围,而实际梯度与响应集中在中心的一小块区域,有效感受野通常只是理论值的一小部分,别把它当作「网络真正用了多大上下文」的证据(见本节延伸阅读)。
∎3.2.6 分组卷积与深度可分离卷积
- 分组卷积(grouped convolution):把 个输入通道与 个输出通道各分成 组,第 组只做组内卷积,组间不通信。
- 深度可分离卷积(depthwise separable convolution):两步——① 逐通道卷积(depthwise)每个输入通道用一个独立 核卷积;② 逐点卷积(pointwise)用 卷积做通道混合。它是分组卷积取 的特例再加一个混合层。
分组:让不同组各管一类特征,组内自足、组间互不干扰。历史上 AlexNet 在两块 GPU 上并行训练时被迫把网络分成两半,那个工程妥协后来被发现也是一种有效的正则与压缩(组数越多,跨通道容量越小)。分离:标准卷积让每个核元素同时承担「空间滤波」与「通道混合」两件事,拆开后空间部分( 个小核)与通道部分()各司其职;代价是跨通道的空间联合模式需要两层才能表达,省下算力的同时把一部分容量交给了深度来补。
设 ,忽略偏置,标准卷积与深度可分离卷积的参数量之比为
即参数量与 MACs 都降到约 。(含偏置时实测比值略大于该式。)
标准卷积参数 ;可分离为逐通道 加逐点 ,合计 ,相除即得。计算量同理:逐通道的 MACs 为 、逐点为 ,相加后除以标准的 得到完全相同的比值——因为输出面积在分子分母中约掉了。
∎把例 3.2.2 中瓶颈块的 、、 换为深度可分离卷积,求新参数量与 MACs,并给出该块总量相对对照组的变化。
逐通道(,;PyTorch 的 groups=C 默认带偏置,故为 ):Params ,MACs 。
逐点(,):Params ,MACs 。
可分离合计:Params (原 的 );MACs (原 的 )。 该块总量(降维 + 可分离 + 升维 ):Params ,MACs ,相对原瓶颈块分别降到 与 ,相对单层 的参数量降到 。
权衡提醒:这只是「更省」的一半故事。省下的容量需要用更多通道或更多层补回来,否则精度下降。MobileNet 系列(面向移动端与嵌入式)正基于这一组取舍设计,在同等精度下计算量比同期 ResNet 低一个数量级左右——具体基准数字随实现与训练配方变化,引用时需核实版本与训练配置。
∎3.2.7 转置卷积与上采样
设卷积可写成矩阵形式 ( 由核、步幅、填充唯一确定,是稀疏的带状矩阵)。转置卷积(又称反卷积 deconvolution、分数步幅卷积)定义为以 为权重矩阵的线性映射 。它交换了「卷积输入空间」与「输出空间」的角色,故输出尺寸满足
( 时退化为对称式; 时具体输出尺寸还依赖 output padding,可落在长度为 的一个区间内)。
不要把它理解成「把卷积撤销」。两个正确的理解方式:① 形状一致的梯度算子——对 ,反向传播要算 ,这个 是必然出现的运算;转置卷积就是把这个「卷积反向传播中对输入求导」的线性层单独拿出来当上采样层用,这也解释了它为什么天然带可学习参数(就是那个核)。② 等效的「零插值 + 普通卷积」——把输入元素之间插入 个零、再补零填充,然后用翻转的核做一次普通卷积,结果与转置卷积完全一致;因此它不需要新算子。
代价:零插值 + 大步幅会在输出上留下棋盘格伪影(checkerboard artifact)——不同位置参与的乘加次数不一致导致幅度周期性起伏。常见缓解:用「上采样 + 普通卷积」替代(最近邻 / 双线性放大后接 卷积),或让核大小能被步幅整除。
| 上采样方式 | 可学习 | 参数量 | 典型用途与注意点 |
|---|---|---|---|
| 最近邻插值 | 否 | 0 | 快、无伪影;块状感明显,常后接卷积平滑 |
| 双线性插值 | 否 | 0 | 平滑,分割网络常用;不引入可学习容量 |
| 转置卷积 | 是 | 表达力强; 易出棋盘格,需谨慎设核与步幅 | |
| 像素重排 PixelShuffle | 否(前置卷积可学) | 0(本身) | 把通道维重排成空间维,与 倍放大等价,超分常用 |
| 反池化 / 最大位置索引 | 否 | 0 | U-Net 早期版本用过;现代多用插值 + 卷积 |
(上采样方式的取舍见下表;本教程在第 3.7 节还会回到「解码器如何恢复分辨率」的完整讨论。)
3.2.8 实现视角:im2col 与卷积的效率
「滑窗 + 内积」是一句双重循环,但 GPU 跑不出速度。工业界把卷积变成矩阵乘(GEMM),因为矩阵乘有几十年优化积累(cuBLAS / MKL)。
# 输入 x: (C_in, H, W),核 w: (C_out, C_in, k, k),步幅 s,填充 p
1. im2col:把每个输出位置的 k×k×C_in 窗口拉成一列
→ X_col: (C_in·k·k, H_out·W_out) # 内存放大 k² 倍,是其主要代价
2. reshape 核 → W_mat: (C_out, C_in·k·k)
3. GEMM:Y = W_mat @ X_col → (C_out, H_out·W_out)
4. col2im:按列还原为 (C_out, H_out, W_out),加偏置
为什么有效:把「带边界的滑窗」这道麻烦交给第 1 步的访存变换,剩下的交给高度优化的矩阵乘。 时内存放大 9 倍、 时 49 倍。
- im2col + GEMM:通用、易写、能吃 BLAS 优化;代价是内存放大与额外访存,小核()最常用。
- Winograd:用多项式变换减少乘法次数( 把每 4 个输出的乘法从 36 次降到 16 次),代价是数值误差略升、变换本身有开销,对深度可分离卷积收益有限。
- 隐式 GEMM / 直接卷积:不物化
X_col,在片上缓存里分块累加,避免 倍内存放大——现代算子库的默认路线。
学习建议:用 torch.unfold 亲手写一遍 im2col,确认自己算的 MACs 与工具(如 thop、fvcore)报的一致;然后记住「真实速度还取决于访存与算子库,不能只看 MACs」——这条在本教程第 9 讲会再次出现。
import torch
import torch.nn as nn
import torch.nn.functional as F
x = torch.randn(2, 3, 224, 224) # (B, C_in, H, W):批优先,通道在维度 1
# 1) 基本卷积:核 3x3、64 个输出通道、步幅 2、填充 1 → 尺寸减半
conv = nn.Conv2d(3, 64, kernel_size=3, stride=2, padding=1)
y = conv(x)
assert y.shape == (2, 64, 112, 112) # floor((224+2-3)/2)+1 = 112
assert sum(p.numel() for p in conv.parameters()) == 1792 # 64*3*9 + 64
# 2) 手写 im2col 卷积,与 Conv2d 数值比对
def conv2d_via_unfold(x, weight, bias=None, stride=1, padding=1):
B, C, H, W = x.shape
C_out, _, k, _ = weight.shape
if padding:
x = F.pad(x, (padding,) * 4) # 上下左右各补 padding
cols = F.unfold(x, kernel_size=k, stride=stride) # (B, C*k*k, L)
out = weight.view(C_out, -1) @ cols # 批矩阵乘 → (B, C_out, L)
if bias is not None:
out = out + bias.view(1, -1, 1) # 偏置按通道广播
Ho = (H + 2 * padding - k) // stride + 1 # 与公式 (3.2) 一致
return out.view(B, C_out, Ho, (W + 2 * padding - k) // stride + 1), cols
y2, cols = conv2d_via_unfold(x, conv.weight, conv.bias, stride=2, padding=1)
print("与 Conv2d 最大误差 =", (y - y2).abs().max().item()) # 期望 ~1e-6 量级
print("col 形状 =", tuple(cols.shape), "内存放大 = C_in*k^2 =", 3 * 9, "倍")
# 3) 分组与深度可分离:groups 就是全部代码
dw = nn.Conv2d(64, 64, 3, padding=1, groups=64) # 逐通道:groups = C_in = C_out
pw = nn.Conv2d(64, 64, 1) # 逐点:通道混合
sep = sum(p.numel() for p in dw.parameters()) + sum(p.numel() for p in pw.parameters())
print(f"标准 {64*64*9+64} vs 深度可分离 {sep},比值 {sep/(64*64*9+64):.3f}") # ≈0.13
# 4) 转置卷积:k=4, s=2, p=1 时输出精确翻倍
up = nn.ConvTranspose2d(64, 32, kernel_size=4, stride=2, padding=1)
assert up(torch.randn(1, 64, 56, 56)).shape == (1, 32, 112, 112)
- 「卷积」到底翻不翻核:深度学习实现的是互相关,不翻转核;但手推反向传播、做核合并、对接信号处理公式时必须显式处理翻转(命题 3.2.1、定理 3.2.1)。
- 核形状写反:核是 。
nn.Conv2d(64, 32, 3)表示输入 64 通道、输出 32 通道,不是反过来——写错就是形状报错十有八九的来源。 - 以为输出通道由输入通道决定:输出通道数由核的个数决定,是完全自由的超参数;唯一硬约束是核的深度 。
- 忘了 卷积也有偏置:瓶颈块参数量核对时的 就是它,漏掉会以为「公式算错了」。
- 把转置卷积当卷积的逆:它不是逆运算,只是「与卷积梯度同形」的上采样;用零插值 + 大步幅时还会带来棋盘格伪影。
- 低估大核卷积的参数开销: 从 3 到 7,参数涨 倍、内存放大也涨到 49 倍;「用大核扩视野」通常不如「下采样 + 小核」或空洞卷积划算。
- 把理论感受野当作实际上下文:有效感受野远小于理论值,且呈中心加权分布(延伸阅读 Luo et al. 2016)。
Q1 输入 ,用 核、 个输出通道、、,求输出形状、参数量与 MACs。
Q2 层 、 卷积的感受野是多少?要得到 的感受野,纯堆 需要多少层?改用「每两层后接一次 池化」,10 层能到多大?
Q3 深度可分离卷积在 、 时参数量是标准卷积的几分之几?为什么这个比值随 增大趋近 ?
Q4 为什么说「转置卷积不是卷积的逆」?从信息量角度给一句话理由,并解释它为什么必然带可学习参数。
参考要点
Q1 ,输出 。参数量 。MACs 。
Q2 ;要 得 。改用每两层后接一次 池化:每阶段增量 ,且 每阶段翻倍,从 出发五阶段得 ——10 层就到 284,远超 101。(这正是「下采样让感受野滚雪球」的量级感。)
Q3 ,约 。 时第一项可忽略,比值趋近 :参数量大头是逐点卷积的 ,它与标准卷积的 只差一个 。
Q4 正向卷积把多个不同输入映射到同一输出(多对一),信息在此时不可逆地丢失;转置卷积只把维度放大回来,既不能恢复被平均掉的信息,也无法保证 (卷积矩阵几乎总是奇异的)。它必然带参数,因为 的元素就是原卷积核(翻转后)的元素——上采样层里的「核」与卷积同构;实践中这些权重是另学的一组,所以它同时是可训练的。
- LeCun, Bottou, Bengio & Haffner, Gradient-Based Learning Applied to Document Recognition(1998,Proc. IEEE)——LeNet-5,卷积用于图像识别的奠基文献。
- Simonyan & Zisserman, Very Deep Convolutional Networks for Large-Scale Image Recognition(2014,arXiv:1409.1556)——「小核堆叠」的系统论证。
- He, Zhang, Ren & Sun, Deep Residual Learning for Image Recognition(2015,arXiv:1512.03385)——瓶颈设计与残差块。
- Luo, Li, Urtasun & Zemel, Understanding the Effective Receptive Field in Deep Convolutional Neural Networks(2016,arXiv:1701.04128)——理论感受野与有效感受野的区别。
- Yu & Koltun, Multi-Scale Context Aggregation by Dilated Convolutions(2015,arXiv:1511.07122)——空洞卷积用于分割的原始动机。
- Howard et al., MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications(2017,arXiv:1704.04861)——深度可分离卷积的工程化。
- Lavin & Gray, Fast Algorithms for Convolutional Neural Networks(2015,arXiv:1509.09308)——Winograd 卷积的系统论述。
- PyTorch 文档
torch.nn.Conv2d、torch.nn.functional.unfold、torch.nn.ConvTranspose2d——形状语义以官方文档为准(API 有版本差异,引用时注明版本)。
本节小结:网络里的卷积实际是互相关(命题 3.2.1),与数学卷积只差一次核翻转;输出尺寸、参数量、计算量三条公式 (3.2)、(3.4)、(3.5) 必须能随手手算;感受野按 (3.6) 递推,下采样让感受野近似几何增长而纯堆小核只是线性增长;分组 / 深度可分离卷积用「解耦空间与通道」换来约 的算力;转置卷积是「与卷积梯度同形」的上采样,能放大形状但不能恢复信息。下一节处理卷积之外剩下的零件:池化如何把等变升级为不变,归一化层为什么在训练与推理时行为不同,以及 Dropout 在卷积里为什么必须换一种做法。