观文听傑

返回

上一篇把卷积拆成了局部连接、权重共享与感受野,但它的示例网络用了一个 stride=2 的卷积,直接把 32×32 特征图变成 16×16。空间尺寸减半能大幅节省计算与显存,却也隐藏了一个问题:当新网格不足以表示原特征的快速变化时,被丢掉的高频会伪装成错误的低频图案。

本文只讲透这一次“缩小”:池化(Pooling)、带步幅卷积(Strided Convolution)分别保留什么,为什么先低通再抽样能减少混叠(Aliasing),以及下采样如何生成卷积神经网络(Convolutional Neural Network, CNN)的多尺度特征层次。

01 为什么不一直保留高分辨率?#

设一层卷积的输入为 XRN×Cin×H×WX\in\mathbb{R}^{N\times C_{in}\times H\times W},输出通道数为 CoutC_{out},核为 K×KK×K。忽略常数和内核实现,乘加量约为:

NHWCinCoutK2N H W C_{in} C_{out} K^2

H,WH,W 同时减半,下一层的空间乘加量只剩约 1/41/4,激活张量也从 [N,C,H,W] 变成 [N,C,H/2,W/2]。这使网络能在后面增加通道数和层数,并让每个新位置对应原图上更大的区域。

高分辨率阶段                   下采样                   低分辨率阶段
[N, 64, 56, 56]  ── 低通/聚合 ──► [N, 64, 28, 28] ── 卷积 ──► [N, 128, 28, 28]
  细边缘、小纹理              └─ 网格间距×2              大轮廓、组合模式
  位置多、显存大                                      位置少、单点视野大
text

下采样不是免费压缩。新网格中每个位置要代表更大区域,究竟先聚合哪些信息,决定了小物体、细边缘和纹理是被保留、平滑,还是误读。

02 “隔一个取一个”为什么会创造假图案?#

下采样因子 s=2s=2 表示每两个位置只保留一个:

y[m]=x[2m]y[m]=x[2m]

考察一条交替亮暗信号与它右移一格的版本:

原信号 x:       1 0 1 0 1 0 1 0
取样位置:       ↑   ↑   ↑   ↑       y      = [1, 1, 1, 1]

右移 1 格 x':  0 1 0 1 0 1 0 1
取样位置:       ↑   ↑   ↑   ↑       y'     = [0, 0, 0, 0]
text

输入只移了一格,输出却从全 1 变成全 0。新网格无法表示“每格翻转一次”的变化,于是取样相位决定了看见哪个假的常量。这就是频率混叠:超过新奈奎斯特频率(Nyquist Frequency)的变化,在低分辨率网格上冒充成另一种较慢的模式。

根据采样定理(Sampling Theorem),抽样前应先用低通滤波器(Low-pass Filter)压低新网格无法表示的快速变化:

不抗混叠: x[n] ───────── 每 2 点取 1 点 ──► y[m]   高频折叠到低频

抗混叠:   x[n] ──► 低通 h[n] ──► 每 2 点取 1 点 ──► y[m]
                         先删除新网格表示不了的成分
text

03 用八个数手算“先平滑再抽样”#

对上面的交替信号使用不重叠的两点平均:

y[m]=x[2m]+x[2m+1]2y[m]=\frac{x[2m]+x[2m+1]}{2}
x : [1,0] [1,0] [1,0] [1,0]  ── 每组求平均 ──► [0.5, 0.5, 0.5, 0.5]
x': [0,1] [0,1] [0,1] [0,1]  ── 每组求平均 ──► [0.5, 0.5, 0.5, 0.5]
text

一格位移不再把整个输出翻转。但两点均值只是最简单的盒式滤波器(Box Filter),频率截止并不锐利,且不重叠窗口仍会受分组边界影响。

一个常用的小型平滑核是二项式核(Binomial Kernel):

h=14[1,2,1]h=\frac{1}{4}[1,2,1]

对二维特征图可用可分离外积 H=hhH=h^\top h

H=116[121242121]H=\frac{1}{16} \begin{bmatrix} 1&2&1\\ 2&4&2\\ 1&2&1 \end{bmatrix}

它先将中心与周围邻域做加权平均,再以步幅 2 保留结果。权重和为 1,因此常量区域的幅度不会平白放大或缩小。

04 最大池化与平均池化保留了什么?#

XRN×C×H×WX\in\mathbb{R}^{N\times C\times H\times W}2×2,stride=2 池化不混合通道,只在每个通道的局部窗口聚合:

