dilation参数控制卷积核元素间的采样间隔步长,而非扩大卷积核尺寸;dilation=2时,3×3核实际感受野为5×5,仅在间隔位置采样,参数量不变。

PyTorch中nn.Conv2d的dilation参数到底控制什么
它不是“扩大卷积核尺寸”,而是控制卷积核元素之间的**间隔步长**。比如dilation=2时,一个3×3卷积核实际覆盖区域是5×5(中间填0),但只在(0,0)、(0,2)、(0,4)…等位置采样,感受野变大,参数量不变。
常见误解是以为dilation会自动调整padding或stride——不会。这三个参数完全正交,需手动协同设计。
-
dilation=1:标准卷积,无空洞 -
dilation>1:引入空洞,感受野指数级增长(尤其堆叠多层时) - 若输入尺寸小、
dilation过大,可能触发RuntimeError: Calculated output size too small
设置dilation时必须同步调整padding才能保持输出尺寸不变
默认padding=0下,增大dilation会让输出尺寸急剧缩小。要维持和dilation=1时相同的输出高宽,得补足因空洞导致的“缺失覆盖”。
通用公式(假设kernel_size=3,stride=1):padding = (dilation * (kernel_size - 1)) // 2
实操建议:
- 直接用
padding=dilation适用于kernel_size=3且stride=1的常见情况(因为(3-1)*dilation//2 == dilation) - 更稳妥写法:
padding = (dilation * (kernel_size - 1)) // 2,避免硬编码 - 别依赖
torch.nn.modules.utils._pair手动算——直接按公式来,清晰且不易错
多层空洞卷积堆叠时,dilation值怎么选才不撑爆内存或失效
典型错误是逐层翻倍设dilation=[1,2,4,8],结果最后一层感受野过大,有效像素极少,梯度稀疏,训练不稳定。
关键约束:
- 确保每层输出尺寸 ≥ 1,否则报错;可用
torch.nn.modules.utils._output_size反推,但更推荐直接试算 - 输入为
H×W,kernel_size=3,stride=1,则第i层要求:H > 2 * dilation_i(近似) - 实践中,
dilation序列常设为[1,1,2,4]或[1,2,2,4],而非严格指数增长 - CPU上
dilation>8可能显著拖慢;GPU上一般支持到64,但访存效率下降明显
验证dilation是否生效:别只看shape,要检查权重连接模式
仅打印layer.weight.shape看不出空洞——它永远显示原始核尺寸(如3×3)。真正区别在前向传播时的采样位置。
快速验证方法:
- 用全1输入(
torch.ones(1,1,7,7))和单通道Conv2d(1,1,3,dilation=2,padding=2),手动算中心点输出应为9(3×3非零权重全参与);若dilation=1,同样padding下中心点输出也是9,但周围点不同 - 调用
torch.jit.trace导出模型后查看IR,能明确看到dilation被编译进底层op - 调试时临时把
weight设为torch.arange(9).view(1,1,3,3).float(),观察输出值是否跳着匹配索引
空洞卷积的“空”不在权重里,而在索引计算逻辑中——这点容易被可视化工具误导。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











