DETR学习笔记

DETR学习笔记

End-to-End Object Detection with Transformers

Abstract.

我们提出了一种新的方法,将目标检测视为直接集预测问题。我们的方法简化了检测流程,有效地消除了许多手工设计的组件的需求,如非最大抑制过程或锚生成(显式编码关于任务的先验知识)。新框架的主要组成部分称为DEtection TRansformer或DETR,是基于集合的全局损耗,通过二部匹配强制进行唯一的预测,以及一个变压器编码器-解码器架构。给定一个固定的学习对象查询的小集合,DETR推理对象和全局图像上下文之间的关系,直接并行输出最终的预测集合(并行的原因是目标检测过程中没有前后顺序,同时并行可以提高速度)。与许多其他现代检测器不同,新模型在概念上很简单,不需要专门的库。在具有挑战性的COCO对象检测数据集上,DETR展示了与完善和高度优化的Faster RCNN基线相当的准确性和运行时性能。此外,DETR易于推广,以统一的方式产生泛视分割。我们表明它明显优于竞争基线。训练代码和预训练模型可从https://github.com/facebookresearch/detr获得。

1 Introduction

对象检测的目标是为每个感兴趣的对象预测一组边界框和类别标签。现代检测器以一种间接的方式处理这一集合预测任务,通过在大量建议集[37,5]、锚[23]或窗口中心[53,46]上定义代理回归和分类问题。它们的性能受到以下因素的显著影响:折叠接近重复预测的后处理步骤、锚集的设计以及将目标框分配给锚[52]的启发式。为了简化这些管道,我们提出了一种直接集合预测方法来绕过代理任务。这种端到端哲学在机器翻译或语音识别等复杂的结构化预测任务中取得了重大进展,但在目标检测方面尚未取得进展**:以前的尝试[43,16,4,39]要么增加了其他形式的先验知识,要么被证明无法与具有挑战性的基准上的强基线竞争**。本文旨在弥补这一差距。

我们通过将目标检测视为直接集合预测问题来简化训练流程。我们采用了一种基于变压器[47]的编码器-解码器结构,这是一种常用的序列预测结构。变压器的自注意机制,显式地建模序列中元素之间的所有成对交互,使这些架构特别适合于集合预测的特定约束,如删除重复预测。

我们的检测变压器(DETR,见图1)一次预测所有对象,并使用集合损失函数进行端到端训练,该函数在预测对象和地面真实对象之间执行二部匹配。DETR通过删除多个手工设计的编码先验知识的组件(如空间锚或非最大抑制)简化了检测管道。与大多数现有的检测方法不同,DETR不需要任何自定义层,因此可以在任何包含标准CNN和变压器类的框架中轻松再现。

image-20221113221452630

与之前的大多数直接集预测工作相比,DETR的主要特征是将二部匹配损耗和变压器与(非自回归)并行解码结合在一起[29,12,10,8]。相比之下,之前的工作集中在rnn的自回归解码[43,41,30,36,42]。我们的匹配损失函数唯一地将一个预测分配给一个地面真值对象,并且对预测对象的排列是不变的,因此我们可以并行地发射它们。

我们在最流行的对象检测数据集COCO[24]上评估DETR,对比非常有竞争力的Faster R-CNN基线[37]。Faster RCNN经历了多次设计迭代,其性能自最初发布以来得到了极大的改进。实验结果表明,新模型具有相当的性能。更准确地说,DETR在大型对象上表现出明显更好的性能,这可能是由变压器的非本地计算实现的。然而,它在小对象上的性能较低。我们希望未来的工作将改进这方面的工作,就像FPN[22]为Faster R-CNN所做的那样。

DETR的训练设置与标准的目标检测器在许多方面不同。新模式需要超长的培训时间和福利从辅助解码损耗的变压器。我们将彻底探索哪些组件对演示的性能至关重要。

DETR的设计理念很容易扩展到更复杂的任务。在我们的实验中,我们展示了在预训练的DETR上训练的简单分割头部在Panoptic segmentation[19]上的表现优于竞争基线,这是一个具有挑战性的像素级识别任务,最近受到了欢迎。

