☰
卷积尺度特性解析:多尺度方案选型与工程排查
2026/9/30 6:33:12 网站建设 项目流程

做视觉、语音或者信号处理的人,几乎都会在某个时刻被同一个问题绊住:模型在验证集上表现很稳,换一张图、换一个拍摄距离、换一台相机,效果就掉得厉害。查来查去,最后大概率都指向同一个根源——卷积的尺度特性。卷积是绝大多数现代感知模型的骨架,但它天生只对"平移"友好,对"尺度"其实相当迟钝。这个结论听起来朴素,可它牵连出来的东西非常多:有效感受野怎么算、空洞卷积的膨胀率怎么配、特征金字塔为什么要做、多尺度训练到底在补什么、球面卷积和自适应图卷积为什么要在意尺度定义,全都从这里长出来。

我打算把自己这几年在检测、分割和音频频谱图上踩过的相关坑,连同背后的数学直觉一起摊开讲。这篇内容会从"卷积和缩放到底能不能交换"这个最基础的问题切入,讲清楚为什么卷积不具备尺度不变性,然后把主流的多尺度方案摆到一张表里做选型对照,最后给一套可以直接跑的验证代码和一份排查清单。不管你是刚学完卷积层池化层全连接层、正准备读卷积神经网络结构图的新手,还是已经能把 3D 卷积自编码器跑起来、想搞清楚多尺度融合细节的老手,应该都能从中挖到点能直接用的东西。我会尽量少摆公式、多讲直觉和参数,把每个选择背后的"为什么"说透。

1. 卷积的尺度特性到底在说什么:从平移等变到尺度敏感

1.1 一个反直觉的对照实验:平移没问题,放大就崩

先做一个几乎不需要代码就能理解的实验。取一张纯色背景上画着细线的图,用最经典的 3x3 拉普拉斯核去卷它。当细线宽度是 1 个像素时,核正对线的位置会给出非常强的响应,因为核的负瓣落在背景上、正中心落在亮线上,差分拉满。现在把整张图放大到 2 倍,细线变成 2 个像素宽。同一个核再卷一遍,会发生什么?中心像素落在了亮线的内部,它左右两侧的邻居也是亮线,负瓣抵掉的能量变少了,响应强度明显下降。如果把图缩小到 0.5 倍,细线可能被重采样糊掉,变成一条灰度渐变带,响应更弱。

整个过程里,那个 3x3 核一个数都没变。这就是卷积对平移天然等变、对尺度却完全不敏感的最小演示。平移等变的意思是:输入平移几个像素,输出跟着平移几个像素,形状一模一样。而尺度不具备这个性质:输入放大 2 倍,输出不是简单地放大 2 倍再乘个系数,形状本身都变了。

很多人的第一反应是"那就把核也放大 2 倍不就行了"。对,思路是对的,这正是后面所有多尺度方案的核心动机。但问题在于:真实数据里尺度的变化是连续且未知的,你不可能为每个可能的缩放都准备一套核。所以工程上我们做的事情,本质上是用有限个尺度的核去近似覆盖连续的尺度空间,或者让核自己去适应尺度变化。理解了这一点,你就能明白为什么图像金字塔、空洞卷积、特征金字塔会被反复发明出来——它们是同一个问题的不同解法。

1.2 连续域里的那条公式:卷积与缩放的交换律

要把这件事说清楚,绕不开一个很短的推导。设 f 和 g 是两个连续信号,g 一般就是卷积核。把两个信号都按同一个因子 a 缩放,定义 f_a(x) = f(ax)、g_a(x) = g(ax),那么有:

(f_a * g_a)(x) = (1 / |a|) · (f * g)(ax)

这条式子说的是:当信号和核一起缩放时,卷积的结果等价于先卷积再缩放,只差一个幅度因子 1/|a|。也就是说,卷积这个运算在"信号与核同步缩放"的变换群下是等变的。这是个好消息,它保证了"正确尺度下用正确尺度的核"能得到自洽的结果。

