论文阅读|新的目标检测思路之DETR

论文相关信息

1.论文题目:End-to-End Object Detection with Transformers

2.发表时间:202005/

3.文献地址:https://arxiv.org/abs/2005.12872
4.论文源码:https://github.com/facebookresearch/detr

Transformer

文章总使用到了Transformer,是NLP中十分流行的结构,最先出现在[Attention is All you Need](Paper (neurips.cc))这篇论文中,这里简单的介绍下Transformer。

在这里插入图片描述

上图是Transformer的一个结构示意图,

有关transformer部分需要去查下博客来补充这部分知识。

介绍

本文介绍的目标检测方法提出将NLP领域广泛使用的Transformer应用到CV领域,这种创新使得其一出现就获得广大关注。和其他目标检测论文不同的是,这不再是换一换backbone,加一加FPN的工作,而是将目标检测看做是一个基于集合的索引问题,从而简化了目标检测的工作流程。

论文提出一种新的思路,将目标检测视为一个集合预测问题。该方法简化了目标检测流程,省去了手工设计的如NMS和先验框等操作。该架构的主要成分为DEtection TRansformer(DETR),DETR使用基于集合的全局损失函数,通过二分匹配和Transformer的编解码结构得到检测结果。给定一个固定的目标查询集合,DETR通过目标对象的关系及图像中的上下文信息,并行输出检测结果。模型的概念简单,不需要特定的库,在COCO数据集上能够和已经完善和高度优化Faster R-CNN差不多的性能。

目标检测的目的是为图像中每个感兴趣目标预测一组边界框及相应类别。然后,当前大多目标检测方法通过回归和分类获得最终的检测结果。但作者指出,模型性能会严重受到后处理的影响。比如在处理近似重叠的目标时,先验框的设置并不能同时满足二者的检测需求。论文提出的方法简化了目标检测流程,该方法已经在诸如机器翻译和语义识别上大获成功。前人也有将其运用于目标检测中,但都是通过添加大量的先验知识或并没有取得如期的结果,这篇论文将补上这些短板。

DETR将检测视为集合预测问题,简化了目标检测的整体流程。采用了基于transformers的 自编码结构,这种结构在序列化预测中很流行。transformers的self-attention机制明确地确定了序列中元素间的交互关系,这使得该架构适用于有特定约束条件(如移除重复的预测)的集合预测

在这里插入图片描述

图1.DETR通过将CNN与transformer结构结合,能够直接预测得到最终的预测集。训练时,二分匹配给真实框分配一个唯一的预测。没有分配给真实框的预测对应“无物体”类别。

​ 图1是DETR的检测流程,一次可以预测多个物体,训练时是end-to-end的,并且采用了结合二分匹配(bipartite matching)的损失函数集。DETR不需要任何定制的layer,文章的实现就是直接使用的标准库中的ResNet和Transformer结构实现的,所以容易复现。

与其他的集合预测问题相比,DETR的一大优势是将二分匹配损失函数和带有并行解码器的transformer结合,从而可以并行处理。该损失函数将预测结果唯一地与标注信息匹配,因而可以实现并行预测。
在这里插入图片描述

与改进过很多次的Faster R-CNN相比,DETR在大目标上表现更好,在小目标上表现不好。这一问题,期待之后通过FPN等来解决。

DETR的设计思想容易扩展到其它的复杂任务,如应用到像素集Panoptic Segmentation(全景分割)任务上时,其上表现优于许多的基准算法。

更新:(新的理解)

以图2分析,CNN部分是提取特征图,即得到一个相对输入图片来说尺寸更小,通道更多的特征图,然后将该特征图flatten成H×W个C维的特征向量,这些特征向量传入transformer encoder做编码信息,可以理解为将特征向量进一步加工,输出信息量更好的特征向量,注意,输出的特征向量和输入的尺寸数量一样,还是H×W个C维的特征向量,然后再将这些向量传入transformer decoder做解码,和这些向量一起作为输入的还有N个object queries,实际上也就是N向量,代表一副图像中能预测的最大物体数量,这些向量开始是随机初始化的,每个向量都和前面的特征向量单独交互,decoder输出优化后的object queries,每个object queries再经过FFN解析得到分类和边框结果作为预测,这样就有N个预测,每个预测是一个tuple:(类别 c i ​ c_i​ ci的概率 p ^ σ ( i ) ( c i ) ​ \hat{p}_{\sigma(i)}(c_i)​ p^σ(i)(ci),预测的4维归一化后的边框坐标 b σ ( i ) ^ ​ \hat{b_\sigma(i)}​ bσ(i)^),将图像中的真实物体的向量扩充为N个(如果本来就有N个就不扩充,扩充的默认为背景),然后使用bipartite match做分配得到1对1分配,即通过匈牙利算法优化来让得到N对匹配的匹配总损失最小,这一步也就是论文总说的通过集合预测损失得到预测结果和真实框的一对一匹配。匹配完成后针对特定的物体优化集合预测损失。inference时只输出匹配的对中有物体的预测。