2 Related work

我们的工作建立在先前几个领域的工作之上:集预测的二部匹配损耗、基于变压器的编码器-解码器架构、并行译码和目标检测方法。

2.1 Set Prediction

没有规范的深度学习模型可以直接预测集合。基本的集合预测任务是多标签分类(参见例[40,33]在计算机视觉背景下的参考资料),对于这种情况,基线方法one-vs-rest不适用于诸如元素之间存在底层结构(即几乎相同的框)的检测等问题。这些任务的第一个困难是避免几乎重复的任务。目前大多数检测器使用后处理如非最大抑制来解决这个问题,但直接集预测不需要后处理。他们需要全局推理方案来模拟所有预测元素之间的相互作用,以避免冗余。对于常大小集预测,密集全连接网络[9]是足够的,但代价昂贵。一般的方法是使用自回归序列模型,如循环神经网络[48]。在所有情况下,损失函数都应该通过预测的排列保持不变。通常的解决方案是基于匈牙利算法[20]设计一个损失,以找到地面真实和预测之间的二部匹配。这加强了排列不变性,并保证每个目标元素都有唯一的匹配。我们采用二部匹配损失法。然而,与大多数之前的工作相比,我们远离自回归模型,并使用并行解码的变压器,我们将在下面描述。

2.2 Transformers and Parallel Decoding

Vaswani等人[47]引入了变压器作为一种新的基于注意的机器翻译构建块。注意机制[2]是来自整个输入序列的信息聚合的神经网络层。transformer引入了自我注意层,它类似于非局部神经网络[49],扫描序列的每个元素,并通过聚合来自整个序列的信息来更新它。基于注意的模型的主要优点之一是它们的全局计算和完美的记忆,这使得它们比rnn更适合于长序列。变形金刚现在在自然语言处理、语音处理和计算机视觉的许多问题中取代rnn[8,27,45,34,31]。

首先在自回归模型中使用变压器,遵循早期的序列到序列模型[44],逐个生成输出令牌。然而,令人望而却步的推理成本(与输出长度成正比,且难以批量处理)导致并行序列生成的发展,在音频[29]、机器翻译[12,10]、单词表示学习[8]以及最近的语音识别[6]等领域。我们还结合了变压器和并行解码,以在计算成本和执行集合预测所需的全局计算能力之间进行适当的权衡。

2.3 Object detection

大多数现代物体检测方法都是根据最初的猜测进行预测。两阶段检测器[37,5]预测盒子w.r.t.提议,而单阶段方法预测w.r.t.锚[23]或可能的对象中心网格[53,46]。最近的工作[52]表明,这些系统的最终性能在很大程度上取决于这些初始猜测的确切设置方式。在我们的模型中,我们能够删除这个手工制作的过程,并通过使用绝对盒预测(w.r.t.)直接预测输入图像(而不是锚点)来简化检测过程。

Set-based loss

一些目标检测器[9,25,35]使用了二部匹配损耗。然而,在这些早期的深度学习模型中,不同预测之间的关系仅用卷积层或全连接层建模,手工设计的NMS后处理可以提高其性能。最近的检测器[37,23,53]在地面真相和预测之间使用非唯一分配规则和NMS。

可学习的NMS方法[16,4]和关系网络[17]明确地建模了不同预测与注意之间的关系。使用直接设置损失,它们不需要任何后处理步骤。然而,这些方法使用额外的手工制作的上下文特征,如建议框坐标,以高效地建模检测之间的关系,而我们则寻找减少模型中编码的先验知识的解决方案。

Recurrent detectors

与我们的方法最接近的是用于对象检测[43]和实例分割的端到端集合预测[41,30,36,42]。与我们类似,他们使用基于CNN激活的编码器-解码器架构的双部分匹配损耗,直接生成一组边界框。然而,这些方法只在小数据集上进行了评估,而没有参照现代基线。特别是,它们是基于自回归模型(更准确地说是rnn)的,所以它们没有利用最近的并行解码变压器