但工程中我们遇到的情况几乎从来不是这个。真实情况是:信号缩放了,核还是原来那个固定的核。也就是想比较 (f_a * g)(x) 和 (f * g)(ax) 之间的关系。答案是一般没有简单关系。举个极端例子,g 是宽度为 2 的矩形窗,f 是一个冲激。f 是冲激时,(f * g) 就是 g 本身,宽度 2。现在把 f 拉开成两个相距 6 个单位的冲激,而 g 还是宽度 2,卷积结果变成两个互不重叠的矩形,中间是零——它与把原来那个宽度 2 的矩形拉宽到宽度 6 完全不是一回事。核没跟着变宽,中间那段的能量就丢了。

提示:这条式子是判断一切多尺度方案合理性的起点。任何声称"我的方法能处理任意尺度"的方案,要么在某个层面重建了"核随尺度缩放"这件事(显式金字塔、可变膨胀率、可变形采样),要么承认只在某个尺度区间内有效。

1.3 离散网格上的近似:采样误差才是隐藏的成本

连续域里公式还算干净,落到离散网格上麻烦立刻翻倍。第一层麻烦来自重采样:图像放大 2 倍时用的插值方式(最近邻、双线性、双三次、Lanczos)会引入不同的高频失真。最近邻会保留硬边缘但产生锯齿,双三次会平滑边缘。同一张图用两种方式放大后送进同一个网络,特征的差异可能比你想象的大得多。

第二层麻烦来自采样的相位。离散卷积的输出位置是固定在整数网格上的,当你把图放大 1.7 倍这种非整数倍时,原本对齐的目标边界会落到亚像素位置,核的采样点与边界的相对位置整体漂移,导致同一类目标的响应强度在整个数据集上波动。这在检测任务里表现为回归框的不稳定,在分割任务里表现为边界抖动。

第三层麻烦最隐蔽:下采样改变了核的物理尺寸。一个 3x3 的核,在 stride=1 的层上覆盖原图 3 个像素;经过两次 stride=2 下采样之后,特征图上一个位置对应原图 4 个像素,同样一个 3x3 核在这层上实际覆盖原图 12 个像素。也就是说,随着网络变深,核的"物理尺度"在自动变大。这既是好事——高层特征天然对应大物体;也是坏事——同一层里所有尺度共享同一套核,小物体在高层特征图上可能只剩一个点,早就被淹没在背景里了。

2. 为什么卷积天生不具备尺度不变性:三条底层原因

2.1 频域视角:一个核只认一个频带

把信号和核都做傅里叶变换,卷积就变成了逐点相乘。缩放定理告诉我们,空间域按因子 a 缩放,对应频域按 1/a 缩放并且能量乘 1/|a|:F{f(ax)} = (1/|a|)·F(ω/a)。这意味着目标的尺度一变,它在频谱上的能量包络就整体平移了。

而一个固定尺寸的卷积核,等价于一个固定的带通滤波器,它只对某个频段敏感。两者重叠得越多,响应越强。当目标变大,它的主要频率成分往低频跑,如果核的通带还在原来的中频位置,就基本接不到能量。这就是"放大之后模型就瞎了"的频域解释。

这里还有一个绕不过去的约束:不确定性原理。空间的窄核必然对应频域的宽通带,反之亦然。想让一个核同时精确分辨所有尺度,物理上做不到。所以凡是号称单尺度解决多尺度的方案,本质上都是在用一个宽的、各向同性的核去换取尺度容忍度——代价是空间选择性下降,细粒度定位变差。理解这个权衡,你在选核尺寸的时候就不会盲目追大。

2.2 有效感受野视角:理论感受野和实际感受野差了三倍

理论感受野的计算公式很规整:RF_i = RF_{i-1} + (k_i − 1) · S_{i-1},其中 S_{i-1} 是前面所有层 stride 的乘积。按这个公式,一个十几层的网络理论感受野轻松超过整张输入图。但实测中真正的有效感受野要小得多,而且像素的贡献强度大致呈高斯分布——中心区域权重极高,边缘几乎为零。