Related work

DETR是基于这些工作构建的:bipartite matching losses(二分匹配损失),set prediction(集合预测),encoder-decoder architectures based on the transformer(基于transformer的编码解码架构),parallel decoding(并行解码),object detection methods(目标检测的方法)。

Set Prediction

在深度学习中,没有特定的结构用于直接集合预测。最典型的集合预测任务当属多标签分类问题,但这类方法不可以直接迁移到目标检测中(目标检测中还需要对目标进行定位)。这类任务中首要问题是重复检测,当前目标检测方法使用的是非极大值抑制。但集合预测不需要后处理,它通过全局推理来预测元素之间的关系。可以使用密集全连接网络预测固定大小的集合,但会带来庞大的计算量。一种可能的解决办法是使用自递归序列模型( autoregressive sequence models),如循环神经网络。在这种情况下,损失函数应该对预测目标保持不变,一种解决办法是使用匈牙利算法设计损失函数来唯一匹配预测结果和标注信息。与以往方法不同的是,论文没有采用自回归模型( autoregressive models),而是使用了带并行编码器的Transformer模型。

Transformers and Parallel Decoding

Transformers最初是被作为一种attention-based building block引入机器翻译的。Attention mechanisms 是一个神经网络层,用于聚合整个输入序列的信息。 Transformers 引入了self-attention layer,它从整个序列聚合信息然后更新序列中的每个元素。居于attention的模型的一个主要优势是它们的全局计算和完美的内存,这使得它们比RNNs更适合长序列。Transformer正在许多自然语言处理、语音识别和计算机视觉任务中取代RNNs。

同早期的序列模型一样,Transformers首先使用自回归模型逐个的生成输出tokens。但是由于其inference花费太大(与输出成比例),所以出现了parallel sequence generation并行序列生成。DETR则是结合了transformers和parallel decoding,因为他们在计算成本和用于集合预测的全局计算间取得了适当的平衡。

Object detection

相关工作部分主要介绍了前人基于集合预测的目标检测方法,前文已经提到,大多数工作都要大量的人为的先验信息,这在一定程度上限制了网络的学习能力。

The DETR model

用于检测的直接集合预测有两个核心部分:(1)一个集合预测损失函数,实现预测内容和标注信息的唯一匹配;(2)一个架构,预测一系列目标,并确定他们的关系,可见下面的图2。

Object detection set prediction loss

DETR会推断出一个固定的N个预测的集合(N远大于一张图片中的目标数量)。然后接下里就是在训练时,如何判断预测结果相对于其ground truth的得分(包括类别、位置和尺寸)。通过loss产生预测结果和ground truth objects的最佳二分匹配,然后针对有物体的预测计算其边框位置损失。

y y y指代ground truth目标集合, y ^ = y ^ i = 1 N \hat{y}={\hat{y}}_{i=1}^N y^=y^i=1N 表示N个预测结果,假设N远大于图片中目标的数量,同样,将 y y y的尺寸也扩充到N(扩充部分为"无物体"∅)。为了找到这两个集合间的二分匹配,定义:

σ ^ = arg ⁡ σ ∈ N m i n ∑ i N L m a t c h ( y i , y ^ σ ( i ) ) , \hat{\sigma}=\arg\limits_{\sigma\in N} min\sum_{i}^NL_{match}(y_i,\hat{y}_{\sigma(i)}), σ^=σNargminiNLmatch(yi,y^σ(i)), (1)