3 The DETR model

在检测中,直接集合预测有两个要素:(1)集合预测损失,它强制在预测结果和基础事实之间进行唯一匹配盒子;(2)预测(一次)一组对象并为它们之间的关系建模的体系结构。我们在图2中详细描述了我们的体系结构。

3.1 Object detection set prediction loss

DETR推断出一个固定大小的N个预测集合,在经过解码器的一次传递中,其中N被设置为明显大于图像中对象的典型数量。训练的主要困难之一是根据地面真相对预测对象(类、位置、大小)进行评分。我们的损失在预测对象和基础真值对象之间产生了一个最优的二部匹配,然后优化特定于对象的(边界框)损失。

让我们用y表示对象的基础真理集,用 y ^ = { y ^ i } i = 1 N \hat{y}=\left\{\hat{y}_{i}\right\}_{i=1}^{N} y^={ y^i}i=1N表示N个预测集。假设N大于图像中物体的数量,我们也将y视为一组大小为N,并配以∅(无物体)的集合。为了找到这两个集合之间的二部匹配,我们寻找代价最低的N个元素 σ ∈ S N \sigma \in \mathfrak{S}_{N} σSN的排列:

经典的二分图匹配算法–匈牙利算法

image-20221117094936346

image-20221114090326022

其中 L match  ( y i , y ^ σ ( i ) ) \mathcal{L}_{\text {match }}\left(y_{i}, \hat{y}_{\sigma(i)}\right) Lmatch (yi,y^σ(i))是ground truth y i y_i yi与指标 σ ( i ) σ(i) σ(i)的预测之间的两两匹配代价。在之前的工作(例如[43])之后,用匈牙利算法有效地计算了这个最优分配。

匹配代价既考虑了类预测,又考虑了预测真值框与基础真值框的相似度。地真集的每一个元素i都可以看作是 y i = ( c i , b i ) y_i = (c_i, b_i) yi=(ci,bi),其中 c i c_i ci是目标类别标签(可能是∅), b i ∈ [ 0 , 1 ] b_i∈[0,1] bi[0,1]是定义地真框中心坐标及其相对于图像大小的高、宽的向量。对于指数σ(i)的预测,我们将 c i c_i ci类的概率定义为 p ^ σ ( i ) ( c i ) \hat{p}_{\sigma(i)}\left(c_{i}\right) p^σ(i)(ci),将预测框定义为 b ^ σ ( i ) \hat{b}_{\sigma(i)} b^σ(i)。我们用这些符号定义 L match  ( y i , y ^ σ ( i ) ) \mathcal{L}_{\text {match }}\left(y_{i}, \hat{y}_{\sigma(i)}\right) Lmatch (yi,y^σ(i)) − 1 { c i ≠ ∅ } p ^ σ ( i ) ( c i ) + 1 { c i ≠ ∅ } L box  ( b i , b ^ σ ( i ) ) -\mathbb{1}_{\left\{c_{i} \neq \varnothing\right\}} \hat{p}_{\sigma(i)}\left(c_{i}\right)+\mathbb{1}_{\left\{c_{i} \neq \varnothing\right\}} \mathcal{L}_{\text {box }}\left(b_{i}, \hat{b}_{\sigma(i)}\right) 1{ ci=}p^σ(i)(ci)+1{ ci=}Lbox (bi,b^σ(i))。(该函数里面包含了分类loss和框的loss)

这种查找匹配的过程与现代检测器中用于匹配建议[37]或锚[22]到地面真值对象的启发式分配规则的作用相同。主要的区别是我们需要找到一对一匹配的直接集合预测没有重复。

第二步是计算损失函数,即前一步匹配的所有配对的匈牙利损失。我们对损失的定义类似于普通物体探测器的损失,即类预测的负对数似然和稍后定义的盒子损失的线性组合:

image-20221114092747298