Yn,c,i,jmax=max0u,v<2Xn,c,2i+u,2j+vY^{max}_{n,c,i,j}=\max_{0\le u,v<2}X_{n,c,2i+u,2j+v} Yn,c,i,javg=14u=01v=01Xn,c,2i+u,2j+vY^{avg}_{n,c,i,j}=\frac{1}{4} \sum_{u=0}^{1}\sum_{v=0}^{1}X_{n,c,2i+u,2j+v}

对窗口 [1270]\begin{bmatrix}1&2\\7&0\end{bmatrix},最大池化输出 7,平均池化输出 2.5。它们对同一邻域做了不同的摘要:

方法窗口内保留什么参数反传到哪里主要风险
最大池化最强响应的幅度0通常只到 argmax 位置一个尖峰/噪声支配,仍可混叠
平均池化局部直流与粗略能量0均匀分给窗口元素边缘、小物体可被模糊
步幅卷积从数据学得的局部组合由学得的核分配核不保证是低通,训练可偏爱高频
低通后抽样可控带宽内的平滑信号可为 0按固定/可学核分配滤波过强会删除任务需要的细纹理

最大池化对窗口内重排不敏感,但它不是标准低通;对交替强弱信号,它仍可在不同取样相位上产生大幅差异。平均池化同时完成粗糙低通和降采样,但其固定权重不会根据任务选择边缘方向。

05 带步幅卷积为何不自动抗混叠?#

带步幅卷积在一步中同时完成局部线性组合和抽样:

Yn,o,i,j=bo+cuvKo,c,u,vXn,c,si+up,sj+vpY_{n,o,i,j}=b_o+ \sum_c\sum_u\sum_v K_{o,c,u,v}X_{n,c,\,si+u-p,\,sj+v-p}

KK 学成平滑核,它可在抽样前压低高频;但训练目标通常只要求降低任务损失,并未约束卷积核的频率响应。一只边缘检测核恰好会放大高频,然后紧接着以步幅 2 抽样,依然可产生混叠。

更清楚的设计是拆开两种职责:

可学特征变换                 明确带宽限制             抽样
Conv2d(stride=1) ──► 非线性 ──► low-pass filter ──► take every 2nd point
[N,Cin,H,W]          [N,Cout,H,W]         [N,Cout,H,W]       [N,Cout,⌈H/2⌉,⌈W/2⌉]
text

这不表示所有 stride=2 卷积都必须替换。它表示当模型对一像素位移过度敏感、输入含周期纹理,或训练与部署缩放链不一致时,“变换”和“抽样”应分开检查。

06 输出尺寸与奇数边长如何处理?#

对核 kk、步幅 ss、补边 pp、空洞率 dd,最大池化和卷积的高度输出公式是:

Hout=Hin+2pd(k1)1s+1H_{out}=\left\lfloor \frac{H_{in}+2p-d(k-1)-1}{s}+1 \right\rfloor

平均池化没有 dilation 参数,令 d=1d=1 即可。对 Hin=7,k=2,s=2,p=0H_{in}=7,k=2,s=2,p=0,默认向下取整得 Hout=3H_{out}=3,最后一行没有进入任何完整窗口。

PyTorch 2.13 当前官方 MaxPool2dAvgPool2d 都提供 ceil_mode=True,允许从左侧补边或有效输入内开始的窗口越过右边界。这能覆盖奇数尺寸的边缘,但也会改变形状规则;与跳连接或分割标签对齐时,必须显式断言。

07 不依赖深度学习框架,先写出一维本体#

下面代码只处理 [L] 信号,用对称补边、二项式低通和步幅 2 抽样暴露数据流:

最后的不等式只是此极小例的回归检查,不是“抗混叠必然位移不变”的定理。补边、非线性、有限核长和后续网络都会影响结果。

08 用 PyTorch 2.13 拆开可学变换与降采样#

先实现一个无可学参数的逐通道模糊下采样层。输入 [N,C,H,W] 使用相同 3×3 核独立处理每个通道,再以 stride=2 抽样:

register_buffer 让固定核随模型进入 state_dict、设备和数据类型,却不会被优化器当成参数。groups=C 是逐通道卷积,它平滑空间维度,不混合通道。这里的零补边是明确取舍;若边界语义重要,可先用 F.pad(..., mode="reflect") 再做 padding=0 的卷积,并重新验证尺寸。

训练时,数据流是 images → transform → blur/downsample → 后续网络 → logits → lossloss.backward() 会穿过固定滤波计算输入和前面可学卷积的梯度,但优化器不会更新 buffer。推理时使用 model.eval()torch.inference_mode();该滤波层本身没有训练/推理两套行为,但同一模型内的批归一化和随机失活有。