其中 L m a t c h ( y i , y ^ σ ( i ) L_{match(y_i,\hat{y}_{\sigma(i)}} Lmatch(yi,y^σ(i)是一对ground truth y i y_i yi和预测结果 σ ( i ) \sigma(i) σ(i)之间的匹配代价(match cost)。优化的匹配过程通过匈牙利算法计算。匹配代价同时考虑了类别预测以及预测和真实框之间的相似性。 y i = ( c i , b i ) y_i=(c_i,b_i) yi=(ci,bi)代表每个真实物体i,其中 c i c_i ci代表类别(如果是填充的无物体则类别为空 ∅ \empty ), b i ∈ [ 0 , 1 ] 4 b_i\in[0,1]^4 bi[0,1]4代表真实框,定义了真实框的中心坐标和其相对于图片尺寸的宽和高(四个坐标为百分比)。对于第 σ ( i ) \sigma(i) σ(i)个预测定义其为类别 c i c_i ci的概率为 p ^ σ ( i ) ( c i ) \hat{p}_{\sigma(i)}(c_i) p^σ(i)(ci),预测的边框为 b σ ( i ) ^ \hat{b_\sigma(i)} bσ(i)^。于是将 L m a t c h ( y i , y σ ( i ) ^ ) Lmatch(y_i,\hat{y_\sigma(i)}) Lmatch(yi,yσ(i)^)定义为

L m a t c h ( y i , y σ ( i ) ^ ) = − 1 { c i ≠ ∅ } p ^ σ ( i ) ( c i ) + 1 { c i ≠ ∅ } L b o x ( b i , b ^ σ ( i ) ) Lmatch(y_i,\hat{y_\sigma(i)})=-1_{\left\{c_i\ne\empty\right\}}\hat{p}_{\sigma(i)}(c_i)+1_{\left\{c_i\ne\empty\right\}}L_{box}(b_i,\hat{b}_{\sigma(i)}) Lmatch(yi,yσ(i)^)=1{ ci=}p^σ(i)(ci)+1{ ci=}Lbox(bi,b^σ(i)) , (2)

这个匹配的过程和其它的目标检测器中给proposal或anchor分配给ground truth object的过程一样,主要的区别是这里是一个1对1 的匹配,是集合预测,每个ground truth只有一个预测,没有重复。

接着是计算损失函数,使用匈牙利损失计算前面一步中计算得到的所有配对。损失函数的定义如下:

L H u n g a r i a n ( y , y ^ ) = ∑ i = 1 N [ − l o g p ^ σ ^ ( c i ) + 1 { c i ≠ ∅ } L b o x ( b i , b ^ σ ( i ) ) ] L_{Hungarian}(y,\hat{y})=\sum_{i=1}^N[-log\hat{p}_{\hat{\sigma}}(c_i)+1_{\left\{c_i\ne\empty\right\}}L_{box}(b_i,\hat{b}_{\sigma(i)})] LHungarian(y,y^)=i=1N[logp^σ^(ci)+1{ ci=}Lbox(bi,b^σ(i))] , (3)

其中 σ ^ \hat{\sigma} σ^是前面计算得到的最佳匹配。实际中,为了抑制class imbalance,我们使用给 c i = ∅ c_i=∅ ci=以因子10来降权。对于真实物体和预测为无物体间的匹配,其match cost为一个常数,和其预测无关。

Bounding box loss:匹配损失和匈牙利损失的第二部分是 L b o x ( ⋅ ) L_{box}(·) Lbox()给边框打分。对于回归损失项,以前的目标检测算法的回归目标大都是预测值相对于标注信息的偏移,而文中使用的是直接回归的方式。其回归损失采用的 l 1 l_1 l1损失和GIoU损失的结合。定义如下:

L b o x ( b i , b ^ σ ^ ( i ) ) = λ i o u L i o u + λ L 1 ∣ ∣ b i − b ^ σ ( i ) ∣ ∣ L_{box}(b_i,\hat{b}_{\hat{\sigma}(i)})=\lambda_{iou}L_{iou}+\lambda_{L1}||b_i-\hat{b}_{\sigma(i)}|| Lbox(bi,b^σ^(i))=λiouLiou+λL1bib^σ(i), (4)

其中 λ i o u , λ L 1 ∈ R \lambda_{iou},\lambda_{L1}\in R λiou,λL1R是超参数。这两个损失都使用通过一个batch中物体的数量归一化。

DETR architecture

在这里插入图片描述

图2.DETR的整体结构。DETR使用一个传统的CNN骨干网学习输入图片的一个2D表示。通过flattens得到一个1维向量,再以一个位置编码做增强补充,然后送入transformer encoder中。transformer decoder把少量的位置嵌套(positional embeddings)作为输入, 这些嵌套也叫object queries,也被用作为decoder的输出。最后会将这些decoder的输出传入一个共享的前馈网络(feed forward network FFN)预测是否结果有要检测的物体,或者没有物体。

DETR的整体架构简单,如上图所示,分为三部分:CNN backbone,encoder-decoder transformer,一个简单的前馈网络(feed forward network/FFN)。DETR的实现很简单,只需要调用框架中的标准CNN和transformer架构即可,在pytorch中使用DETR来infer时代码可以少于50行。

Backbone:输入初始图片 x i m g ∈ R 3 × H 0 × W 0 x_{img}\in R^{3×H_0×W_0} ximgR3×H0×W0,生成一个低分辨率的特征 f ∈ R C × H × W f\in R^{C×H×W} fRC×H×W。通常C=2048,H,W= H 0 / 32 , W 0 / 32 H_0/32,W_0/32 H0/32,W0/32

Transformer encoder:首先通过一个1×1 的卷积来减少backbone输出 f f f的通道数,由C变为D,然后得到新的特征图 z 0 ∈ R d × H 0 × W 0 z_0\in R^{d×H_0×W_0} z0Rd×H0×W0,encoder期待的是一个序列的输入,因此需要将特征图变化为一个空间上1维,通道数为d×HW的特征图。每个encoder层都有一个标准的架构,且由一系列的multi-head self-attention模块和前馈网络FFN组成。因为transformer架构是置换不变的,所以给增加了一个固定的位置编码,添加到每一个attention 层的输入中。(由于在这里,CNN没有提取图像中目标的位置信息,这里在输入编码器前加入一个可学习的位置信息,即位置编码。位置编码的概念来自NLP,是Transformer中为了表征序列中各元素之间的位置信息,相关的内容可以参考transformer论文或源码)

Transformer decoder:在解码器阶段,我们看到解码器的输入编码的输入外,还有一个名为目标查询的输入,这和Transformer的结构相对应,这表示N NN个论文中所预测目标。最后通过FFN产生边界框的坐标和类别信息。(每个预测目标单独使用一个FFN,通过并行处理,因此权重是共享的)通过编解码器的注意力机制,模型可以通过图像的全局信息来推理出预测内容和标注信息对。这就使得整个模型具有检测的功能。

上面提到的FFN其实是一个带有ReLU激活函数、d个隐藏层单元的三层感知机。FFN预测边界框的归一化信息,并通过softmax层预测类别信息。由于模型得到的固定大小N(大于图像中目标数)的预测结果,那些不带有类别的结果就类似于预测结果为背景。最后,用于本文的结构其实是这样的:

在这里插入图片描述

图3.transformer的结构。

pytorch实现的infer代码示例:

1 import torch
2 from torch import nn
3 from torchvision.models import resnet50
4
5 class DETR(nn.Module):
6
7 def __init__(self, num_classes, hidden_dim, nheads,
8 num_encoder_layers, num_decoder_layers):
9 super().__init__()
10 # We take only convolutional layers from ResNet-50 model
11 self.backbone = nn.Sequential(*list(resnet50(pretrained=True).children())[:-2])
12 self.conv = nn.Conv2d(2048, hidden_dim, 1)
13 self.transformer = nn.Transformer(hidden_dim, nheads,
14 num_encoder_layers, num_decoder_layers)
15 self.linear_class = nn.Linear(hidden_dim, num_classes + 1)
16 self.linear_bbox = nn.Linear(hidden_dim, 4)
17 self.query_pos = nn.Parameter(torch.rand(100, hidden_dim))
18 self.row_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))
19 self.col_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))
20
21 def forward(self, inputs):
22 x = self.backbone(inputs)
23 h = self.conv(x)
24 H, W = h.shape[-2:]
25 pos = torch.cat([
26 self.col_embed[:W].unsqueeze(0).repeat(H, 1, 1),
27 self.row_embed[:H].unsqueeze(1).repeat(1, W, 1),
28 ], dim=-1).flatten(0, 1).unsqueeze(1)
29 h = self.transformer(pos + h.flatten(2).permute(2, 0, 1),
30 self.query_pos.unsqueeze(1))
31 return self.linear_class(h), self.linear_bbox(h).sigmoid()
32
33 detr = DETR(num_classes=91, hidden_dim=256, nheads=8, num_encoder_layers=6, num_decoder_layers=6)
34 detr.eval()
35 inputs = torch.randn(1, 3, 800, 1200)
36 logits, bboxes = detr(inputs)

