https://zhuanlan.zhihu.com/p/50369448
重要的是感受野
多尺度特征提取:通过不同空洞率的卷积层捕获不同范围的特征
保持空间分辨率:采用适当的padding策略,确保输出特征图尺寸与输入一致
全局上下文信息:通过全局平均池化和上采样,将全局信息融入到局部特征中
特征融合:将多尺度特征在通道维度拼接后通过1x1卷积融合
注意事项
- 批归一化(BatchNorm)的处理
注意事项: 在测试或推理阶段,必须将模型设置为评估模式(eval()),特别是当批次大小为1时。
Apply
# 正确做法
aspp = SimpleASPP(in_channels=256, out_channels=256)
aspp.eval() # 切换到评估模式,避免BatchNorm错误
原因分析: 如代码中的SimpleASPP.__init__所示,每个卷积层后都接了BatchNorm。在训练模式下,BatchNorm需要计算当前批次的均值和方差,当批次大小为1且经过全局平均池化后,每个通道只剩下一个值,会导致 ValueError: Expected more than 1 value per channel when training 错误。
- 空洞卷积的参数设置
注意事项: 空洞率(dilation rate)和padding需要正确匹配,以保持特征图尺寸不变。
# 正确的参数设置
self.conv6 = nn.Conv2d(in_channels, out_channels, 3, padding=6, dilation=6, bias=False)
self.conv12 = nn.Conv2d(in_channels, out_channels, 3, padding=12, dilation=12, bias=False)
self.conv18 = nn.Conv2d(in_channels, out_channels, 3, padding=18, dilation=18, bias=False)
关键公式: 对于3x3卷积,要保持输出尺寸与输入一致,padding值应等于dilation值。这样可以确保不同空洞率的分支输出相同尺寸的特征图,便于后续拼接。
- 全局上下文特征处理
注意事项: 全局平均池化后的特征图需要正确上采样回原始尺寸。
# 全局池化分支的正确处理
x_global = self.global_avg_pool(x) # 输出尺寸: [batch, channels, 1, 1]
x_global = self.conv_global(x_global)
x_global = self.bn_global(x_global)
x_global = self.relu(x_global)
# 必须上采样回原始尺寸
x_global = F.interpolate(x_global, size=original_size[2:], mode='bilinear', align_corners=True)
原因: 全局平均池化会将特征图压缩为1x1大小,必须通过上采样恢复到原始尺寸,才能与其他分支的特征图在通道维度上拼接。
- 输入尺寸的兼容性
注意事项: ASPP模块对输入尺寸有一定要求,尤其是空洞率较大时。
问题分析: 当空洞率很大时,需要确保输入特征图有足够的尺寸。如果输入尺寸太小,可能导致有效感受野超过特征图边界,降低特征提取效果。从代码中的test_aspp_with_different_sizes测试可以看出,该实现能处理从32×32到512×512的不同尺寸输入,但实际应用中需要根据空洞率调整最小输入尺寸。
- 计算资源消耗
注意事项: ASPP模块包含多个并行分支,计算量和参数量较大。
# 最终融合的卷积层,输入通道数是单个分支的5倍
self.conv_final = nn.Conv2d(out_channels * 5, out_channels, 1, bias=False)
优化建议: 在资源受限的环境中,可以考虑减少分支数量或降低单个分支的通道数,但这可能会影响多尺度特征提取的效果。
- 感受野与应用场景匹配
注意事项: 空洞率的选择应与具体任务需求匹配。
# 感受野计算示例(3x3卷积)
receptive_field = 1 + 2 * rate # 代码中的简化公式
应用建议: 不同的应用场景需要不同范围的上下文信息。例如,语义分割中较大的目标需要较大的感受野,而细节分割可能更依赖较小的空洞率。
总结
ASPP模块通过多分支并行结构有效捕获多尺度特征,但在使用时需要特别注意批归一化模式切换、空洞卷积参数匹配、全局特征处理以及输入尺寸兼容性等问题。正确处理这些注意事项,可以充分发挥ASPP模块的多尺度特征提取能力,提高模型性能。