09 数据缩放时如何使用官方抗混叠 API?#

对输入图像或连续特征图做明确的尺寸变换时,PyTorch 当前官方 torch.nn.functional.interpolate 提供 antialias=True。对以“批量—通道—高度—宽度”(Batch-Channel-Height-Width, NCHW)排列的四维张量,可写成:

import torch
import torch.nn.functional as F

images = torch.rand(8, 3, 224, 224)
small = F.interpolate(
    images,
    size=(112, 112),
    mode="bilinear",
    align_corners=False,
    antialias=True,
)

assert small.shape == (8, 3, 112, 112)
assert small.dtype == images.dtype
python

当前文档说明 antialias 支持二线性(Bilinear)、双三次(Bicubic)和 Lanczos 模式;对下采样,align_corners=False 与抗混叠的组合还有明确的图像库对齐语义。不要在没有检查模式支持时只是“加上这个参数”。

这个 API 适合尺寸重采样,不会自动学习任务特征。在 CNN 块内,你仍需决定它放在可学卷积之前还是之后,并保证训练、验证和服务端使用同一条缩放链。

10 下采样如何生成多尺度特征层次?#

记第 ll 层感受野为 rlr_l,相邻特征位置在原图上的间距为 jlj_l。沿用上一篇的递推:

rl=rl1+(kl1)dljl1,jl=jl1slr_l=r_{l-1}+(k_l-1)d_lj_{l-1},\qquad j_l=j_{l-1}s_l

一次 2×2,stride=2 池化使 jj 翻倍。后续同样的 3×3 卷积,每次会在原图上扩张更多像素:

层                 张量形状              r(原图感受野)    j(原图间距)
输入               [N,  3, 32,32]          1                 1
Conv 3×3,s=1       [N, 32, 32,32]          3                 1
Pool 2×2,s=2       [N, 32, 16,16]          4                 2
Conv 3×3,s=1       [N, 64, 16,16]          8                 2
Pool 2×2,s=2       [N, 64,  8, 8]         10                 4
Conv 3×3,s=1       [N,128,  8, 8]         18                 4
text

高分辨率层保留精确位置和小边缘,低分辨率层用更少位置表示更大区域和更抽象模式。这就是多尺度特征层次(Multi-scale Feature Hierarchy)。但一旦只保留最深的 8×8 层,小物体可能在早期下采样中消失;后续的上采样无法凭空恢复它。

11 一条可执行的位移敏感调试路径#

  1. 先定位所有降采样点。 搜索 stride>1、池化、interpolate/resize和数据增强,画出从原图到 logits 的尺寸链。
  2. 用可视化的高频输入。 棋盘格、一像素细线和斜条纹能比自然图像更快暴露混叠;逐层保存特征图。
  3. 做一像素压力测试。 将输入上下左右各移一格,忽略补边影响的边缘,比较中间特征和最终概率,不要只比较 argmax 类别。
  4. 只替换一个下采样点。 在相同权重、输入和 eval() 模式下,比较原池化/步幅卷积与低通后抽样,找到第一个过度敏感层。
  5. 同时看任务指标与稳定性。 统计原图与小位移版的 logits 差、一致预测率和分组指标;抗混叠不应以丢掉关键小结构为代价。
  6. 确保对比可复现。 固定随机种子、输入批次和软件版本。官方文档提醒,统一计算设备架构(Compute Unified Device Architecture, CUDA)上的某些卷积与插值反向可为非确定,严格实验要单独配置确定性并记录性能代价。

一个简单的最终表示稳定性指标可写成:

S=1Ni=1Nzizishift2zi2+ϵS=\frac{1}{N}\sum_{i=1}^{N} \frac{\lVert z_i-z_i^{shift}\rVert_2} {\lVert z_i\rVert_2+\epsilon}

ziRKz_i\in\mathbb{R}^{K} 是第 ii 个样本的 KK 维未归一化类别分数(logits),zishiftz_i^{shift} 是位移版输出,ϵ\epsilon 防止分母为 0。SS 越小只表示对该扰动更稳定,不能替代准确率、校准度和任务安全性。