其中,σ为第一步(1)中计算的最优分配。在实践中,当 c i = ∅ c_i =∅ ci=时,我们将对数概率项的权重降低10,以考虑类不平衡。这类似于Faster R-CNN训练过程如何通过对[37]进行子采样来平衡积极/消极建议。注意,物体与∅之间的匹配代价不依赖于预测,这意味着在这种情况下,代价是一个常数。在匹配代价中,我们使用的概率是 p ^ σ ( i ) ( c i ) \hat{p}_{\sigma(i)}\left(c_{i}\right) p^σ(i)(ci)而不是对数概率。这使得类预测项与 L b o x ( ⋅ , ⋅ ) L_{box}(·,·) Lbox()(如下所述)可通约,并且我们观察到更好的实证表现。

Bounding box loss.

匹配代价和匈牙利损失的第二部分是对边界框进行评分的 L b o x ( ⋅ ) L_{box}(·) Lbox()。与许多检测器将箱型预测作为∆w.r.t的初始猜测不同,我们直接进行箱型预测。虽然这种方法简化了实现,但也带来了损耗的相对规模问题。最常用的 l 1 l_1 l1损耗对于小盒子和大盒子会有不同的尺度,即使它们的相对误差相似。为了缓解这个问题,我们使用 l 1 l_1 l1损失和比例不变的IoU loss[38] L i o u ( ⋅ , ⋅ ) L_{iou}(·,·) Liou()的线性组合。总的来说,我们的盒子损耗是 λ iou  L iou  ( b i , b ^ σ ( i ) ) + λ L 1 ∥ b i − b ^ σ ( i ) ∥ 1 \lambda_{\text {iou }} \mathcal{L}_{\text {iou }}\left(b_{i}, \hat{b}_{\sigma(i)}\right)+\lambda_{\mathrm{L} 1}\left\|b_{i}-\hat{b}_{\sigma(i)}\right\|_{1} λiou Liou (bi,b^σ(i))+λL1bib^σ(i)1 ,其中 λ i o u , λ L 1 ∈ R λ_{iou},λ_{L_1}∈R λiou,λL1R是超参数。这两个损失是根据批处理中的对象数量进行规范化的。

3.2 DETR architecture

整个DETR体系结构非常简单,如图2所示。它包含三个主要组件,我们将在下面描述:提取紧凑特征表示的CNN骨干,编码器-解码器转换器,以及进行最终检测预测的简单前馈网络(FFN)。

image-20221114094950182

image-20221114093611093

(图中的FFN后面的框class box和no object分别对应类别损失和box损失)

(对于decoder过程的损失计算,作为辅助计算可以再每个transformer decoder后面接FFN的损失计算,用来增强计算效果)

与许多现代检测器不同的是,DETR可以在任何深度学习框架中实现,该框架提供通用的CNN主干和只需几百行代码的变压器体系结构实现。在Py Torch[32]中,用于DETR的推理代码可以在少于50行中实现。我们希望,我们的方法的简单性将吸引新的研究人员到检测社区。

Backbone

image-20221114093714401

Transformer encoder

首先,1x1卷积将高级激活映射f的通道维数从C降至更小的维数d,形成新的特征映射 z 0 ∈ R d × H × W z_0∈R^{d×H×W} z0Rd×H×W。编码器期望一个序列作为输入,因此我们将 z 0 z_0 z0的空间维度分解为一个维度,从而得到d×HW特征映射。每个编码器层都有一个标准的架构,由一个多头自注意模块和一个前馈网络(FFN)组成。由于变压器体系结构是排列不变的,我们用固定位置编码[31,3]作为补充,这些编码被添加到每个注意层的输入中。我们遵循[47]中所描述的体系结构的详细定义,请参阅补充材料。

Transformer decoder

解码器遵循变压器的标准架构,使用多头自和编码器-解码器注意机制转换大小为d的N个嵌入。与原始转换器的不同之处在于,我们的模型在每个解码器层并行解码N个对象,而Vaswani等人[47]使用自回归模型,每次预测一个元素的输出序列。我们建议不熟悉这些概念的读者查阅补充材料。因为解码器也是排列不变的,所以N个输入嵌入必须不同才能产生不同的结果。这些输入嵌入是习得的位置编码,我们称之为对象查询,与编码器类似,我们将它们添加到每个注意层的输入中。N个对象查询被解码器转换为嵌入的输出。然后通过前馈网络将它们独立解码为框坐标和类标签(下一小节将进行描述),得到N个最终预测。在这些嵌入上使用自注意和编码器-解码器注意,该模型使用它们之间的成对关系对所有对象进行全局推理,同时能够使用整个图像作为上下文。