这件事对尺度特性的影响是直接的:你以为模型在看一个大区域,其实它主要依赖很小的中心区域。当一个目标的尺寸超过了有效感受野,模型只能看到它的局部纹理,判不出整体形状;反之当目标远小于有效感受野,它会被周围大量背景稀释。检测里小目标的召回率上不去,很大一部分原因就出在这儿。

我在一个工业缺陷检测项目里吃过这个亏:理论感受野算下来是 200 多个像素,缺陷最小只有 15 个像素。按照"感受野远大于目标"的直觉应该没问题,可实际漏检率一直卡在 12% 下不来。后来可视化梯度发现,真正有效的响应区只有 60 像素左右,缺陷落在边缘区域时几乎拿不到信号。把骨干换成带跳连的多尺度融合结构之后,漏检降到了 3% 以内。

2.3 采样网格视角:各向异性数据里尺度有多个方向

前面的讨论默认了空间是各向同性的,但很多数据不是。视频、医学体数据、点云、音频频谱图都属于这一类。

拿 3D 卷积神经网络处理 CT 体数据举例:通常层厚方向的分辨率远低于平面内分辨率,常见的是 0.7mm × 0.7mm × 3mm。一个 3x3x3 的各向同性立方核,在这份数据上物理覆盖范围是 2.1mm × 2.1mm × 9mm,层厚方向的物理尺度是平面内的 4 倍多。这意味着模型在层厚方向的"视野"其实大得多,尺度特性在这个方向上完全失衡。同理,3D 卷积自编码器用来做体数据重建时,如果不做重采样或者不使用各向异性的核(比如 3x3x1),重建结果会在层厚方向明显模糊。

音频频谱图上也是同一个问题:时间轴和频率轴的"尺度"物理含义完全不同,同一类声学事件在时间上拉长和频率上移是两件事。做门控卷积这类只沿时间轴建模的结构,是因为研究者发现频率轴上的卷积会破坏谐波结构。这其实是尺度特性在异构坐标上的直接推论——尺度不可比的两个轴,不该共用同一个核。

图结构的尺度定义又是另一套逻辑。图卷积里没有"核尺寸"这个概念,取代它的是邻域跳数 k。自适应图卷积之所以流行,是因为不同节点的最优聚合半径差异极大:社交网络里活跃节点两跳就覆盖上千人,而某些稀疏区域的节点需要更多跳才能触及同等规模。尺度在这里变成了"图上的距离尺度",固定跳数的聚合必然在稠密区过平滑、在稀疏区欠聚合。

影响范围先收一收:尺度特性不只是分类任务的精度问题,它牵动的是所有以卷积为基本算子的任务的泛化半径。目标检测的 anchor 设计、语义分割的边界质量、深度估计的远近一致性、遥感影像的跨分辨率迁移、医学影像的跨设备泛化、全景图上的形变、点云上的密度差异,都能归到这一条线上来。你把这条线捋顺了,很多看起来毫不相关的工程难题会突然变得有迹可循。

3. 多尺度方案选型:四类思路的适用边界对照

3.1 输入侧:图像金字塔与尺度抖动

最朴素也最可靠的办法,是在输入端做文章。测试时把同一张图缩放到多个尺寸各跑一遍,再融合结果,这就是经典的图像金字塔。它的最大优点是不动网络结构、不改预训练权重,随时可以加上去,对已有系统的改造风险最低。老一代检测器基本都靠它撑住多尺度指标。

缺点是成本线性增长。跑 3 个尺度就是 3 倍推理时间,而且不同尺度输出的框要做 NMS 融合,尺度差异大时还容易出现同一目标被拆成多个框。所以实际部署时会限制尺度数量,通常选 0.5、1.0、1.5 或者按数据集的目标尺寸分布扫一遍选几个峰值点,而不是均匀取。

训练侧的对应做法是随机尺度抖动:每张图随机缩放到 [0.6, 1.4] 之间的某个比例再裁到固定尺寸。这个操作的收益在检测和分割上通常比换骨干更明显,代价是 BN 统计量会被不同尺度搅乱,需要配合更大的 batch 或者同步归一化。

