摘要
一、论文介绍
本文参考的论文主要介绍了DetectoRS模型,一个高性能的目标检测模型。DetectoRS通过引入递归特征金字塔(RFP)和可切换空洞卷积(SAC)两大创新点,显著提升了目标检测的精度。尽管原文并未直接提及SAConv2d模块,但基于对话上下文,我们可以将SAC(Switchable Atrous Convolution,可切换空洞卷积)理解为SAConv2d(Switchable Atrous Convolution 2D)的简化称呼,并据此进行总结。
二、创新点
- 递归特征金字塔(RFP):RFP通过添加反馈连接到特征金字塔网络(FPN),实现了特征的多次递归计算,从而丰富了特征的表示能力。
- 可切换空洞卷积(SAC,即SAConv2d):SAC允许在标准卷积和条件卷积之间进行有效转换,而无需改变任何预训练模型。它通过使用不同的空洞率来卷积相同的输入特征,并利用开关函数来收集结果,从而增强了模型对不同尺度的适应性。
三、方法
在DetectoRS中,SAC被集成到ResNet骨干网络中,替换了其中的3x3卷积层。对于每个SAC层,都附加了两个全局上下文模块,以提供额外的图像级信息。在训练过程中,SAC能够学习如何根据不同的输入特征和空间位置来选择最合适的空洞率,从而实现更准确的特征提取。
在将SAC(即SAConv2d)应用于Yolo11的改进中,我们替换了Yolo11的Bottleneck中的Conv模块为SAC模块。这样做的目的是利用SAC的尺度适应性来增强Yolo11对不同尺寸目标的检测能力。
四、模块作用
- SAC(SAConv2d)模块:通过动态调整空洞率,SAC模块能够更有效地捕捉不同尺度的目标特征。这有助于提升模型对小目标和遮挡目标的检测性能。
- 在Yolo11中的应用:将SAC模块集成到Yolo11的Bottleneck中,可以增强网络对特征的提取能力,从而提高整体的目标检测精度。
五、改进的效果
通过将SAC(即SAConv2d)模块引入Yolo11,我们预期能够观察到以下改进效果:
- 精度提升:SAC模块的尺度适应性有助于模型更准确地检测不同尺寸的目标,从而提高整体的目标检测精度。
- 鲁棒性增强:SAC模块能够处理更复杂的场景,如目标遮挡、背景杂乱等,从而提升模型的鲁棒性。
- 训练效率:尽管SAC模块引入了额外的计算量,但其高效的特征提取能力有助于模型更快地收敛到更低的损失值,从而在一定程度上提高训练效率。
需要注意的是,由于实际改进效果取决于多种因素(如数据集、训练策略等),因此上述预期效果需要在具体实验中进行验证。
论文翻译:《DetectoRS:使用递归特征金字塔和可切换空洞卷积检测目标》
许多现代目标检测器通过使用“多看多想”机制展现出了卓越的性能。在本文中,我们探索了将这种机制应用于目标检测的主干网络设计中。在宏观层面,我们提出了递归特征金字塔(Recursive Feature Pyramid),它将来自特征金字塔网络(Feature Pyramid Networks)的额外反馈连接融入到自下而上的主干层中。在微观层面,我们提出了可切换空洞卷积(Switchable Atrous Convolution),它以不同的空洞率对特征进行卷积,并使用开关函数收集结果。将这两者结合起来,我们得到了DetectoRS,它显著提高了目标检测的性能。在COCO test-dev数据集上,DetectoRS实现了目标检测领域最优的 55.7 % 55.7\% 55.7%的边界框平均精度(box AP),实例分割领域最优的 48.5 % 48.5\% 48.5%的掩码平均精度(mask AP),以及全景分割领域最优的 50.0 % 50.0\% 50.0%的PQ(Panoptic Quality)。代码已公开^{1}。
1 引言
为了检测物体,人类视觉感知通过反馈连接传递高级语义信息,选择性地增强和抑制神经元激活[2,20,21]。受人类视觉系统的启发,“多看多想”机制已在计算机视觉中得到实现,并展现出卓越的性能[5,6,62]。许多流行的两阶段目标检测器,例如Faster R-CNN[62],首先输出目标候选框,然后基于这些候选框提取区域特征以检测物体。沿着同样的方向,Cascade R-CNN[5]开发了一个多阶段检测器,其中后续的检测头使用更具选择性的样本进行训练。这一设计理念的成功激励我们在目标检测神经网络的主干网络设计中探索它。特别是,我们在宏观和微观层面都部署了这一机制,从而提出了DetectoRS,它在保持相似推理速度的同时,显著提高了最先进的目标检测器HTC[8]的性能,如表1所示。
在宏观层面,我们提出的递归特征金字塔(RFP)建立在特征金字塔网络(FPN)[48]的基础上,通过将FPN层的额外反馈连接融入到自下而上的主干层中,如图1a所示。将递归结构展开为顺序实现,我们得到了一个会多次查看图像的目标检测主干网络。与Cascade R-CNN中使用更具选择性的样本训练的级联检测头类似,我们的RFP递归地增强FPN以生成越来越强大的表征。类似于深度监督网络(Deeply-Supervised Nets)[39],反馈连接将直接从检测头接收梯度的特征带回自下而上主干网络的低层,以加快训练速度并提高性能。我们提出的RFP实现了“多看多想”的顺序设计,其中自下而上的主干网络和FPN会多次运行,其输出特征依赖于前一步骤中的特征。
在微观层面,我们提出了可切换空洞卷积(SAC),它以不同的空洞率[12,32,57]对相同的输入特征进行卷积,并使用开关函数收集结果。图1b展示了SAC概念的一个示意图。开关函数是空间依赖的,即特征图的每个位置可能有不同的开关来控制SAC的输出。为了在检测器中使用SAC,我们将自下而上主干网络中的所有标准 3 × 3 3 \times 3 3×3卷积层转换为SAC,这极大地提高了检测器的性能。一些先前的方法采用了条件卷积,例如[43,80],它们也将不同卷积的结果组合为单个输出。与那些需要从头开始训练的架构不同,SAC提供了一种机制,可以轻松地转换预训练的标准卷积网络(例如,ImageNet预训练[63]的检查点)。此外,SAC中使用了一种新的权重锁定机制,其中不同空洞卷积的权重相同,除了一个可训练的差异。
将提出的RFP和SAC结合起来,我们得到了DetectoRS。为了证明其有效性,我们在具有挑战性的COCO数据集[51]上将DetectoRS融入最先进的HTC[8]中。在COCO test-dev数据集上,我们报告了目标检测的边界框平均精度(box AP)[23]、实例分割的掩码平均精度(mask AP)[28]以及全景分割的PQ(Panoptic Quality)[37]。以ResNet-50[30]为主干的DetectoRS显著提高了HTC[8]的性能,边界框平均精度提高了 7.7 % 7.7\% 7.7%,掩码平均精度提高了 5.9 % 5.9\% 5.9%。此外,以ResNeXt-101-64x4d[77]为主干的DetectoRS实现了最优的 55.7 % 55.7\% 55.7%的边界框平均精度和 48.5 % 48.5\% 48.5%的掩码平均精度。结合以Wide-ResNet-41[11]为主干的DeepLabv3+[15]的物体预测,DetectoRS在全景分割领域创造了新的PQ记录,达到 50.0 % 50.0\% 50.0%。
2 相关工作
目标检测。目标检测方法主要分为两大类:一阶方法,例如[40,49,54,60,64,73,86,87],和多阶方法,例如[5,7,8,10,26,27,29,34,62,75]。多阶检测器通常比一阶检测器更灵活、更准确,但也更复杂。在本文中,我们使用多阶检测器HTC [8]作为基线,并与这两类方法进行了比较。
多尺度特征。我们的递归特征金字塔基于特征金字塔网络(FPN)[48],FPN是一种利用多尺度特征的有效目标检测系统。之前,许多目标检测器直接从主干网络[4,54]中提取多尺度特征,而FPN则通过自上而下的路径将不同尺度的特征进行顺序组合。PANet [53]在FPN的基础上增加了另一条自下而上的路径。STDL [88]通过尺度转换模块来利用跨尺度特征。G-FRNet [1]增加了带有门控单元的反馈。NAS-FPN [25]和Auto-FPN [79]使用神经架构搜索[93]来找到最优的FPN结构。EfficientDet [70]提出重复一个简单的BiFPN层。与它们不同,我们提出的递归特征金字塔通过反复遍历自下而上的主干网络来丰富FPN的表示能力。此外,我们将空洞空间金字塔池化(ASPP)[14,15]融入FPN以丰富特征,这与Seamless [59]中的Mini-DeepLab设计类似。
递归卷积网络。许多递归方法已被提出以解决不同类型的计算机视觉问题,例如[35,46,69]。最近,提出了一种用于目标检测的递归方法CBNet [55],该方法将多个主干网络级联以输出特征作为FPN的输入。相比之下,我们的递归特征金字塔(RFP)使用提出的包含ASPP的FPN以及有效的融合模块来执行递归计算。
条件卷积。条件卷积网络采用动态核、宽度或深度,例如[17,43,47,52,80,83]。与它们不同,我们提出的可切换空洞卷积(SAC)允许从标准卷积到条件卷积的有效转换机制,而无需改变任何预训练模型。因此,SAC是许多预训练主干网络的即插即用模块。此外,SAC使用全局上下文信息和一种新颖的权重锁定机制来提高其有效性。
3 递归特征金字塔
3.1 特征金字塔网络
本小节介绍了特征金字塔网络(FPN)的背景。设 B i \mathbf{B}_{i} Bi表示自下而上主干网络的第 i i i阶段, F i \mathbf{F}_{i} Fi表示自上而下FPN的第 i i i个操作。配备FPN的主干网络输出一组特征图 { f i ∣ i = 1 , … , S } \left\{\mathrm{f}_{i} \mid i=1, \ldots, S\right\} {fi∣i=1,…,S},其中 S S S是阶段的数量。例如,在图2a中 S = 3 S=3 S=3。对于 ∀ i = 1 , … , S \forall i=1, \ldots, S ∀i=1,…,S,输出特征 f i f_{i} fi定义为
f i = F i ( f i + 1 , x i ) , x i = B i ( x i − 1 ) \mathbf{f}_{i}=\mathbf{F}_{i}\left(\mathbf{f}_{i+1}, \mathbf{x}_{i}\right), \quad \mathbf{x}_{i}=\mathbf{B}_{i}\left(\mathbf{x}_{i-1}\right) fi=Fi(fi+1,xi),xi=Bi(xi−1)
其中 x 0 \mathbf{x}_{0} x0是输入图像, f S + 1 = 0 \mathbf{f}_{S+1}=\mathbf{0} fS+1=0。建立在FPN上的目标检测器使用 f i \mathbf{f}_{i} fi进行检测计算。
3.2 递归特征金字塔
我们提出的递归特征金字塔(RFP)为FPN添加了反馈连接,如图2b所示。设 R i \mathbf{R}_{i} Ri表示在将其重新连接到自下而上的主干网络之前对特征进行的变换。然后,对于 ∀ i = 1 , … , S \forall i=1, \ldots, S ∀i=1,…,S,RFP的输出特征 f i f_{i} fi定义为
f i = F i ( f i + 1 , x i ) , x i = B i ( x i − 1 , R i ( f i ) ) \mathbf{f}_{i}=\mathbf{F}_{i}\left(\mathbf{f}_{i+1}, \mathbf{x}_{i}\right), \quad \mathbf{x}_{i}=\mathbf{B}_{i}\left(\mathbf{x}_{i-1}, \mathbf{R}_{i}\left(\mathbf{f}_{i}\right)\right) fi=Fi(fi+1,xi),xi=Bi(xi−1,Ri(fi))
这使得RFP成为一个递归操作。我们将其展开为一个顺序网络,即 ∀ i = 1 , … , S , t = 1 , … T \forall i=1, \ldots, S, t=1, \ldots T ∀i=1,…,S,t=1,…T,
f i t = F i t ( f i + 1 t , x i t ) , x i t = B i t ( x i − 1 t , R i t ( f i t − 1 ) ) \mathbf{f}_{i}^{t}=\mathbf{F}_{i}^{t}\left(\mathbf{f}_{i+1}^{t}, \mathbf{x}_{i}^{t}\right), \mathbf{x}_{i}^{t}=\mathbf{B}_{i}^{t}\left(\mathbf{x}_{i-1}^{t}, \mathbf{R}_{i}^{t}\left(\mathbf{f}_{i}^{t-1}\right)\right) fit=Fit(fi+1t,xit),xit=Bit(xi−1t,Rit(fit−1))
其中 T T T是展开迭代的次数,我们使用上标 t t t来表示在展开步骤 t t t时的操作和特征。 f i 0 \mathbf{f}_{i}^{0} fi0设置为 0 \mathbf{0} 0。在我们的实现中, F i t \mathbf{F}_{i}^{t} Fit和 R i t \mathbf{R}_{i}^{t} Rit在不同步骤中是共享的。我们在第5节的消融研究中展示了共享和不同 B i t \mathbf{B}_{i}^{t} Bit的情况,以及不同 T T T值的性能。在我们的实验中,我们使用不同的 B i t \mathbf{B}_{i}^{t} Bit并设置 T = 2 T=2 T=2,除非另有说明。
我们对ResNet[30]主干网络B进行了修改,使其能够同时接收 x \mathbf{x} x和 R ( f ) \mathbf{R}(\mathbf{f}) R(f)作为输入。ResNet有四个阶段,每个阶段都由几个相似的块组成。我们只对每个阶段的第一个块进行了修改,如图3所示。这个块计算一个3层特征,并将其添加到一个由捷径计算出的特征上。为了使用特征 R ( f ) \mathbf{R}(\mathbf{f}) R(f),我们添加了另一个卷积层,并将卷积核大小设置为1。该层的权重初始化为0,以确保当我们从预训练的检查点加载权重时,它不会产生任何实际影响。
我们使用空洞空间金字塔池化(ASPP)[13]来实现连接模块 R \mathbf{R} R,该模块接收一个特征 f i t \mathbf{f}_{i}^{t} fit作为输入,并将其转换为图3中使用的RFP特征。在这个模块中,有四个并行分支以 f i t \mathrm{f}_{i}^{t} fit作为输入,其输出然后沿着通道维度拼接在一起,形成 R \mathbf{R} R的最终输出。其中三个分支使用卷积层后跟ReLU层,输出通道数是输入通道数的 1 4 \frac{1}{4} 41。最后一个分支使用全局平均池化层来压缩特征,然后是一个 1 × 1 1 \times 1 1×1卷积层和ReLU层,将压缩后的特征转换为大小为 1 4 \frac{1}{4} 41(按通道)的特征。最后,将其大小调整并与来自其他三个分支的特征拼接在一起。这三个分支中的卷积层具有以下配置:卷积核大小=[1,3,3],空洞率=[1,3,6],填充=[0,3,6]。与原始ASPP[13]不同,我们没有在拼接后的特征后面添加卷积层,因为在这里 R \mathbf{R} R不生成用于密集预测任务的最终输出。注意,四个分支中的每一个都生成一个通道数为输入特征 1 4 \frac{1}{4} 41的特征,将它们拼接在一起会生成一个与 R \mathbf{R} R输入特征大小相同的特征。在第5节中,我们展示了带有和不带有ASPP模块的RFP的性能。
3.4 融合模块的输出更新
如图2c所示,我们的RFP还使用了一个融合模块来结合 f i t \mathbf{f}_{i}^{t} fit和 f i t + 1 \mathbf{f}_{i}^{t+1} fit+1,以更新等式(3)中使用的展开阶段 t + 1 t+1 t+1时 f i \mathbf{f}_{i} fi的值。如果我们将 f i t \mathrm{f}_{i}^{t} fit视为一系列数据,那么融合模块与循环神经网络[31]中的更新过程非常相似。融合模块用于从第2步到第T步的展开步骤。在展开步骤 t + 1 ( t = 1 , … , T − 1 ) t+1(t=1, \ldots, T-1) t+1(t=1,…,T−1)中,融合模块以第t步的特征 f i t \mathbf{f}_{i}^{t} fit和第t+1步由FPN新计算出的特征 f i t + 1 \mathbf{f}_{i}^{t+1} fit+1作为输入。融合模块使用特征 f i t + 1 \mathrm{f}_{i}^{t+1} fit+1通过一个卷积层后跟Sigmoid操作来计算一个注意力图。得到的注意力图用于计算 f i t \mathbf{f}_{i}^{t} fit和 f i t + 1 \mathbf{f}_{i}^{t+1} fit+1的加权和,以形成一个更新的 f i \mathbf{f}_{i} fi。这个 f i \mathbf{f}_{i} fi将作为 f i t + 1 \mathbf{f}_{i}^{t+1} fit+1用于后续步骤的计算。在第5节的消融研究中,我们将展示带有和不带有融合模块的RFP的性能。
4 可切换空洞卷积
4.1 空洞卷积
空洞卷积[12,32,57]是一种有效的技术,可以扩大任何卷积层中滤波器的视野。特别地,具有空洞率 r r r的空洞卷积在连续滤波器值之间引入 r − 1 r-1 r−1个零,等效于将 k × k k \times k k×k滤波器的核大小扩大到 k e = k + ( k − 1 ) ( r − 1 ) k_{e}=k+(k-1)(r-1) ke=k+(k−1)(r−1),而不增加参数数量或计算量。图1b展示了空洞率设置为1(红色)和2(绿色)的 3 × 3 3 \times 3 3×3卷积层的示例:使用不同的空洞率,通过相同的一组卷积权重可以大致检测到不同尺度的同一类对象。
4.2 可切换空洞卷积
在本小节中,我们将详细介绍我们提出的可切换空洞卷积(SAC)的细节。图4展示了SAC的总体架构,它包含三个主要部分:SAC组件前后附加的两个全局上下文模块。本小节重点关注中间的SAC主要组件,稍后将解释全局上下文模块。
我们使用 y = Conv ( x , w , r ) \mathbf{y}=\operatorname{Conv}(\mathbf{x}, \mathbf{w}, r) y=Conv(x,w,r)来表示具有权重 w \mathbf{w} w和空洞率 r r r的卷积操作,它以 x \mathbf{x} x为输入并输出 y \mathbf{y} y。然后,我们可以将卷积层转换为SAC,如下所示。
Conv ( x , w , 1 ) → 转换为SAC S ( x ) ⋅ Conv ( x , w , 1 ) + ( 1 − S ( x ) ) ⋅ Conv ( x , w + Δ w , r ) \begin{array}{r} \operatorname{Conv}(\mathbf{x}, \mathbf{w}, 1) \xrightarrow[\text { 转换为SAC }]{\text { }} \mathbf{S}(\mathbf{x}) \cdot \operatorname{Conv}(\mathbf{x}, \mathbf{w}, 1) \\ +(1-\mathbf{S}(\mathbf{x})) \cdot \operatorname{Conv}(\mathbf{x}, \mathbf{w}+\Delta \mathbf{w}, r) \end{array} Conv(x,w,1) 转换为SAC S(x)⋅Conv(x,w,1)+(1−S(x))⋅Conv(x,w+Δw,r)
其中,这里的 r r r是SAC的超参数, Δ w \Delta \mathbf{w} Δw是可训练的权重,开关函数 S ( ⋅ ) \mathbf{S}(\cdot) S(⋅)实现为一个带有 5 × 5 5 \times 5 5×5核的平均池化层,后跟一个 1 × 1 1 \times 1 1×1卷积层(见图4)。开关函数依赖于输入和位置;因此,主干模型能够根据需要适应不同的尺度。除非另有说明,否则我们在实验中将 r r r设置为3。
我们提出了一种锁定机制,通过将一个权重设置为 w \mathbf{w} w,另一个权重设置为 w + Δ w \mathbf{w}+\Delta \mathbf{w} w+Δw,原因如下。目标检测器通常使用预训练的检查点来初始化权重。然而,对于从标准卷积层转换而来的SAC层,缺少较大空洞率的权重。由于不同尺度的对象可以通过具有不同空洞率的相同权重来大致检测,因此很自然地使用预训练模型中的权重来初始化缺失的权重。我们的实现使用 w + Δ w w +\Delta \mathbf{w} w+Δw作为缺失的权重,其中 w w w来自预训练的检查点, Δ w \Delta \mathbf{w} Δw初始化为0。当固定 Δ w = 0 \Delta \mathbf{w}=0 Δw=0时,我们观察到平均精度(AP)下降了0.1%。但是,仅使用 Δ w \Delta \mathbf{w} Δw而没有锁定机制会大大降低AP。
4.3 全局上下文
如图4所示,我们在SAC主要组件的前后插入了两个全局上下文模块。这两个模块是轻量级的,因为输入特征首先通过全局平均池化层进行压缩。全局上下文模块与SENet[33]相似,但有两个主要区别:(1)我们只有一个卷积层,没有任何非线性层;(2)输出被加回到主流中,而不是将输入乘以Sigmoid计算的重校准值。通过实验,我们发现将全局上下文信息添加到SAC组件之前(即将全局信息添加到开关函数中)对检测性能有积极影响。我们推测,这是因为当提供全局信息时, S \mathbf{S} S可以做出更稳定的切换预测。然后,我们将全局信息移出开关函数,并将其放置在主体前后,以便Conv和S都可以从中受益。我们没有采用原始的SENet公式,因为我们发现它没有对最终模型的AP产生改进。在第5节的消融研究中,我们展示了带有和不带有全局上下文模块的SAC的性能。
4.4 实现细节
在我们的实现中,我们使用可变形卷积[19,92]来替换等式4中的两个卷积操作。它们的偏移函数是不共享的,在从预训练的主干加载时初始化为预测0。第5节的实验将展示带有和不带有可变形卷积的SAC的性能比较。我们通过替换主干中所有的 3 × 3 3 \times 3 3×3卷积层,在ResNet及其变体[30,77]上采用了SAC。全局上下文模块中的权重和偏置初始化为0。开关 S \mathbf{S} S中的权重初始化为0,偏置设置为1。 Δ w \Delta \mathbf{w} Δw初始化为0。上述初始化策略保证了当在ImageNet[63]上预训练的主干加载时,将所有 3 × 3 3 \times 3 3×3卷积层转换为SAC,在COCO[51]上进行任何训练步骤之前,输出不会改变。
5 实验
5.1 实验细节
我们在COCO数据集[51]上进行了实验。本文提出的所有模型均在包含115k张标记图像的2017年训练集上进行训练。然后,我们在val2017和test-dev上对模型进行测试。我们使用mmdetection[9]实现了DetectoRS。我们的基线模型是HTC[8],它使用数据集中的边界框和实例分割标注。运行时测量是在单张NVIDIA TITAN RTX显卡上进行的。我们严格遵循HTC[8]的实验设置。对于消融研究,我们以0.1的学习率训练模型12个周期,在第8和第12个周期后将学习率乘以0.1。此外,其他训练和测试设置保持不变,未使用任何额外的优化技巧。对于消融研究后的主要结果,我们使用多尺度训练,将长边设置为1333,短边从[400, 1200]中随机采样。我们以0.1的学习率训练模型40个周期,在第36和第39个周期后将学习率乘以0.1。对于ResNeXt-101-32x4d和ResNeXt-101-64x4d,我们使用了Soft-NMS[3]。我们还报告了有无测试时增强(TTA)的结果,测试时增强包括水平翻转和短边设置为[800,1000,1200,1400,1600]、长边设置为1.5倍短边的多尺度测试。
5.2 消融研究
在本小节中,我们在表2和表3中展示了RFP和SAC的消融研究结果。表2显示了以ResNet-50和FPN为骨干网络的基线HTC的边界框和掩码AP。然后,我们将提出的RFP和SAC添加到基线HTC中,两者都能在速度没有大幅下降的情况下将AP提高>4%。将它们组合在一起就构成了我们的DetectoRS,它在3.9 fps的帧率下实现了49%的边界框AP和42.1%的掩码AP。
表3展示了RFP和SAC的单独消融研究,其中我们展示了它们性能提升的来源。对于RFP,我们展示了“RFP + sharing”,其中 B i 1 B_{i}^{1} Bi1和 B i 2 B_{i}^{2} Bi2共享权重。我们还通过展示没有ASPP模块和融合模块的RFP性能(即“RFP - aspp”和“RFP - fusion”),来证明这两个模块带来的改进。最后,我们将展开步长 T T T从2增加到3,得到“RFP +3X”,这进一步将边界框AP提高了1.3%。对于SAC,我们首先在没有DCN[19]的情况下进行实验(即“SAC - DCN”)。然后,我们在“SAC - DCN - global”中证明了全局上下文能够在AP上带来提升。“SAC - DCN - locking”打破了图4中的锁定机制,其中第二个卷积仅使用 Δ w \Delta \mathbf{w} Δw,证明了权重锁定对于SAC是必要的。最后,在“SAC - DCN + DS(dual-switch)”中,我们用两个独立的开关 S 1 ( x ) \mathbf{S}_{1}(x) S1(x)和 S 2 ( x ) \mathbf{S}_{2}(x) S2(x)替换了 S ( x ) \mathbf{S}(x) S(x)和 1 − S ( x ) 1-\mathbf{S}(x) 1−S(x)。表3中的消融研究表明,在我们探索的设计空间中,RFP和SAC的公式具有最佳配置。
图6展示了HTC、“HTC + RFP”和“HTC + SAC”的结果可视化。通过比较,我们发现RFP类似于人类视觉感知,能够选择性地增强或抑制神经元激活,从而更容易找到附近上下文信息更为关键的遮挡物体。SAC则因为其能够根据需要增加视野的能力,更擅长于检测图像中的大物体。这也与表2中SAC的结果一致,SAC具有更高的 A P L \mathrm{AP}_{L} APL。图7展示了HTC、“HTC + RFP”、“HTC + SAC”和DetectoRS的训练损失。它们都能够显著加速训练过程,并收敛到更低的损失。
5.3 主要结果
在本小节中,我们展示了DetectoRS的主要结果。我们将最先进的检测器HTC与DetectoRS相结合,并使用ResNet-50和ResNeXt-101作为DetectoRS的骨干网络。边界框检测结果如表4所示。结果分为4组。第一组展示了一阶段检测器。第二组展示了多阶段检测器。第三组是HTC,即DetectoRS的基线。第四组是我们的结果。结果还可以分为简单测试结果和TTA结果,其中TTA是测试时增强的缩写。第三列显示了是否使用了TTA。请注意,不同的方法使用了不同的TTA策略。例如,CBNet使用了一种强大的TTA策略,可以将其边界框AP从50.7%提高到53.3%。当使用ResNeXt-101-32x4d作为骨干网络时,我们的TTA策略仅带来1.4%的提升。不同检测器的简单测试设置也可能存在显著差异。DetectoRS使用(1333,800)作为测试图像尺寸。更大的输入尺寸往往能带来性能提升(见[70])。DetectoRS采用了与HTC相同的设置。
我们还展示了表5中的实例分割结果。由于表4中的许多方法没有在其论文中提供掩码AP,因此我们仅将DetectoRS与其基线HTC进行比较。边界框和掩码对象检测的实验设置相同,只是我们报告的是 A P mask \mathrm{AP}_{\text {mask}} APmask而不是 A P bbox \mathrm{AP}_{\text {bbox}} APbbox。从表5中可以看出,与边界框结果一致,DetectoRS在实例分割任务上也显著超过了其基线。
最后,表6展示了全景分割结果。由于DetectoRS仅检测物体,因此我们使用DeepLabv3+[15]和骨干网络Wide-ResNet-41[11, 76, 84]进行背景预测。通过在不调整任何超参数的情况下使用panoptic API[37]中提供的脚本将物体和背景预测相结合,我们在COCO上设置了一个新的全景分割PQ最高值,为50.0%。
5.4 可视化学习到的开关
图8展示了表3中“SAC - DCN”的最后一个开关函数输出的可视化结果。图中较暗的强度表示该区域的开关函数从较大的空洞率中收集了更多的输出。将开关输出与原始图像进行比较,我们观察到开关输出与真实物体尺度很好地对齐。这些结果表明,可切换空洞卷积的行为与我们的直觉一致,即在遇到大物体时倾向于使用较大的空洞率。
6 结论
在本文中,受“多看多想”设计理念的启发,我们提出了DetectoRS,它包括递归特征金字塔(RFP)和可切换空洞卷积(SAC)。递归特征金字塔在宏观层面上实现了“多想”,通过反馈连接将FPN的输出带回自下而上骨干网络的每个阶段。可切换空洞卷积在微观层面上实现了“多看”,对输入使用两个不同的空洞率进行卷积。DetectoRS在COCO数据集上进行了对象检测、实例分割和全景分割测试,并在所有这些任务上取得了新的最优结果。
代码
class ConvAWS2d(nn.Conv2d):def __init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True):super().__init__(in_channels,out_channels,kernel_size,stride=stride,padding=padding,dilation=dilation,groups=groups,bias=bias)self.register_buffer('weight_gamma', torch.ones(self.out_channels, 1, 1, 1))self.register_buffer('weight_beta', torch.zeros(self.out_channels, 1, 1, 1))def _get_weight(self, weight):weight_mean = weight.mean(dim=1, keepdim=True).mean(dim=2,keepdim=True).mean(dim=3, keepdim=True)weight = weight - weight_meanstd = torch.sqrt(weight.view(weight.size(0), -1).var(dim=1) + 1e-5).view(-1, 1, 1, 1)weight = weight / stdweight = self.weight_gamma * weight + self.weight_betareturn weightdef forward(self, x):weight = self._get_weight(self.weight)return super()._conv_forward(x, weight, None)def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict,missing_keys, unexpected_keys, error_msgs):self.weight_gamma.data.fill_(-1)super()._load_from_state_dict(state_dict, prefix, local_metadata, strict,missing_keys, unexpected_keys, error_msgs)if self.weight_gamma.data.mean() > 0:returnweight = self.weight.dataweight_mean = weight.data.mean(dim=1, keepdim=True).mean(dim=2,keepdim=True).mean(dim=3, keepdim=True)self.weight_beta.data.copy_(weight_mean)std = torch.sqrt(weight.view(weight.size(0), -1).var(dim=1) + 1e-5).view(-1, 1, 1, 1)self.weight_gamma.data.copy_(std)class SAConv2d(ConvAWS2d):def __init__(self,in_channels,out_channels,kernel_size,s=1,p=None,g=1,d=1,act=True,bias=True):super().__init__(in_channels,out_channels,kernel_size,stride=s,padding=autopad(kernel_size, p, d),dilation=d,groups=g,bias=bias)self.switch = torch.nn.Conv2d(self.in_channels,1,kernel_size=1,stride=s,bias=True)self.switch.weight.data.fill_(0)self.switch.bias.data.fill_(1)self.weight_diff = torch.nn.Parameter(torch.Tensor(self.weight.size()))self.weight_diff.data.zero_()self.pre_context = torch.nn.Conv2d(self.in_channels,self.in_channels,kernel_size=1,bias=True)self.pre_context.weight.data.fill_(0)self.pre_context.bias.data.fill_(0)self.post_context = torch.nn.Conv2d(self.out_channels,self.out_channels,kernel_size=1,bias=True)self.post_context.weight.data.fill_(0)self.post_context.bias.data.fill_(0)self.bn = nn.BatchNorm2d(out_channels)self.act = Conv.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()def forward(self, x):# pre-contextavg_x = torch.nn.functional.adaptive_avg_pool2d(x, output_size=1)avg_x = self.pre_context(avg_x)avg_x = avg_x.expand_as(x)x = x + avg_x# switchavg_x = torch.nn.functional.pad(x, pad=(2, 2, 2, 2), mode="reflect")avg_x = torch.nn.functional.avg_pool2d(avg_x, kernel_size=5, stride=1, padding=0)switch = self.switch(avg_x)# sacweight = self._get_weight(self.weight)out_s = super()._conv_forward(x, weight, None)ori_p = self.paddingori_d = self.dilationself.padding = tuple(3 * p for p in self.padding)self.dilation = tuple(3 * d for d in self.dilation)weight = weight + self.weight_diffout_l = super()._conv_forward(x, weight, None)out = switch * out_s + (1 - switch) * out_lself.padding = ori_pself.dilation = ori_d# post-contextavg_x = torch.nn.functional.adaptive_avg_pool2d(out, output_size=1)avg_x = self.post_context(avg_x)avg_x = avg_x.expand_as(out)out = out + avg_xreturn self.act(self.bn(out))