Prediction feed-forward networks (FFNs)

最后通过具有ReLU激活函数和隐含维数d的3层感知器和线性投影层进行预测。FFN预测归一化中心坐标,框的高度和宽度w.r.t输入图像,线性层使用softmax函数预测类标签。由于我们预测的是一个固定大小的N个边界框集合,其中N通常远大于图像中感兴趣的对象的实际数量,因此使用一个额外的特殊类标签∅来表示在一个槽内没有检测到对象。该类的作用类似于标准对象检测方法中的“background”类。

Auxiliary decoding losses

在训练过程中,我们发现在解码器中使用辅助损耗[1]是有帮助的,特别是帮助模型输出正确的数字每个类的对象的。我们在每一解码层后添加预测ffn和匈牙利损耗。所有的预测ffn都共享它们的参数。我们使用一个附加的共享层范数来规范化来自不同解码器层的预测ffn的输入。

4 Experiments

image-20221114094211883

image-20221114094233824

image-20221114094302900

image-20221114094340340

image-20221114094351647

image-20221114094521538

image-20221114094544531

image-20221114094558466

image-20221114094610222

image-20221114094642627

image-20221114094659195

image-20221114094712798

5 Conclusion

我们提出了一种新的基于变压器和二部匹配损耗的目标检测系统设计,用于直接集预测。该方法在具有挑战性的COCO数据集上取得了与优化的Faster R-CNN基线相当的结果。DETR实现简单,架构灵活,易于扩展到全景分割,结果具有竞争力。此外,它在大型对象上的表现明显优于Faster R-CNN,这可能是由于自我注意执行的全局信息处理。

这种检测器的新设计也带来了新的挑战,特别是在小物体的训练、优化和性能方面。目前的探测器需要数年的改进才能处理类似的问题,我们希望未来的工作能够成功地解决DETR的这些问题。

6、伪代码

import torch
from torch import nn
from torchvision.models import resnet50

class DETR(nn.Module):

	def __init__(self, num_classes, hidden_dim, nheads,
		num_encoder_layers, num_decoder_layers):
		super().__init__()
		# We take only convolutional layers from ResNet-50 model
		self.backbone = nn.Sequential(*list(resnet50(pretrained=True).children())[:-2])
		self.conv = nn.Conv2d(2048, hidden_dim, 1)
		self.transformer = nn.Transformer(hidden_dim, nheads,
		num_encoder_layers, num_decoder_layers)
		self.linear_class = nn.Linear(hidden_dim, num_classes + 1)
		self.linear_bbox = nn.Linear(hidden_dim, 4)
		self.query_pos = nn.Parameter(torch.rand(100, hidden_dim))
		self.row_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))
		self.col_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))

	def forward(self, inputs):
		x = self.backbone(inputs)
		h = self.conv(x)
		H, W = h.shape[-2:]
		pos = torch.cat([
		self.col_embed[:W].unsqueeze(0).repeat(H, 1, 1),
		self.row_embed[:H].unsqueeze(1).repeat(1, W, 1),
		], dim=-1).flatten(0, 1).unsqueeze(1)
		h = self.transformer(pos + h.flatten(2).permute(2, 0, 1),
		self.query_pos.unsqueeze(1))
		return self.linear_class(h), self.linear_bbox(h).sigmoid()

detr = DETR(num_classes=91, hidden_dim=256, nheads=8, num_encoder_layers=6, num_decoder_layers=6)
detr.eval()
inputs = torch.randn(1, 3, 800, 1200)
logits, bboxes = detr(inputs)

猜你喜欢

转载自blog.csdn.net/charles_zhang_/article/details/127842090