注意:尺度抖动的幅度不要凭感觉设。我见过有团队直接开到 [0.3, 2.0],结果小尺度样本把 BN 的方差带偏,训练后期 loss 反复震荡。稳妥的起点是以数据集目标尺寸的中位数为中心,上下浮动 30% 左右,稳定后再逐步放开。

3.2 核侧:空洞卷积、大核与可变形采样

第二类思路改的是卷积核自己。空洞卷积的做法是在核元素之间插入 r−1 个空洞,用一个 3x3 的参数去换取更大的覆盖范围。等效核尺寸的换算是:

k_eff = k + (k − 1) · (r − 1)

一个 3x3、r=2 的核等效于 5x5,r=3 等效于 7x7,参数量和计算量几乎不变。这就是它在分割网络里被广泛采用的原因——在保持分辨率的前提下扩大感受野。

但空洞卷积有一个非常容易踩的坑:网格效应。当连续几层都用同一个膨胀率时,采样点会落在固定的稀疏格点上,中间大片像素永远不参与计算。极端情况下 r 大到一定程度,3x3 核退化成一个十字形的稀疏采样器,小目标恰好落在空隙里就完全没响应。工程上的对策是让连续层的膨胀率互质,比如 1、2、5 或者 1、2、3 交替,保证叠加后采样点是稠密的。

可变形卷积是更激进的版本,它让每个采样点带一个可学习的偏移量,核的形状可以随内容自行弯曲。这对非刚体形变特别有用,代价是额外的偏移量预测分支、更差的算子支持和更明显的过拟合风险。小数据集上慎用。

深度可分离卷积在这里扮演的角色不太一样:它不是解决尺度的,而是让大核变得可负担。把 7x7 甚至 31x31 的大核拆成逐通道卷积加逐点卷积,参数量能降一个数量级,于是"直接用大核换大感受野"这条路重新变得可行。近几年不少工作重新捡起大核卷积,靠的就是这个组合。

3.3 结构与融合侧:金字塔、多分支与跨尺度注意力

第三类思路在网络的层级结构上做文章,也是我个人最推荐的方向,因为它的性价比最高。

空间金字塔池化(SPP)在特征图上用不同尺度的池化窗口并行操作再拼接,让同一层特征携带多个尺度的上下文。空洞空间金字塔池化(ASPP)把它换成了多个不同膨胀率的并行卷积分支,在分割网络里几乎是标配。特征金字塔(FPN)走的是另一条路:把深层语义和浅层细节通过自顶向下的路径加横向连接融在一起,让每一层负责一个尺度区间。HRNet 则反其道而行,全程保持高分辨率并让多分辨率分支反复交换信息。

这里有个容易被忽略的设计要点:每一层该负责哪个尺度区间,是需要和数据的实际目标尺寸对齐的。FPN 的 P3 到 P7 分别对应多大的目标,取决于骨干的 stride 配置和 anchor 设置。如果数据集里 80% 的目标都落在 P4 对应的区间,而你在 P6、P7 上浪费了大量算力,那是明显的配置错位。标注框尺寸统计一下做个直方图,比拍脑袋定 anchor 靠谱得多。

跨尺度融合的另一个技术点是对齐。上采样用最近邻、双线性还是转置卷积,直接影响融合质量。转置卷积如果 stride 和 kernel 配置不当会有棋盘效应,表现为输出图上规则的网格状纹理——本质上是一种因尺度放大方式不当引入的伪影。稳妥做法是双线性上采样加一个 3x3 卷积做平滑,虽然多一层但几乎没有伪影。

3.4 等变与几何侧:球面卷积、对数极坐标与特殊核

第四类思路最"硬核",从变换群的层面重构卷积算子本身。

对数极坐标变换是其中最优雅的一个想法:把图像从笛卡尔坐标映射到 (log r, θ) 空间,此时原图上的缩放就变成了坐标轴上的一维平移。卷积对平移是等变的,那么在这个变换后的空间里做卷积,就等价于在原空间里对尺度等变。这个思路非常漂亮,工程上却受限于极坐标下的采样密度问题——靠近原点处严重过采样,远处欠采样,实现时要做密度补偿。