12 最常见的“能跑,但缩错了”#

  • 把步幅当成纯计算优化。 stride=2 改变了采样网格与可表示频率,不是与 stride=1 近似等价的快速实现。
  • 认为最大池化天然平移不变。 窗口内的小移动可保持最大值,但峰值跨过窗口边界就会跳到另一个输出单元。
  • 忽略奇数尺寸。 向下取整、ceil_mode、不对称补边会影响哪一侧被丢掉,并在编码器—解码器或残差分支相加时引发一格错位。
  • 训练和推理的 resize 不一致。 不同图像库、插值模式、align_corners 和抗混叠选项会产生系统性输入偏移。
  • 用循环移位冒充真实平移。 torch.roll 会把右边像素绕回左边;除非数据本来是周期的,否则应用明确补边和裁剪实现位移。
  • 只检查特征图是否“更平滑”。 过强低通可让图看起来干净,却同时删掉微小病灶、细裂纹或文字笔画。

13 它们分别会在哪里失败?#

  • 小目标与密集预测。 目标只有几个像素时,早期降采样可将其整体平均掉;检测、分割和关键点需保留高分辨率分支或融合浅层特征。
  • 纹理本身就是信号。 材料缺陷、显微图像和遥感中的细颗粒可能是分类依据;抗混叠带宽必须用验证集和频段压力测试选择。
  • 单个异常峰值。 最大池化会保留热像素、脉冲噪声或污点,并将大部分梯度集中到它。
  • 边界包含语义。 医学扫描视野、地图瓦片或周期经纬网格需要不同补边;固定零补边可创造虚假边缘。
  • 只追求位移稳定。 姿态估计和像素定位要求的是平移等变(Translation Equivariance),不是所有中间响应不变;终端任务决定该对齐还是该聚合。

14 与相近方法的边界#

方法空间尺寸是否可学抗混叠保证典型用途
MaxPool2d通常减小保留最强局部响应
AvgPool2d通常减小有限的盒式平滑局部均值、全局平均池化
Conv2d(stride=2)减小无显式保证联合学习特征变换和降采样
固定低通 + 抽样减小低通核否由滤波器带宽决定降低位移敏感和高频折叠
interpolate(..., antialias=True)可大可小降采样时显式抗混叠图像/特征尺寸重采样
空洞卷积可保持不是降采样抗混叠方法不减小特征图而扩大理论感受野
自适应池化指定输出不自动保证将不同输入尺寸归约到固定网格/向量

自适应池化的“自适应”指它根据输入尺寸计算窗口与步幅,不是学习参数。空洞卷积虽然也“隔点读取”卷积核,但它通常保留输出网格,与把整张特征图降采样不是一件事。

15 今天真正需要记住什么?#

  1. 下采样将 H×WH×W 减小一半可使后续空间计算约降为 1/41/4,并快速扩大感受野,但它必然改变可表示的空间频率。
  2. 直接隔点取样会让新网格表示不了的高频折叠成假低频;先低通再抽样能减少这种混叠,但不能使信息损失可逆。
  3. 最大池化保留最强局部响应,平均池化做固定局部平滑,步幅卷积学习局部组合;“可学”不等于“必然抗混叠”。
  4. 下采样逐步把精确空间位置换成更大视野与更低成本,从而构成多尺度特征层次;小目标是否在换取中消失必须实测。
  5. 调试时应用棋盘格、一像素平移、逐层形状和 logits 差找到第一个敏感降采样点,并与真实任务指标一起评估。

16 思考题与小练习#

  1. [N=2,C=8,H=15,W=17] 输入使用 MaxPool2d(kernel_size=3,stride=2,padding=1)。分别在 ceil_mode=False/True 下手算输出形状,画出最后一个窗口覆盖了哪些有效位置,再用 PyTorch 断言。
  2. 生成 32×32 棋盘格及其右移一像素版本,比较直接隔点取样、AvgPool2d(2)MaxPool2d(2)BlurDownsample2d。记录四种输出的均方差,解释为什么“输出更接近”不能单独证明任务更好。
  3. 在一个小型 CNN 中只替换第一个 stride=2 层,对验证集的原图、四个一像素平移版和带细纹理子集分别统计准确率与稳定性 SS。哪些结果能支持使用抗混叠,哪些表明低通过强?

相关工作#

17 下一篇预告#

下采样让深层特征拥有大感受野,却可把小物体和精确位置丢在浅层。下一篇将以特征金字塔网络(Feature Pyramid Network, FPN)为主线,追踪自顶向下路径与横向连接如何把深层语义送回高分辨率特征。

特征图减半为何会凭空改变图案?池化、步幅卷积与抗混叠下采样
https://zwjcode.cn/blog/downsampling-pooling-strided-convolution-antialiasing
作者
发布于 2026年9月3日
版权协议 CC BY-NC-SA 4.0
评论加载似乎遇到了问题,请尝试刷新页面。