Experiments

部分实现的细节:

数据集COCO2017detection and panoptic segmentation datasets.118k训练图片和5k验证图片。

骨干网:ResNet-50和ResNet-101,分别对应DETR和DETR-R101

数组增强由scale augmentation和random crop augmentations

首先设备劝退:16V100 GPUs,300epochs训练了3天,每个GPU4张图片。

在这里插入图片描述

图4。与faster rcnn的实验对比。Conclusion

文章提出了一个新的基于transformers和用于直接集合预测的二分匹配损失的目标检测架构。该检测架构再COCO数据集上取得了和当前优化后的Faster RCNN相当的检测结果,论文中使用的DETR仅是普通CNN,Transformer和FFN的结合,类似于目标检测中的主干网络、网络颈以及网络头,期间不添加其他的操作。论文的关键是将特征输入Transformer后依旧要保持目标的位置信息以及最后通过合适的方法将预测结果同标注信息匹配。总的来说,这是当前目标检测领域内比较新的一种思路。同时在论文中,作者也提出为原始模型中加入FPN以改善小目标的检测结果。

论文提供了一种新的目标检测思路(基于transformer),这也为NLP和CV领域idea 的转化提供了一种思路。

最后论文中也提到了目前DETR在小目标检测这一块由明显的不足,之后可以在小目标检测上结合其它检测器的处理方法(如FPN等)来解决这个问题。

参考:
https://www.bilibili.com/video/BV1Qg4y1B7rL?from=search&seid=16317708109550808656

我的大师兄博客:(二十三)论文阅读 | 目标检测之DETR_Skies_的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/yanghao201607030101/article/details/112286491