球面卷积处理的是 360 度全景图像。这类图像在球面上没有天然的"上"和"下",普通卷积在极点附近的形变极其严重,同一个物体在图像中心和边缘的像素尺度能差好几倍。球面卷积通过定义在球面上的旋转群上的卷积核来保证旋转等变,尺度问题在这里表现为球面坐标下不可避免的形变。

社区里还有一些非矩形核的尝试,比如三角核、六边形核这类结构化形状。它们的共同动机是让核的采样点分布更贴合目标的实际几何形态,在特定任务(比如条纹状纹理、方向性结构)上能比方形核更省参数。适用面窄,但思路值得记一笔。

方案类别典型手段尺度处理方式额外成本适用场景
输入侧图像金字塔、尺度抖动显式枚举尺度推理时间线性增长已有系统快速补强、目标尺寸跨度极大
核侧空洞卷积、可变形卷积、大核扩大单个核的覆盖计算量小、显存中等需要保持分辨率的分割任务
结构侧SPP、ASPP、FPN、HRNet分层分工加跨层融合结构复杂度上升检测、分割的通用首选
等变侧球面卷积、对数极坐标改造算子保证等变实现复杂、生态弱全景、遥感、特定几何数据
非欧侧图卷积、自适应图卷积邻域跳数即尺度依赖图构建质量点云、社交网络、分子结构

4. 动手实操:先验证尺度行为,再搭一条多尺度链路

4.1 用几十行代码把卷积的尺度行为看清楚

理论讲完必须落到可观测的现象上。下面这段代码构造一个高斯斑和一个拉普拉斯核,把斑按不同因子缩放,观察同一核的响应怎么变。

import torch import torch.nn.functional as F def make_blob(size=161, sigma=5.0): ax = torch.arange(size).float() - (size - 1) / 2 yy, xx = torch.meshgrid(ax, ax, indexing="ij") g = torch.exp(-(xx ** 2 + yy ** 2) / (2 * sigma ** 2)) return (g / g.sum()).view(1, 1, size, size) lap = torch.tensor([[0., 1., 0.], [1., -4., 1.], [0., 1., 0.]]).view(1, 1, 3, 3) blob = make_blob() for s in [0.5, 0.75, 1.0, 1.5, 2.0, 3.0]: n = int(161 * s) scaled = F.interpolate(blob, size=(n, n), mode="bilinear", align_corners=False) resp = F.conv2d(scaled, lap, padding=1) print(f"scale={s:>4} shape={n:>3} " f"max_abs={resp.abs().max().item():.4f} " f"l1={resp.abs().sum().item():.4f}")

跑出来你会看到两条规律。第一,最大响应绝对值在 scale=1.0 附近达到峰值,往两边都下降,这就是核与目标尺度匹配的窗口效应。第二,响应的 L1 总量随尺度单调变化,因为参与边缘的总面积在变。前者说明"尺度匹配"是真实存在的硬约束,后者提醒你在做多尺度融合时不能直接用响应幅度当权重,得先做归一化。

把lap换成 3x3 均值核再跑一遍,你会发现曲线的峰更宽、更平——这正好印证了不确定性原理那段:模糊的核尺度容忍度高,但空间选择性差。

4.2 量化模型自己的尺度敏感度

验证完算子的行为,下一步是量化你手上模型的尺度敏感度。做法很简单:拿验证集,按一组缩放因子重采样,固定评估协议跑指标,画一条曲线。

import numpy as np import torch SCALES = np.arange(0.4, 2.21, 0.2) # 0.4 到 2.2,步长 0.2 def scale_curve(model, loader, evaluator, device="cuda"): curve = {} for s in SCALES: m = evaluator.reset() for img, target in loader: if s != 1.0: h, w = img.shape[-2:] img = torch.nn.functional.interpolate( img, scale_factor=s, mode="bilinear", align_corners=False) img = img.to(device) pred = model(img) m.update(pred, target, scale=s) curve[round(float(s), 2)] = m.compute() return curve def flatness(curve, key="map"): vals = np.array([curve[k][key] for k in sorted(curve)]) best = vals.max() # 指标保持在峰值 95% 以内的缩放区间长度 width = (vals >= 0.95 * best).sum() / len(vals) return float(width)

