太多了 我都累了 这都第4了
这次先是关于他的小样本目标检测 , 用很少的训练示例检测新目标
小样本目标检测
论文地址:
https://openaccess.thecvf.com/content/CVPR2022/papers/Han_Few-Shot_Object_Detection_With_Fully_Cross-Transformer_CVPR_2022_paper.pdf
小样本目标检测 (FSOD) 旨在使用很少的训练示例检测新目标,最近在社区中引起了极大的研究兴趣。已经证明基于度量学习的方法使用基于双分支的孪生网络对这项任务有效,并计算图像区域和少样本示例之间的相似性以进行检测。
然而,在之前的工作中,两个分支之间的交互只限于检测头,而剩下的数百层用于单独的特征提取。受最近关于视觉转换器和视觉语言转换器的工作的启发,研究者提出了一种新颖的基于完全交叉转换器(Fully Cross-Transformer)的FSOD模型 (FCT),方法是将交叉转换器整合到特征主干和检测头中。提出了非对称批处理交叉注意来聚合来自具有不同批处理大小的两个分支的关键信息。新模型可以通过引入多级交互来改善两个分支之间的少样本相似性学习。PASCAL VOC和MSCOCO FSOD基准的综合实验证明了我们模型的有效性。
以往小样本检测方法大致可以分为俩类:single-branch方法和two-branch方法;前者通常是基于Faster RCNN进行finetuned,需构建multi-class classifier;但该方法针对shot比较少例如1-shot时,较为容易出现过拟合情况;而后者通常时构建siamese网络,分别同时提取query特征和support特征,然后基于metric learning方法比如feature fusion,feature alignment,GCN或者non-local attention来计算俩分支的相似性,由于在Novel类别上无需构建multi-class classifier,所以泛化性更好;俩类方法大致差异如下图所示:
新框架 Task Definition
在小样本目标检测(FSOD)中,有两组类C=Cbase∪Cnovel和Cbase∩Cnovel=∅,其中基类Cbase每个类都有大量训练数据,而新类Cnovel(也称为支持类)只有每个类的训练示例很少(也称为支持图像)。对于K-shot(例如,K=1,5,10)目标检测,研究者为每个新类别c∈Cnovel准确地使用K个边界框注释作为训练数据。FSOD的目标是利用数据丰富的基类来协助检测少样本的新类。
Overview of Our Proposed Model (FCT)
研究者认为以往的two-branch方法只关注了detection head部分的特征交互,忽略了特征提取部分;于是这篇论文的motivation就出来了。因此研究者在Faster RCNN上提出了Fully Cross-Transformer(FCT)的小样本检测方法,在每个阶段都进行特征交互。如下图所示:
The Cross-Transformer Feature Backbone
在cross-transformer中计算Q-K-V attention时为了减少计算量,研究者采用了PVTv2的方式。上面大致介绍了query和support特征提取,在特征交互上作者提出了 Asymmetric-Batched Cross-Attention。具体做法如下图和公式所示:
评论。研究者彻底研究了提出的模型中两个视觉分支之间的多层次交互。cross-transformer特征主干中的三个阶段使两个分支与低级、中级和高级视觉特征逐渐有效交互。
The Cross-Transformer Detection Head
在detection head部分,和以上操作相反,在每张query上提取完proposal之后经过ROI Align可以得到ROI特征fp∈RBp∗H′∗W′∗C3,其中Bp=100,为了减少计算复杂度还是对support进行ave操作fs′=1Bs∑Bsfs,fs′∈R1∗H′∗W′∗C3,然后使用Asymmetric-Batched Cross-Attention计算俩分支attention,不同的是,query分支Bp≥1 and Bs′=1 。 whaosoft aiot http://143ai.com
实验
从上面表格的(c-d)俩行可以看出,使用三阶段训练在2-shot、10-shot上均有提升。
好了开始第二段 RTFormer
丢掉多头机制!百度开源RTFormer , 构建一个超快速语义分割Transformer方案
对于实时语义分割,由于 Transformer 的计算机制耗时,纯基于 CNN 的方法在该领域仍然占主导地位。本文提出了 RTFormer,一种用于实时语义分割的高效双分辨率转换器,与基于 CNN 的模型相比,它在性能和效率之间取得了更好的平衡。
论文链接:https://arxiv.org/abs/2210.07124 [NeurIPS2022]
代码地址:https://github.com/PaddlePaddle/PaddleSeg
尽管Transformer方案在语义分割领域取得了非常惊人的性能,但在实时性方面,纯CNN方案仍占据主流地位。本文提出了一种用于实时语义分割的高效对偶分辨率Transformer方案RTFormer,它具有比CNN方案更佳的性能-效率均衡。
为达成GPU设备上的高推理效率,所提RTFormer采用了线性复杂度的GPU友好注意力模块,同时消除了多头机制。此外,作者发现:跨注意力机制对于全局上下文信息聚合非常有效。多个主流基准数据集(Cityscapes, CamVid, COCOStuff, ADE20K)上的实验结果验证了所提RTFormer的有效性。下图给出了CAMVid数据集上不同方案的性能与推理速度对比,很明显:RTFormer具有最佳的性能-速度均衡。
出发点
ViT技术在CV领域证实其有效性后,相关技术迅速在各个领域取得了一系列的成果。比如语义分割领域的DPT、SegFormer、HRFormer、Segmentor等均取得了非常优异的成绩。但是,相比CNN方案,Transformer方案因自注意力机制问题存在高计算量、高显存占用问题,导致其推理效率明显不如CNN方案。
作者认为:注意力机制在推理效率方面的瓶颈主要源自以下两个维度:
-
现有注意力机制的计算属性对于GPU设备不够友好,如二次复杂度、多头机制;
-
仅在高分辨率特征图实施注意力可能并非最有效捕获长距离上下文关系的方案,这是因为高分辨率特征的单个特征向量的感受野非常有限。
基于上述所提到的两个局限性,本文提出了一种GPU友好的注意力模块与跨分辨率注意力模块,并由此构建了RTFormer。
接下来,我们首先对本文所提GPU友好注意力RTFormer模块进行介绍,然后结合如何基于RTFormer模块构建RTFormer分割架构。
RTFormer block
上图给出了本文所提RTFormer模块示意图,它是一种对偶分辨率模块,它包含两种类型注意力模块。在低分辨率分支,作者采用了GPU友好的注意力模块以捕获高层全局上下文信息,而在高分辨率分支,作者则引入了跨分辨率注意力机制对高层全局上下文信息进行传播扩散,也就是将两个分辨率的特征通过注意力模块进行聚合。
-
它使得矩阵乘操作成为一体且非常适合于GPU设备;
-
它在某种程度上了保持了多头机制的优势。
Cross-resolution Attention 已有研究证实:多分辨率融合对于稠密预测任务非常有效。对于多分辨率架构设计,我们在不同分支独立执行GAF处理,然后再进行信息交互。作者认为:直接在高分辨率特征执行注意力对于全局上下文学习不够高效。为更有效的获得全局上下文信息,作者提出了跨分辨率注意力,它可以充分利用从低分辨率分支学到的高层语义信息。该过程可描述如下:
需要注意的是:考虑到GPU设备的快速推理因素,这里同样消除了多头机制。
RTFormer
上图给出了RTFormer架构示意图,它由Backbone与SegHead两部分构成:
-
Backbone:为提取高分辨率特征所需的局部信息,作者将卷积与所提RTFormer模块进行了组合以构建RTFormer。具体来说,RTFormer的Stem、Stage1以及Stage2部分由卷积与残差模块构成,从Stage3开始采用所提对偶分辨率模块以促进高分辨率分支与低分辨率分支特征的信息交互,在后三个阶段,高分辨率特征的stride保持为8不变,而低分辨率的stride则分别为16、32、32。值得说明的是,Stage分与Stage5由本文所提RTFormer模块构成以促进高效全局上下文建模,而Stage3则仍由残差模块构建。
上表给出了RTFormer-Slim与RTFormer-Base的架构配置信息,很明显,RTFormer的骨*分由5个stage构成,其中3-5stage由对偶分辨率特征构成,在分割头方面,RTFormer引入了DPPM模块进一步提取多尺度特征。
实验
上表与图给出了Cityscapes与CamVid数据集上的性能对比,从中可以看到:
-
在Cityscapes数据集上,在所有实时分割方案中,RTFormer取得了最佳的速度-精度均衡;
-
RTFormer-Slim取得了76.3%mIoU指标且推理速度高达110.0FPS,优于STDC2-Seg75与DDRNet-23-Slim。
-
RTFormer-Base取得了79.3%mIoU指标且推理速度高达39.1FPS,取得了新的SOTA结果。
-
在CamVid数据集上,所提方案仅需ImageNet预训练即取得了82.5%mIoU指标且推理速度达94.FPS,优于采用额外Cityscapes预训练的STDC2-Seg;
-
RTFormer-Slim仅需4.8M参数即取得了81.4mIoU指标且推理速度高达190.7FPS,优于STDC2-Seg与DDRNet-23;
-
从视觉效果方面来看,RTFormer-Base具有更佳的细粒度分解结果。
上表与图给出了ADE20K数据集上不同方案的性能对比,从中可以看到:
-
RTFormer-Base取得了42.1%mIoU指标且推理速度达71.4FPS,优于其他方案;
-
相比DDRNet-23-Slim,RTFormer-SLim取得了36.7%mIoU指标,同时保持相当的速度。
-
从视觉效果可以看到:相比DDRNet-23,所提方案的分割结果具有更好的细节与上下文信息。
代码
本文代码已经开源在PaddleSeg仓库,笔者对其核心code进行摘录如下:
class RTFormer(nn.Layer):
def __init__(self, ...):
super().__init__()
...
def forward(self, x):
x1 = self.layer1(self.conv1(x))
x2 = self.layer2(self.relu(x1))
# stage-3
x3 = self.layer3(self.relu(x2))
x3_ = x2 + F.interpolate(self.compression3(x3), size=paddle.shape(x2)[2:], mode='bilienar')
x3_ = self.layer3_(self.relu(x3_))
# stage-4与stage-5的计算流程类似stage-3
x4_ = ...
x5_ = ...
# SegHead, DAPPM
x6 = self.spp(x5)
x6 = x6 + F.interpolate(x6, size=paddle.shape(x5_), mode='bilinear')
x_out = self.seghead(paddle.concat([x5_, x6], axis=1))
return F.interpolate(x_out, paddle.shape(x)[2:], mode='bilinear')
class ExternalAttention(nn.Layer):
def __init__(self, ...)
super().__init__()
def _act_sn(self, x):
x = x.reshape([-1, self.inter_channels, 0, 0]) * (self.inter_channels ** -0.5)
x = F.softmax(x, axis=1)
x = x.reshape([1, -1, 0, 0])
def _act_dn(self, x):
x_shape = paddle.shape(x)
h, w = x_shape[2], x_shape[3]
x = x.reshape([0, self.num_heads, self.inter_channels //self.num_heads, -1])
x = F.softmax(x, axis=3)
x = x / (paddle.sum(x, axis=2, keepdim=True) + 1e-06)
x = x.reshape([0, self.inter_channels, h, w])
def forward(self, x, cross_k=None, cross_v=None):
x = self.norm(x)
if not self.use_cross_kv:
x = F.conv2d(x, self.k, bias=None, stride=2 if not self.same_in_out_chs else 1, padding=0)
x = self._act_dn(x) # n,c_inter,h,w
x = F.conv2d(x, self.v, bias=None, stride=1, padding=0)
else:
B = x.shape[0]
x = x.reshape([1, -1, 0, 0]) # n,c_in,h,w -> 1,n*c_in,h,w
x = F.conv2d(x, cross_k, bias=None, stride=1, padding=0, groups=B)
x = self._act_sn(x)
x = F.conv2d(x, cross_v, bias=None, stride=1, padding=0, groups=B)
x = x.reshape([-1, self.in_channels, 0, 0])
return x