flatness这个指标比绝对精度有用得多。它衡量的是"模型能容忍多宽的尺度变化"。实测经验是:只做单尺度训练的检测模型,flatness 通常只有 0.2 到 0.3;加上尺度抖动训练之后能到 0.5 以上;再叠上特征金字塔,可以到 0.7 左右。这条曲线跑一次的成本不高,但能直接告诉你下一步该往训练侧补还是往结构侧补。

实操心得:跑尺度曲线时,缩放后记得同步调整评估时的框匹配阈值逻辑。有些评估器内部按绝对像素设了最小框尺寸限制,缩放后小目标被过滤,曲线会出现假性下跌,白白误导判断方向。

4.3 多尺度训练的落地配置与参数计算

有了敏感度数据,配置就有的放矢了。下面是一份我常用的多尺度训练配置思路,逻辑是先确定目标尺寸分布,再倒推输入尺寸和 anchor 设置。

第一步,统计标注框的宽高。把 sqrt(w·h) 画成直方图,找到 5%、50%、95% 分位数。假设结果是 12、48、260 像素。

第二步,确定网络能覆盖的范围。以 stride 为 8、16、32、64 的四层特征金字塔为例,一层特征图上一个点能覆盖的物理尺寸大致是该层 stride 的 4 到 8 倍(受有效感受野小于理论值的修正)。于是四层大致覆盖 32 到 512 像素,对上面那份分布是够用的。

第三步,确定 anchor 或回归基准尺寸。让四层分别负责 [12, 32]、[24, 64]、[48, 128]、[96, 260] 这几段,层间保留重叠避免出现覆盖空洞。

第四步,确定输入尺寸和尺度抖动幅度。目标中位数 48 像素,如果输入统一到 800x800,则大多数目标占 6% 的图幅。抖动区间设 [640, 960] 对应约 1.5 倍的尺度跨度,先跑通再考虑放开。

import numpy as np def anchor_sizes(median, num_levels=4, stride_base=8, ratios=(1.0, 2.0)): levels = [] for i in range(num_levels): base = median * (2 ** (i - 1)) levels.append([round(base * r, 1) for r in ratios]) return levels print(anchor_sizes(median=48)) # [[24.0, 48.0], [48.0, 96.0], [96.0, 192.0], [192.0, 384.0]]

这套流程的价值在于每一层的尺度分工是有数据支撑的,而不是抄别人的配置。数据集一换,重新跑一遍四步,十分钟的事。

4.4 空洞卷积的膨胀率配置与感受野对照表

空洞卷积的配置错误率极高,这里给一份可以直接对照的计算表。累计感受野按 RF_i = RF_{i-1} + (k_eff_i − 1) · S_{i-1} 递推。

层核膨胀率等效核stride累计感受野
conv13x31313
conv23x31315
conv33x31327
conv43x313111
conv53x313115
conv63x313219
dil13x325135
dil23x337159
def rf_table(layers): rf, s = 1, 1 rows = [] for k, r, st in layers: k_eff = k + (k - 1) * (r - 1) rf = rf + (k_eff - 1) * s rows.append((k, r, k_eff, st, rf)) s *= st return rows cfg = [(3,1,1)]*3 + [(3,1,2)] + [(3,1,1)]*2 + [(3,2,1), (3,3,1)] for row in rf_table(cfg): print(f"k={row[0]} r={row[1]} k_eff={row[2]} s={row[3]} RF={row[4]}")

注意 dil1 和 dil2 用的是 2 和 3,互质,叠加后采样点稠密。如果你把这两层都设成 2,等效核会膨胀得很快但采样是格点状的,中间的空隙在语义分割里会表现为规则排列的孔洞。判断标准很简单:看连续两层的膨胀率是否互质,最大公约数大于 1 就要警惕。

另外,空洞卷积的输出尺寸要保持和输入一致,padding 必须设成 r,而不是固定的 1。这个参数写错会让特征图逐层缩小,很多"训练不收敛"的莫名其妙问题就出在这儿。

5. 常见问题与排查技巧实录

5.1 尺度相关故障速查表

下面这些现象我在不同项目里反复遇到,整理成表方便对照排查。

现象可能原因排查动作处理方式
训练集好、验证集崩验证集存在训练分布外的尺度画验证集目标尺寸直方图与训练集对比补尺度抖动增强,或按尺度分层采样
小目标召回极低有效感受野与小目标不匹配可视化梯度响应区域加高分辨率层、用特征金字塔浅层、降低最小输入尺寸
大目标预测成多个碎块感受野不足、高层语义不够检查高层特征图分辨率增加膨胀率、加深高层、调大 anchor
分割边界呈规则孔洞空洞卷积网格效应检查连续层膨胀率是否互质改成 1、2、5 这类互质组合
放大后的图精度断崖单尺度核与目标频谱错配跑尺度曲线看 flatness多尺度测试融合,或补金字塔结构
上采样出现网格纹理转置卷积配置不当检查 stride 与 kernel 比例换双线性上采样加 3x3 平滑
换分辨率后 BN 层失稳统计量跨尺度不一致对比不同尺度的特征均值方差同步归一化、加大 batch、冻结早期 BN
多尺度融合反而变差各尺度响应幅度未归一化统计各尺度输出分布先归一化再融合,或学权重

5.2 几条用真金白银换来的避坑清单

第一条,尺度增强和批归一化是绑在一起的。只要你在训练里加了尺度抖动,BN 的滑动统计量就会横跨多个分辨率。如果 batch 很小(比如 2 或 4),这些统计量会非常吵,推理时用它们会引入明显偏差。解决办法要么上同步归一化,要么在训练末尾用固定的小尺度抖动再跑几个 epoch 让统计量收敛,要么干脆换成对 batch 不敏感的分组归一化。

第二条,测试时缩放的尺度最好落在训练抖动区间的内部,而不是边界。训练抖动是 [0.6, 1.4],测试你上 1.6,那 1.5 到 1.6 这段就是外推,收益往往为负。我习惯做多尺度测试时选三个点,分别落在区间内的 30%、70% 位置和中心,避开端点。

第三条,别忽略标注本身的尺度一致性。换个数据集、换一批标注员,同样的目标框大小可能差 20%。模型的尺度敏感度有一部分其实是被标注噪声放大的。做尺度曲线之前,先抽 100 张图人工核对一下框的紧致程度,能省掉后面大量的无效调参。

第四条,评估指标对小尺度的敏感度经常不够。总体 mAP 是各尺度平均的结果,小目标的波动可能被大目标的稳定表现掩盖。建议按目标尺寸分层出指标,小、中、大三档分开看,否则你会以为模型没问题。

第五条,非欧数据的尺度问题不要照搬图像上的结论。图卷积里"加大感受野"等价于增加跳数,而跳数一多就会过平滑,所有节点特征趋同。自适应图卷积之所以要动态调整聚合半径,就是为了在稠密区收窄、稀疏区放宽。这跟图像里的多尺度金字塔是同一个哲学,但实现手段完全不同,参数也完全不能互相参考。

第六条,几何形变严重的数据优先考虑算子层面的改造。全景、遥感大幅旋转、球面投影这些场景里,输入侧和结构侧的手段收益有限,因为问题的根源是算子本身的等变性不对。这时候老老实实上球面卷积或者做极坐标变换,比堆十层金字塔管用。

最后说一个我自己的体会。刚接触这个方向时,我总想着找一个"万能的多尺度结构"一劳永逸,试过的方案从金字塔到可变形卷积排了一长串,效果都不稳定。后来慢慢想明白了:尺度特性本质上是一个匹配问题,不是一个建模问题。数据里的目标有多大、分布在哪个区间、有多少外推风险,这些信息决定方案;结构只是用来把这个匹配关系落到参数上的工具。所以我现在的固定动作是先跑尺寸直方图和尺度敏感度曲线这两张图,拿到数据再决定动哪里——大多数时候,改几个增强参数和一个膨胀率,就够了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询