10 DETR 论文精读【论文精读】End-to-End Object Detection with Transformers

目录

DETR 这篇论文,大家为什么喜欢它?为什么大家说它是一个目标检测里的里程碑式的工作?而且为什么说它是一个全新的架构?

1 题目

2摘要

2.1新的任务定义:把这个目标检测这个任务直接看成是一个集合预测的问题

2.2贡献:端到端的框架(新的目标函数强制模型输出独一无二的预测、使用了transformer encoder decoder架构、learned object query、并行出框)

2.3好处:想法上和实践上都很简单、性能不是最优但是很简单就能拓展到其他任务上

3引言:加长版的摘要

4模型架构

5 结果:AP不高,但是很简单而且好拓展

6 相关工作:基于集合的目标函数和encoder decoder的形式去做目标检测

7 方法

7.1基于集合的目标函数到底是怎么做的:二分图匹配,匈牙利算法,一对一匹配?

7.1.1二分图匹配问题的一个高效的解决算法:匈牙利算法

7.1.2对于目标检测来说,这个 cost Matrix 里面的值应该放什么呢?loss:分类loss和出框loss

7.2 DETR 的这个具体模型架构

7.2.1补充材料中提到的细节:object query 的这个自注意力操作、在decoder后面加了很多额外的这个目标函数

8伪代码

8.1我们来看,首先就是说你可以去定义一个DETR这个模型

8.2那具体DETR的模型长什么样?我们看一下它是怎么初始化的。

8.3前向过程

9实验

9.1DETR跟之前的方法,比如说Fasterrcnn比到底是个什么水平:

9.1.1那如果我们来对比一下这一行,就是 fast RCN 的 DC 5 模型和这个 DETR 的这个 DC 5 模型

9.1.2那同样的道理,我们再把这个 backbone 换成 Resnet 101,再把这个 FPN 也加上,然后去跟 DETR 的这个 101 去比

9.2消融实验和可视化

9.2.1transformer encoder的可视化:使用 transformer  encoder 之后,其实图片里的物体就已经分得很开了

9.2.2transformer encoder数值上的表现:transfer 编码器这个层数越深,这个编码器学到的这个全局特征也就越好

9.2.3transformer decoder的可视化:即使在遮挡这么严重的情况下,它还是能把这个轮廓分得非常清楚

9.2.4object query 的可视化

总结


DETR 这篇论文,大家为什么喜欢它?为什么大家说它是一个目标检测里的里程碑式的工作?而且为什么说它是一个全新的架构?

        大家好,今天我们来讲一篇 ECC V20 的关于目标检测的论文。它的名字想必大家都不陌生,也就这两年火热的DETR,其实就是 detection Transformer 的缩写。这篇论文当时在 2020 年5月第一次挂到 arxiv 上的时候,就引起了 CV圈 的强烈反响,网上很多人都觉得这篇论文应该是 ECCV 20 的最佳论文。而且也就是从 20 年5月到今年5月两年的时间, DETR 的引用就已经超过了2000,而且它的官方代码也有将近 9000 个star。如果我们跟去年大火的 clip 相比, CLIP 的官方代码到现在也只有 8000 个star,所以可见 DETR 的受欢迎程度。那今天我们就来精读一下,DETR 这篇论文,看看大家为什么喜欢它?为什么大家说它是一个目标检测里的里程碑式的工作?而且为什么说它是一个全新的架构?

1 题目

        文章的题目非常简单明了,就是 end to end object detection with Transformers。那这篇文章的两个关键词一个就是 end to end 这种端到端的目标检测,另外一个就是使用了最近大火的Transformer来做目标检测。

        那如果对目标检测了解不多的同学来说,可能并不能体会到这个端到端的意义究竟有多大。而事实上,从深度学区开始火,一直到DETR,目标检测领域里都很少有端到端的方法,大部分方法至少最后还需要一个后处理的操作,也就是 NMS 这个操作。 NON maximum suppression 非极大值抑制,不论你是proposal based 方法还是 Anchor based 方法,还是 NON Anchor based方法,你最后都会生成很多的这个预测框,那如何去除这些冗余的框就是NMS 要做的事情。而因为有了NMS 的存在,这个模型在调参上就比较复杂,而且即使训练好了一个模型,部署起来也非常困难,因为 NMS 这个操作不是所有硬件都支持的。所以说一个简单的端到端的目标检测系统是大家一直以来梦寐以求的,而 DETR 就解决了以上说的这些痛点,它既不需要proposal,也不需要anchor,直接利用 transformer 这种能全局建模的能力而把目标检测看成了一个集合预测的问题。而且也因为有了这种全局建模的能力,所以说DETR不会输出那么多冗余的框,它最后出什么结果就是什么结果,而不需要再用 NMS 去做这个后处理了,一下就让模型的训练和部署都简单了不少。作者其实在他们的官方代码里也写到,他们的目的就是不想让大家一直觉得目标检测是一个比图像分类难很多的任务,他们其实都可以用一种简单的优雅的框架去把它做出来,而不像之前目标检测那些框架一样需要很多的这个人工干预,需要很多的先验知识,而且还需要很多复杂的甚至普通的库或者普通的硬件不支持的一些算子。

        作者团队全部来自 Facebook AI 其实现在应该叫 Meta AI,一座 Nicholas 是 NYU 的博士生,这应该是在Facebook实习的时候做出来的工作。二作 Francisco 其实应该是老熟人了,只要你用Pytorch,多多少少都会在 Pytorch 的 issue 里看到 Francisco 给别人答疑,或者论坛里给别人答疑,或者说看到 Francisco 的 pull request, Francisco 是pytorch最重要的维护者之一。然后 Alexander 可能对做 CV 的人来说也不陌生,他就是第一个提出全景分割这个任务的,就是 Panoptic segmentation。接下来他又做了 panoptic FPN,后来又和凯明一起合作了 point RAN 的这篇论文,所以在分割领域里非常有经验。这也就难怪DETR 在最后做了一个全景分割的实验拓展。

        那在文章精读之前。我们先来看一下整篇文章的一个结构,整个 DETR 算上附录的话,其实还是比较长的,一共有 26 页。那上来先是摘要,然后引言,然后是相关工作, D E T R 的相关工作还是写得比较好,而且铺垫做得也不错。接下来三页主要就是讲的 D E T R这个方法。然后从第八页开始,一直到第 13 页,都是在目标检测这个任务上的性能。然后最后两页是做了一下全景分割的实验,然后附录里面上来先是对一些概念做了一些铺垫,比如说 Transformer 的结构,还有使用的这些目标函数。接下来两页就主要讲了一下这个模型的具体结构,以及训练的时候这个超参的设置,然后再接下来两页就是写了一些更多的这个消融实验和结果。最后一页就是把这个DETR 的这个伪代码放上来了,其实这里也不是伪代码,已经是真真实实的pytorch的代码了。作者在这篇文章里反复就强调DETR,而是一个非常简单的方法,能把目标检测做的跟这个图像分类一样简单。最后的这个代码不到 50 行,但却把DETR整个从模型的建立和模型的前向以及整个的推理过程全都包括了,所以非常适合大家去上手学习,以及在它上面做一些相应的拓展。

2摘要

2.1新的任务定义:把这个目标检测这个任务直接看成是一个集合预测的问题

        那接下来。我们就来先读一下这个摘要部分,那在摘要里作者一上来就把这篇文章干了什么事交代清楚,他们说我们这篇文章就是把这个目标检测这个任务直接看成是一个集合预测的问题。因为你本来的任务就是给定一个图片,然后你去预测一堆框,然后每个框不光要知道它的坐标,还要知道这个框里所包含的物体的类别。但是这些框其实就是一个集合,对于不同的图片来说,它里面包含的框也是不一样的,也就是说每个图片对应的那个集合也是不一样的那我们的任务就是说给定一个图片,我要去把这个集合预测出来,但是听起来这么直接的一个设置,之前很少有人把它做work。

2.2贡献:端到端的框架(新的目标函数强制模型输出独一无二的预测、使用了transformer encoder decoder架构、learned object query、并行出框

        然后这篇文章的贡献就是把这个目标检测做成了一个端到端的框架,之前特别依赖于人的先验知识的部分都给删掉了。比如说最突出的这个非极大值抑制的这个部分,还有就是生成 Anchor 的这个部分,那一旦把这两个部分拿掉之后,我们也不用费尽心思的去设计这种 Anchor 了,而且最后也不会出这么多框,也不会用到NMS,也不会有那么多的超参需要去调,所以说整个网络就变得非常的简单。

        那作者接下来说,那具体 detr 提出了什么呢? DeTR 提出了两个东西,一个就是提出了一个新的这个目标函数,它就通过这种二分图匹配的方式,能够强制模型去输出一组独一无二的这个预测。意思就是说没有那么多冗余的框了,每个物体理想状态下它就会生成一个框。

        那另外一个贡献就是使用了这种 Transformer encoder decoder 的架构。

        那具体来说还有两个小贡献,或者说有两个小细节是在这个 consumer encoder decoder 这边的一个:就是在 Transformer 解码器的时候,我们还有另外一个输入,也就本文中说的这个 learned object query,这个其实也有点类似于 Anchor 的意思,我们接下来会细讲。总之在给定了这些 object query 之后,DETR就可以把这个 learned object query 和这个全局的图像信息结合在一起,通过不停地去做这种注意力操作,能够让模型直接输出最后的一组预测框。而且作者这里还强调了一下是 in parallel 就是一起出框了,为什么要强调一下是并行出框?其实有两个原因,一个原因是在 Translora 原始的 2017 年那篇论文里,它的那个 decoder 因为是用到自然语言处理的任务上,所以它还有一个掩码机制,就是它采用的是一种自回归的方式,就一点一点把这个文本生成出来的。而这里我们是做视觉里的这个目标检测任务,我们是一股脑就把这些目标检测框全都输出来的,所以跟 NLP 那边是不一样的。而且第二点,不论是从这个想法上还是从这个时效性上来说,并行都比串行要更合适。因为首先这些框它是没有一个顺序的,并不是说我检测一个大物体就要先依赖于检测小物体,或者说检测图片右边的物体就要依赖于图,检测图片左边的物体,它没有一个先后的顺序,所以说没法做这种自回归的预测。第二,对于视觉,尤其对于检测任务来说,我们肯定是希望它越快越好,越实时性越好,那所以说并行一起出框肯定是要比顺序的一个个出框要时效性高很多的。

2.3好处:想法上和实践上都很简单、性能不是最优但是很简单就能拓展到其他任务上

        那说完了DETR具体干了个什么事情,那作者接下来就要吹一下DETR有什么好处了,那我们会发现作者这里头把这个简单性排到了第一位,他说这个新的模型从想法上来看非常简单,而且从实践上来看,它也不需要一个特殊的 deep learning library,那只要你这个库或者你这个硬件支持 CNN 和Transformer,那你就一定能支持 D E T R。那卖完了这个简单性之后,作者还提到了这个性能,那在 Coco 这个数据集上, DETR 和一个训练的非常好的 fast RCN 的基线网络取得了差不多的这个结果。而且这个模型内存速度也和 fast RCN差不多,那其实光从目标检测的这个性能上来说, DETR 在当时不是最强的,甚至说它和当时最好的方法差了将近 10 个点。因为当时最好的方法在 Coco 这个数据集上已经有 52、53 的这个 AP 了。但是 DETR 只有44,不过 DETR 实在是想法太好,真的是解决了目标检测里很多的痛点,而且写作也非常好,所以说中稿肯定是没有问题的。不过即使如此,可能作者也有点虚,所以说他又试了一下别的任务,结果发现了在全景分割这个任务上, DETR 的效果还是非常不错的。所以说最后作者又列了一下这个优点,就是DETR能够非常简单的就能拓展到其他的任务上,比如说就可以去做全景分割了,模型的大半部分就是前半部分都不用动,就是用detr,只不过在后面加一个专用的分割头就可以了。那这个性质其实非常厉害了,尤其是对于一个新的方法来说,因为它本来就是挖了一个坑,那你这个坑肯定是挖得越大越好,这样接下来才会有更多的人来填坑嘛。所以反而从这个角度来说,这个性能稍微差一点其实是好事,因为接下来大家才会在你这个上面继续去做,所以接下来我们会在结论里的时候也提到,最近基于DETR的这个改进工作层出不穷,光 CVPRR 中稿的我看可能都会有 10 篇左右了。然后最后作者说他们的这个代码全都在 Facebook research 下面这个 detr 的 repo 里,感兴趣的同学可以去玩一玩。我其实也是非常建议去读一下代码的。Facebook research的这个代码库一般都写得非常好,尤其是本来就是做开源的人写出来的这个代码库真的是看起来都是一种享受。

3引言:加长版的摘要

        接下来我们就直接来看引言部分, DETR 的引言其实就是它摘要的一个加长版,然后加了很多细节,我们一段一段来看。

        作者上来先说其实这个目标检测任务,就是对于每一个这个感兴趣的物体,我们去预测一些框和这个物体的类别,所以说白了它就是一个集合预测的问题。但是现在大多数好用的这个目标检测器都是用一种间接的方式去处理这个集合预测的问题的,比如说

  1. 就是用这种 proposal 的方式,就是 RCN 系列的工作, RS RCNN, musk RCN, cascade RCNN,
  2. 或者就是用anchor这种方式,就 yellow for goloss。
  3. 还有就是最近的一些 non anchor base 的方法,比如说用物体的中心点 center net 或者 f cost 这种方法。

        这些方法都没有直接地去做这个集合预测的任务,而而是设计了一个替代的,要么是回归,要么是分类的任务去解决这个目标检测问题。但是所有之前提到这些方法,就是这些应用特别广的检测器,它们的性能很大程度上受限于后处理这步操作,也就是N MS 这步操作。因为这些方法都会生成大量的这种冗余的框,也就是他这里说的 near duplicate predictions,就是接近重复的这种预测,对于同一个物体会大大小小的左左右右的出来很多框,所以最后就得用 NMS 去把这些框都抑制掉。但是也因为用了Anchor,因为用了IMS,所以导致这些检测器都非常的复杂,而且非常的难以优化,非常的难调参

        所以为了简化这个流程,本文 DETR 就提出了一个直接的方式去解决这个集合预测的问题。从而巧妙地绕过了之前所有的这些代理任务,也就绕过了人工设计的这些部分:比如说生成Anker,比如说使用NMs。然后作者说这种端到端的思想其实已经在很多别的任务里大范围的使用了,而且能使这些任务都变得更加的简单,更加的好用。但是在目标检测领域还没有人这么做过,之前也有一些类似的尝试,比如作者这里列的 learnable IMS 或者soft IMS。他们一定程度上简化了这个目标检测的流程,但是要么就是融入了更多的这种先验知识,要么呢就是在这些比较难的 Benchmark 数据集上取得不了很好的成绩。所以最后作者总结第一段我们的目的就是要把这个鸿沟弥补上,就是我们不需要使用更多的这种先验知识,我们就是端到端的一个网络,同时还能在这些比较难的数据集上取得最好的结果。

4模型架构

        那接下来作者又讲了几段话,大概描述了一下 D E T r 是什么,有什么好处?那其实我们就看这个图一,基本上就能知道。图一就是把 D E t r 整个的这个流程大概画了一下

        其实就是分几步,第一步就是先用一个卷积神经网络去抽一个特征

        然后在拿到这个特征之后,我们把它拉直,送给一个 Transformer 的 encoder decoder,那在这里 Transformer encoder 的作用就是去进一步的学习这个全局的信息,这样为接下来的decoder,也就是为了最后的这个出预测框做铺垫。作者后面也会用很多的这个实验和图来说明为什么我们要用Transformer encoder。但最直观最简单的理解就是,如果使用了Transformer encoder,那每一个点或者说每一个特征就跟这个图片里其他的特征都会有交互了,那这样他大概就知道哪块是哪个物体,哪块又是另外一个物体,那对于同一个物体来说,你就只应该出一个框,而不是出好多个框,所以说这种全局的特征非常有利于去移除这种冗余的框然后在做完第二步这个全局建模,也就是 Transformer encoder 之后,

        那接下来第三步就是用Transformer decoder 生成这个 框的输出。那这里作者其实没有画这个 object query,但其实这个 object query 挺重要的。也就是说当你有了这个图像的特征之后,你这里还会有一个object query,这个 query 其实就是限定了你要出多少个框,然后你通过这个 query 和这个特征不停地去做这个交互,在这个 decoder 里去做这个自助力操作,从而得到了最后的输出的这个框。在论文里,作者选择的这个框数是100,是一个固定的值,所以就意味着不论你是什么图片,你最后都会预测出来 100 个框。

        那现在问题来了,那你出的这 100 个框怎么去和 ground truth 这个框做匹配,然后去算loss。那就是文章的第四部分,也就是它最重要的一个贡献,就是它把这个问题看成是一个集合预测的问题,最后它就能用这种二分图匹配的方法去算这个loss。比如说这里 ground truth 其实就只有两个框,那在训练的时候,通过算这 100 个预测的框和这两个 ground truth 框之间的这种matching loss,从而决定出在这 100 个预测中,哪两个框是独一无二的,对应到这个红色和黄色的ground truth 框的。一旦决定好这个匹配关系之后,然后才会像普通的目标检测一样去算一个分类的loss,再算一个 bonding box的loss,而至于那些没有匹配到 ground truth 的框,也就是剩下 98 个框。其实就会被标记成没有物体,也就是所谓的这个背景类,

        所以总结一下,其实就是四步,第一步用卷积神经网络抽特征,第二步用 Transformer encoder 去学全局特征,帮助后面做检测。第三步就是用 Transformer decoder 去生成很多的这个预测框。第四步。就是把这个预测的框和 ground truth 的框做一个匹配,然后最后在匹配上的这些框里面去算这个目标检测的loss,这样整个模型就能训练起来了。

        那推理的时候DETR是怎么做的?同样的道理,前三步都是一致的,先用卷积神经网络去突出特征,然后通过一个 transformer encoder decoder 去生成最后的输出。只有第四步不一样,因为训练的时候你需要去算这个二分图匹配的loss,但是在你做推理的时候,其实第四步这个 loss 是不需要的,你直接在你在最后的这个输出上,你用一个阀值去卡一下这个输出的置信度,那最后模型比较置信的也就是那些置信度大于0. 7 的预测就会被保留下来,也就是所谓的前景物体,那剩下所有的那些置信度小于0. 7 的就被当成背景物体了。所以说我们可以看到DETR这个框架,不论是在训练的时候还是在做推理的时候,都没有 Anchor 生成的这一步,而且也都没有用到NMS。

5 结果:AP不高,但是很简单而且好拓展

        说完了模型的架构,作者最后就卖了一下结果,而且还顺带提了几个细节。

        第一个结果就是在 Coco 这个数据集上,DETR取得了跟之前一个 fast RCN 的这个基线网络匹配的结果,就是不论从 AP 这个性能上,还是从模型大小和这个速度上都差不多。而且尤其值得一提的是,虽然这个 AP 结果差不多。但是大物体的 AP 和小物体的 AP 差的还是非常远的。比如说DETR就对这个大物体表现特别的好,作者就觉得这个应该归功于使用了Transformer,所以你能做这种全局的建模了,那这样不论这个物体有多大,它应该都能检测出来,而不像原来一样:如果你使用 Anker 的话,它就会受限于Anchor 的这个大小

        但是同时 DETR 也有缺陷,比如说它的这个小物体上效果就不怎么样,那作者觉得这个还好,毕竟 DETR 是一个新的框架,它也需要时间去进化,那像之前的那些目标。检测器也都是通过了多年的进化才达到现在这个水平的。比如说 EULO V1,V2,V3。V4,V5、还有RCN, fast RCN, mask RCN,还要加 FBN 的 RCN 以及现在的Cascade RCN。所以作者这里就说接下来肯定是会有这个后续工作来提高这一点的。就像几年前 FBN 对fasterRCN 做的一样,通过使用这种多尺度的特征能够提升这个小物体的检测。而事实上确实如此,只不过这次不是像之前一样用了一年半的时间才从 fast RCN 到FPN。这次只用不到半年的时间。effective 第一条就出来了,不仅很好地通过这种多尺度的特征解决了小物体这个问题,同时也解决了作者接下来提到这个问题,就是第一条训练太慢DETR确实训练特别慢,想要达到很好的效果。作者训练了 500 个epoch,其实对于 Coco 来说,大家一般就训练几十个epoch,所以 500 个 epoch 相当于是 10 倍于之前的这个训练时长。

        但这里也是很值得我们学习的一点就是当你改变了这个训练setting,使你这个方法跟之前的方法都没法去做公平对比的时候,你怎样做才能让审稿人相信你的说法,才能让审稿人放过你?我们回头可以看一看D ETR 是怎么解决的。那最后作者就强调了一下, DETR 不光是做检测的一个方法,它其实是一个框架,它可以拓展到很多别的任务上,这也就是作者这里说的这个 DETR 的这个设计理念,就是为了能够适应于更多的这种复杂的任务的,从而让这些复杂任务都变得简单,而且甚至有可能用一个unified一个统一的框架去解决所有的这些问题。而事实上,作者也确实做到了,不光是在这篇论文里,它能验证出DETR 对这个全景分割有用,而接下来在很多别的后续工作里也验证了 DETR 的有效性,很快就把 DETR 拓展到这个目标追踪,还有视频里的姿态预测,视频里的语义分割等等各种任务。所以DETR真的是遍地开花,也难怪那么多人觉得 DETR 有拿这个最佳论文的潜质。

6 相关工作:基于集合的目标函数和encoder decoder的形式去做目标检测

        那接下来我们看一下相关工作。在相关工作这一节,作者其实讲了三个部分。作者先讲了一下集合预测这个问题,以及之前大家一般都是用什么方法去解决这种集合预测的问题。因为视觉这边用这个集合预测去解决问题的不多,所以作者觉得有必要来科普铺垫一下,然后第二条相关工作,作者就介绍一下 Transformer 以及这种 parallel decoding,就是如何不像之前的那些 Transformer decoder 一样去做那种自回归的预测,而是一股脑一口气把这个预测全都给你返回来。然后第三条路就是介绍了一下目标检测之前的一些相关工作,我们这里就着重讲一下第三个方向

        那我们直接来看相关工作的 2. 3 节目标检测。作者上来说,现在的大部分的这个目标检测器都是根据已有的一些初始的这些猜测,然后去做这些预测的。

  1. 比如说对于这种 two stage 的目标检测方法来说,它们的初始猜测就是中间的这个proposal
  2. 那对于这种 single stage 的目标检测方法来说,它们的初始猜测就是anchor,或者说是这种物体的中心点

        但是最近的一篇论文做了详细的比较,他发现之前的这些方法,它们的性能跟刚开始的这个初始的猜测非常相关。所以说你怎么去做这个后处理,得到最后的这个预测,其实对这最后的性能的影响是至关重要的,所以作者这里就从两个方面来阐述了这件事情,

  1. 第一个就是用这种集合的思想来做,就是 set based loss。那之前有没有类似的工作,用这种基于集合的目标函数去做目标检测?其实肯定是有的,那比如说作者这里说的这种可以学习的NMS 的方法,或者说这种关系型的网络,它都可以利用这种类似于自注意力的方法去处理物体之间的这种联系,从而导致最后能得出这种独一无二的预测,这样就不需要任何的这个后处理的步骤了。但是这些方法的这个性能往往都比较低,那为了跟当时那些比较好的方法这个性能对齐,那这些方法往往又用了一些人工干预,比如他这里说的用手工设计的这种场景特征,去帮助模型进行学习。但是DETR的目标是想让这个目标检测做的尽可能的简单,所以他不希望这个过程特别复杂,他也不希望用到过多的这种人工先验的知识,所以这就是 DETR 和之前的方法的区别。
  2. 那除了目标函数之外,第二个作者想讲的就是这个 recurrent detector,就是之前有没有类似的工作,用这种 encoder decoder 的形式去做目标检测,其实也是有的,不光是有做这种目标检测,而且还要做这种实例分割的工作还是蛮多的。但是这些工作全都是 1516 年的时候的工作,那个时候大家去做这种 recurrent detector 全都是用的是RNN,那因为你用了RNN,所以说你肯定是自回归的模型,所以你这个时效性就会比较差,而且你这个性能也会比较差。而 DETR 因为用了 Transformer 的 encoder decoder,所以我们后面可以看到,不光是利用了Transformer encoder 以后,我们能得到更全局的信息,从而这个目标检测更容易做了而且用了这种 Transformer 不带掩码机制的decoder。DETR 最后能够一起把这些目标框全都输出来,从而达到这种parallel decoding,所以时效性大大增强了

        但其实当我们看了这些相关工作之后,我们发现其实让 DETR 工作的最主要的原因还是因为使用了Transformer,因为之前大家也试过基于集合的这种目标函数,也利用匈牙利算法去做过这个二分图匹配,但是因为你这个 backbone 出来的特征不够强,所以最后的性能不好,你还得依赖一些先验知识或者人工的干预,从而让你达到更好的性能。

        那第二个方向也一样,之前也有人已经用 RNN 去做过这种 encoder decoder 的方式了,只不过因为没有用Transformer,所以说它的结果不够好,它跟当时的别的那些基线模型比不过,所以说白了 DETR 的成功还是Transformer的成功。

7 方法

        那接下来我们就来看一下文章的主体部分,就是 DETR 这个方法。那在主体方法部分其实主要分了两块,第一块就是 3. 1 节,主要说了一下基于集合的目标函数到底是怎么做的,作者是如何通过一个二分图匹配,把这个预测的框和这个 ground truth 的框连接在一起,从而算得这个目标函数的。然后第二个章节 3. 2,主要就是讲了一下 DETR 的这个具体模型架构。也就我们刚才在图一里说过的那四步,作者这里也分了四小段去分别说明这四步在干什么。

7.1基于集合的目标函数到底是怎么做的:二分图匹配,匈牙利算法,一对一匹配?

        我们回到正文,我们可以看到这个第三章,一开始作者就是说我们这一章节主要就讲了两个东西,一个就是基于这种集合的目标函数,另外一个就是这个 DETR 的这个结构。那之所以把这目标函数放在前面,而把这个结构放在后面,其实是因为这个结构相对而言还是比较标准的:你用一个 CNN 去抽一个特征,然后再用一个 Transformer encoder decoder 去做这种特征的强化,然后最后出这个预测框,相对而言还是比较好理解,而且比较标准的,没什么太多可以讲的。就算是这个object query 是一个比较新的东西,但就是非常小的一个东西,它可能几句话就解释清楚了,反而是基于集合的这种目标函数是比较新的东西,正是因为有了这个目标函数,所以我们才能达到这种一对一的这个出框方式,所以才能不需要NMS。所以作者这里就先说了这个目标函数,那具体来说这个目标函数是怎么回事?为什么我们之前说了好多遍这个二分图匹配,什么匈牙利算法,什么一对一匹配,这到底都是什么意思?读完这个章节之后,可能大家就会有一个更清晰的了解,作者这里说 DETR 这个模型最后的输出是一个固定的集合,就是说不论你这个图片是什么,你最后都会输出 n 个输出。那在这篇论文里, n 就是100,也就是说任何一张图片进来,最后都会给你扔出来 100 个框,那一般而言,这个 n 也就100,应该是比这个一张图片中所包含的物体个数要多很多的,那普通的一张图片可能里面就含有几个或者十几个物体。尤其是对于Coco 这个数据集而言, Coco 里一张图片里包含的最大个体数也没有超过100,所以说作者这里把 n 设成 100 就足够用了。但是现在问题就来了,你这个 DETR 每次都会出 100 个输出,但是实际上像我们刚才说的一样,一个图片的这个 ground truth 的 bonding box 可能只有几个,那你如何去做这种匹配?你如何去算loss?你怎么知道哪个预测框就对应那个 ground truth 框?所以这里作者就把这个问题转化成了一个二分图匹配的问题。

7.1.1二分图匹配问题的一个高效的解决算法:匈牙利算法

        那接下来我们就来先说一下这个二分图匹配到底是个什么问题。那如果你去上网搜或者去看这个维基百科,大部分的讲解都是给了这么一个例子,就是如何分配一些工人去干一些活儿,从而能让最后的这个支出最小。就比如说现在我有三个工人,就是a、b、c,然后我要去完成三个工作,也就是分别是x、y、z,然后因为每个工人他各自有各自的长处和短处,所以说他完成这些工作他需要的时间,或者需要的工钱也不一样,所以最后就会有这么一个矩阵,每个矩阵里就有他完成这项任务所需要的时间,或者说完成需要任务所需要的钱。然后这个矩阵就叫 cost Matrix,也就叫损失矩阵。那这个最优二分图匹配的意思就是说最后我能找到一个唯一解,能够给每个人都去分配它对应最擅长的那项工作,然后使得把这三个工作完成最后的这个价钱最低。那其实说的更直白一点,我就是用遍历的算法,我也可以把这个做出来,我所有的这个排列组合我都跑一遍,我最后看哪个花的钱最少,我就选哪个就好了,但是这样这个复杂度肯定就非常高了,那就有很多的算法来解决这个问题。那像这个匈牙利算法就是其中一个比较有名,而且比较高效的算法。那其实一般遇到这个问题大家都有成熟的解决方案了,比如说大家一般就会用 CYPI 这个包里提供的一个函数叫做 linear sum assignment去完成,这个 linear sum assignment 这个函数,它的输入其实就是这个 cost Matrix,你只要把这个 cost Matrix 给它,就能给你算出来一个最优的排列,告诉你哪个人应该干哪个活。其实在DETR这篇论文里,它的代码里也用的是这个函数,为什么呢?其实你仔细一想,目标检测这里其实也是一个二分图匹配的问题,那你可以把这个 ABC 看成它 100 个预测的框,然后把这个x,y, z 看成是 ground truth 的框,当然了,这个 cost Matrix 不一定是个正方形,它也可以是长方形,总之你都是可以扔到这个函数里去得到一个最优匹配的。

7.1.2对于目标检测来说,这个 cost Matrix 里面的值应该放什么呢?loss:分类loss和出框loss

        那既然我们已经知道可以用这种方法去解决现在的这个问题,那对于目标检测来说,这个 cost Matrix 里面的值应该放什么呢?其实你从 cost Matrix 里就可以看出来,它里面就应该放的是cost,也就是损失,那损失是什么?其实就是loss。那 loss 是什么?那对于一般目标检测来说, loss 就可以用来算,它其中包含两个部分,一个就是你分类对不对,有一个分类的loss,另外就是有一个这个出框的这个准确度,你这个框预测的准不准。所以说也就是遍历所有的这些预测的框,然后拿这些预测的框去和 ground truth 的框去算这两个loss,然后把这个 loss 放到这个 cost Matrix 里就可以了。一旦你有了这个loss,你就可以用 scipy的这个 Linear sum assignment,也就这个匈牙利算法去得到最后的这个最优解。

        那作者这里其实也给了一些注释。他说其实这个找最优的这种匹配,跟原来利用人的这个先验知识去把预测和之前的这种 proposal 或者 anchor 做匹配的这种方式是差不多的,都是一个意思,只不过这里的约束更强,就是我一定要得到一个一对一的这个匹配关系,而不是像原来一样是一对多的。也就是说,我现在我只会有一个框,跟 ground truth 的框是对应的,这样我后面才不需要去做那个后处理NMS

        那一旦你做完了这个匹配这一步骤,也就是说你一旦知道了这 100 个预测框中有哪几个框跟这个 ground truth 框是对应的,那接下来你就可以算一个真正的目标函数,然后用这个 loss 去做梯度回传,去更新模型的参数了。

        准确地说,最后的目标函数其实就是

        那乍一看还是两个loss,一个是这个分类的loss,一个是这个出框的loss,那DETR这里作者做了两个跟普通的目标检测不太一样的地方。

  1. 第一个一般大家在做这种分类的 loss 的时候,都是用这个 log 去算的,但是作者这里为了让这个 loss 和后面这个 loss 大概在同样的这个取值空间,所以作者把这个 log 给去掉了,作者发现了这样的结果,最后会稍微好一些。
  2. 那第二个改动就是在这个 bonding box 这块,之前的工作一般都是用一个 L1 loss 就可以了。但是对于 DETR 来说,用L1 loss 可能就有点问题,因为 L1 loss 跟这个出框的大小有关系,你这个框越大,你最后算出来那个 loss 就容易越大。那因为DETR 我们之前也说过,它用了transformer这种全局的特征,所以它对这种大物体很友好,所以它经常会出大框,那出大框它这个 loss 就会大,所以就不利于优化。那所以作者在这里不光是使用了一个L1loss,它还用了一个 generalized i o u loss。那这个 generalize io u loss 就是一个跟框大小无关的一个目标函数。

        所以作者这里就用了 io one loss 和 generalized i o u loss 的一个合体来算最后这个 bonding box 的loss,但这就属于是小的实验细节了。总之最后的这个目标函数跟普通的目标检测来说也是差不多的,只不过是先去算了一个最优匹配,然后在最优匹配的上面再去算这个loss,这个就是 DETR 的 基于集合预测的目标函数,从而能做到出的框和 ground truth 能够做到一一匹配,而不需要 NMS。

7.2 DETR 的这个具体模型架构

        那主体方法的第二部分,就是 DETR 的这个整体网络框架,文字里其实有很多的细节,但是其实我们只用看这个图 2 就已经基本知道DETR 在干什么了。

        这个图 2 也就是图一的一个升级版,图一画的很简单,就是让大家看清楚这个第一条的这个 flow 是什么样,这里面的图 2 就把每个步骤画得更清晰了一些。接下来我还是会走一遍这个前线过程,从而让大家更清晰的知道这个DETR是怎么运作的。那在DETR 的这个官方代码库里,作者也提供了一些Notebook,所以大家可以去玩。那在其中一个 notebook 里,作者就给了一个做推理的例子,那在那个例子里,

        这个输入图片的大小就是 3 * 800 * 1066,3就是 RGB channel,对这个图片而言还是相当大的,做检测分割一般这个输入图片都会大一些,而不像分类那边是 224 * 224。

        那第一步就是通过这个卷积网络去得到一些特征,那走到卷积网络的这个最后一层,走到 CONv 5 的时候,其实你就会得到这么一个特征,就 2048 * 25 * 34,那这个 25 和 34 就分别是之前的 800 和 1066 的 1/ 32,然后 2048 就是这个对应的通道数。

        然后接下来因为你要把这个特征扔给一个Transformer,所以说作者这里就做了一次 1 * 1 的降维操作就把这个 2048 变成了256,所以说从这个卷积神经网络出来的这个特征维度就是 256 * 25 * 34。

        那接下来因为要进transform,而 Transformer 是没有这个位置信息的,所以说我们要给它加入这个位置编码,那在这里面这个位置编码其实是一个固定的位置编码,它的维度大小也是 256 * 25 *34。那目的很简单,就是因为这两个东西是要加在一起的,所以说它的这个维度必须得一致。那好了,现在这两个东西加到一起之后,其实就是 Transformer 的输入了,这时候你只需要把这个向量拉直的意思,也就是说把这个 h 和 w 拉直变成一个数值,也就是变成了这个 850 * 256,那 850 就这个序列长度,那 256 就是这个 Transformer 的 hidden dimension。

        那接下来就跟一个普通的 Transformer encoder,或者跟我们之前讲过的 vision Transformer 是一样的了,那你这个输入是 850 * 256,那你不论过多少个这个 Transformer encoder block,你最后的输出还是 850 * 256,那在 DETR 里,作者这里使用了 6 个encoder,也就是说这里会有 6 个 Transformer encoder 这样叠起来,那这第二步其实也就算走完了。

        那第三步就是进入一个decoder,然后去做这个框的输出。那这里面就有一个新东西了,也就我们之前反复提到过的这个 object query,这个 object query 其实是一个 learnable 的embedding,就它其实是可以学习的,而且准确的说它是一个 learnable 的 positional embedding,那它的维度是 100 * 256,那 256 是为了和之前这个 256 对应,这样子大家才好在一起做乘法。然后 100 的意思,也就是说告诉这个模型我最后要得到 100 个输出,其实你也可以把它理解成是一种 anchor 的机制,或者是一种condition,就是一个条件,我给你这个条件之后,你这个模型基于我这个条件最后做出什么样的判断。

        然后在这个 Transformer decoder 里头,其实就做的是一个 cross attention,就是说我的输入是这个object query 是 100 * 256。然后我还有另外一个输入是从这个图像端拿来的全局特征,是 850 * 256,这时候我拿 850 * 256 和这个 100 * 256 去反复的做这种自制力操作,最后就得到了一个 100 * 256 的特征。同样的道理, DETR 里也用了 6 层decoder,也就是说这里是有 6 个 transformer decoder 叠加起来的,那这个每层的输入和输出的维度也都是不变的,始终是 100 * 256 进, 100 * 256出。

        那第三步其实也就说完了,那你拿到这个100 * 256 的这个最终特征之后,其实最后就是要做这个预测了,就是要在上面加一个这个检测头,那检测头其实是比较标准的,就是加一个 feed forward network,就是一些MLP那准确的说就是你把这个特征给这些全连接层,然后这个全连接层就会给你做两个预测,一个是做物体类别的预测,一个是做出框的预测,那类别如果是 Coco 就是 91 类。然后框其实就是四个值,分别对应的是x、y,就是这个出框的中心点,以及这个框的这个高度和宽度。

        那一旦我们用了这 100 个预测框,我们就可以去和这个 ground truth 里的这两个框去做这种最优匹配,然后用匈牙利算法,然后去算得最后的这个目标函数,然后梯度反向回传,然后来更新这个模型,这样一个端到端的可以学习的 DETR 模型就实现了。

7.2.1补充材料中提到的细节:object query 的这个自注意力操作、在decoder后面加了很多额外的这个目标函数

        当然了,模型这里还有很多的细节,比如说在补充材料里,作者就强调说在这个 transformer decoder 里,在每一个 decoder 里都会先做一次这个 object query 的这个自注意力操作。但其实在第一层这个 decoder 里,它可以不做,是可以省掉,但是后面那些层都不能省掉。这个 object query做这个自助力的操作主要就是为了移除这种冗余框,因为它们之间互相通信之后,就知道你每个 query 可能得到什么样一个框,我们尽量不要去做重复的框。

        另外还有一个细节就是在最后算 loss 的时候,作者发现为了让这个模型收敛的更快或者训练的更稳定,所以它在这个 decoder 后面加了很多,叫 auxiliary loss,就是加了很多额外的这个目标函数。其实这是一个很常见的 trick 了之前。在这个检测分割里,尤其是分割里是用得非常常见的。就是说我不光在最后一层去算这个loss,我在之前的这些 decoder 层里也去算loss,因为其实你每个 decoder 最后出来的输出都是 100 * 256,你都可以在这个 100 * 256 上去做这个FFN,然后得到这个输出,所以作者这里就是在每一个 decoder 后面,就是123456,在六个 decoder 后面都加了这个 FF n,而去得到了这个目标检测的输出,然后去算了这个loss。当然这里面这些 FFN 全都是共享参数。

8伪代码

        那其实到这儿就把DETR整个方法已经说完了,那为了巩固一下,我们再过一遍这个伪代码,顺便来看一下 DETR 到底有多简单。作者这里说他用不到 50 行的代码,就是这是完全可以跑的,其实不是伪代码,是直接可以跑的 Pytorch 代码,那这个版本其实是经过了一些简化的,所以说最后的结果没有那么高,那在文章里其实 DETR 的基线模型有42,那这个版本训练出来其实就只有 40 的准确率,但是就已经可以整个完全反映出 DETR 的结构了。

8.1我们来看,首先就是说你可以去定义一个DETR这个模型

       然后像 Coco 的话就有 91 个类,你这个 Transformer 里的 hidden dimension 就是256,然后你多头自注意力用了8,然后你用了 6 个这个 encoder layer,然后你 decoder layer 也是6,所以你就创建了一个DETR的这个模型。

8.2那具体DETR的模型长什么样?我们看一下它是怎么初始化的。

  1. 那首先第一步他需要一个卷积神经网络的backbone,对吧?那所以说这里面他就去找了一个 预训练好的 res 50,然后把这个 backboon 抽出来,
  2. 所以 backbone 有了,然后接下来有一个投射层,也就把这个 2048 变成256,也就是这层 conv投射层。
  3. 接下来它就需要这个transformer encoder decoder 了,也就是这个函数就定义好了,那 decoder 最后就会给你一个 100 * 256 的特征,那基于这个特征你就可以做预测了。
  4. 那预测的时候你就需要有两个FFN,一个 FFN 就是做这种类别的预测,
  5. 那另外一个 FFN 就是做这个框的预测。
  6. 那接下来这个 query positioning embedding,其实就是 object query,我们可以看到这里设的是100,最最后会出 100 个框
  7. 然候这个 positioning embedding, row embedding 和 column embedding 其实就是最开始跟这个卷积神经网络出来的特征加在一起的那个固定的embedding。

8.3前向过程

  1. OK,那现在模型定义完了,我们就来看一下这个前向过程
  2. 那前向过程很简单,给一个输入,我们过一下backbone,得到一个 2048 的特征
  3. 过一下这个投射层就得到了 256 的特征
  4. 然后得到 256 的特征之后,我们要把它拉直,所以 h 就 flatten 了,就拉直了就变成 850 * 256 那个特征了。
  5. 然后这时候因为你给了transformer,你需要位置信息,所以说你就自己先设了一个位置信息编码
  6. 你把这个位置信息编码和这个 H一加,这就是 Transformer 的输入了。
  7. 那同时这个 Transformer 里不光是有encoder,还有decoder,那 decoder 输入你就还需要有一个 object query,所以这时候你就要把这个 query positioning embedding 也传进去,所以说 Transformer 它收到了两个输入,一个是图像那边来的这个全局特征输入,一个是这个 object query 的输入。那最后经过这个 transformer 的 encoder decoder,最后我就得到了一个 100 * 256 的这个特征h
  8. 那基于这个h,我做一次 FFN 就得到了这个物体类别的判断,然后再做一次 FFN 就得到了这个框的判断
  9. 所以最后就得到了这个 Logis 和bonding boxes

        所以在这里完全没有 NMS 这个后处理操作,而且整体结构非常的简单直白,大家立马就对 DETR 这个结构爱不释手。

9实验

        那讲完了文章的主体方法部分,接下来我们就来看一下实验,我们主要就是看一下几个表格和图。从而心里能得到一个感受,就是DETR跟之前的方法,比如说Fasterrcnn比到底是个什么水平,以及为什么要用 Transformer encoder ?到底好在哪里?还有就是通过可视化看看 object query 到底学到了什么

9.1DETR跟之前的方法,比如说Fasterrcnn比到底是个什么水平:

        那首先我们直接来看表一里。就是对比了一下 DETR 和之前的这个 fast RCN 的方法,这个性能上到底如何。

        这个表里的上半部分其实是 detectron two 里的 fast RCN 的实现

        因为在这篇论文里 DETR 还用了一些别的技巧,比如说使用 GLU loss,比如说使用了更多的数据增强,而且训练了更长的时间,所以说作者又在中间把这些同样的模型又重新训练了一遍,就是用这些更好的训练策略去把上面这三个模型又训练了一遍。

        所以我们也可以看到,其实模型都是一个模型,只不过在后面用这个加号来表示是它这个提升版。所以这也就是为什么对于这个gflops、 FPS 还有这个模型参数量,它们其实都是一样的,因为它本来就是一个模型,只不过是训练的策略不一样。然后但是我们也可以看出来这个训练的策略非常重要,你就把这个训练策略改一改,这个性能就提升蛮大的, 39- 41、40- 42、42- 44,基本稳健的都能提升两个点。

        那作者这里接下来做对比,其实就是做这个中间和下面的对比,因为他们的训练的设置差不多,所以相对而言比较公平,但毕竟一个是用CNN,一个是用Transformer,所以说也很难强求他们什么都保持一致。在目前这种情况下,其实他们的这个训练设置已经差不多了

9.1.1那如果我们来对比一下这一行,就是 fast RCN 的 DC 5 模型和这个 DETR 的这个 DC 5 模型

        我们就可以看到,虽然它的这个 FPS 就是跑起来的这个速度差不多,当然这个 fast RCN 跑得更快一些,但是它的这个 Flops 会小,187只有 320 的差不多一半。所以这也就牵扯到另外一个问题了,就与现在大多数论文里经常汇报的都是 g Flops 这个参数,好像你觉得这个 g flops 越小行,这个模型就越小,跑起来就越快,其实不尽然,如果你更关心的是速度的话,那你还是要比较一下每个模型跑的最后的这个 FPS,gflops 跟这个没有什么关系。同样的道理,如果你对比这个参数量 41 也比这个 166 小很多很多了,但是DETR还是在推理的时候跑得更慢一些。那如果从 AP 这个角度上来看,fasterR CN 只有41,但DETR有 43. 3,高了两个多点,还是相当不错的。

9.1.2那同样的道理,我们再把这个 backbone 换成 Resnet 101,再把这个 FPN 也加上,然后去跟 DETR 的这个 101 去比

        我们会发现他们的这个参数量一样,都是 60 兆,而这个 g Flops 也都是 250 左右但是DETR 还是慢了一倍,FasterRCN 是 22 P S,DETR就只有 10 了。但是虽然它跑得慢,但是它的效果还是高一些的,它最后 AP 能达到44.9,而发 CRC 只有44。但这一个点的差距其实没什么。而作者更希望大家意识到的是这个细分类的比较,就是说到底对这个小物体(APs)和这个大物体(APL)而言,这个 DETR 和 fast RCN 差在哪里?我们可以看到,对于这种小物体(APs)而言, fast RCN 表现得非常好,比这个 DETR 要高 4 个AP,但是在大物体这边, DETR 反而比这个FasterrCnN 高了6个AP。这个结果就非常有意思了,作者这里觉得是因为使用了 Transformer 这个全局建模,而且没有用这个Anchor,所以说 DETR 想检测多大的物体就可以检测多大的物体。所以对大物体比较友好。但是因为DETR 这个框架实在是太简单了,它也没有使用多尺度的特征,它也没有用FPN,他也没有用一个非常复杂的这个目标检测头,所以说在这个小物体的处理上就不是很好

9.2消融实验和可视化

        那因为对于目标检测来说,大部分情况就只有 Coco 一个数据集,所以说做完这个实验之后就没什么实验好做了。而且因为DETR 的这个性能跟当时最好的那些检测器比也比不过,所以作者这里需要的其实是更多的这个消融实验,用更多的这种公平的对比来体现出DETR的优势。还有就是通过可视化,通过一些分析来证明DETR为什么好,所以这也就是写论文的另一个技巧,就是说当一个想法在数据集 a 上不 work 的时候,它有可能在数据集 b 上work,它有可能在这个设置下不 work 的时候,它在那个设置下work。如果你觉得你的想法真的很好,但是就是刷分刷不过的话,其实有时候是你这个切入点没有找对,找到一个合适的切入点,找到一个合适的研究动机,做起研究或者写起论文来就容易很多了。

9.2.1transformer encoder的可视化:使用 transformer  encoder 之后,其实图片里的物体就已经分得很开了

那言归正传,我们来看看作者这里放的第一个这个可视化图,就这个图 3 到底在讲一个什么事情?

        在图 3 里它其实是把这个 transformer encoder 就这个编码器的这个自注意力给可视化出来了。比如说在现在这个图里有几个牛,然后如果我们在这些牛身上点一些点,就是以这些点作为基准点,比如说这块,这一块,这块,然后我们用这个基准点去算这个点和这个图像里所有其他点的这个自注意力然后我们看看这个自注意力是怎么分布的,我们就会惊奇的发现这个自注意力已经做得非常非常好了。你在这头牛上做这个自注意力,它其实基本已经把这头牛的形状给你恢复出来了,甚至已经有一点实例分割出来的那个 Mask 的形状了。而且即使对于遮挡这么严重的情况,这头小牛在这头大牛身子下面,它还是能把这两头牛分得相当清楚,所以这也就是使用 transformer  encoder 的威力。当你已经使用 transformer  encoder 之后,其实图片里的物体就已经分得很开了,那你这个时候再在上面去做这个decoder,去做目标检测或者做这种分割,那相对而言这个任务就简单很多。

9.2.2transformer encoder数值上的表现:transfer 编码器这个层数越深,这个编码器学到的这个全局特征也就越好

        那接下来我们再看一看这个 transformer  编码器这个数值上的表现。

        表 2 里就是分析一下当这个 transformer  encoder 从 0 层到 3 层、 6 层、 12 层的时候,这个最后的这个目标检测的结果到底有多好。我们可以发现随着这个层数的增加,这个性能一直都是在增加的,也并没有饱和的现象,但是当然了,你这个层数的增加就会带来这个参数的增长和这个速度的变慢,所以说有的时候也是要取一些 trade off 的,总体而言,其实我觉得大概取个 3 层就差不多了,那在这篇文章里作者取的是 6 层。总之结论就是说你这个 transfer 编码器这个层数越深,这个编码器学到的这个全局特征也就越好,你有可能看到的那个可视化就会越清晰,物体和物体之间就会分得越开,而这样对你最后的这个目标检测就会容易很多。

9.2.3transformer decoder的可视化:即使在遮挡这么严重的情况下,它还是能把这个轮廓分得非常清楚

        那看完了transformer  编码器,那我们来看一看 transformer  解码器,因为它也是一个 transformer  block,所以你也有这个自注意力可以去可视化。所以我们来看一看,在经过了 transformer  encoder 之后,我们为什么还需要一个decoder,然后这个 decoder 它到底在学什么呢?

        这个图其实非常有意思,而且把DETR的好处展现的是淋漓尽致,它这里面是把每个物体的这个自助力用不同的颜色表示出来了。比如说对于这两头大象,小的这头像用的是黄色,大的这头像用的是蓝色。我们可以发现,即使在遮挡这么严重的情况下,比如说这个蹄子这一块,后面那个大象的蹄子还是可以显示出蓝色。还有比如说这个蹄子这块也是蓝色,遮挡非常严重,还有这么细的尾巴也是蓝色。而对于小象来说,其实象的这个皮肤,这大象小象的皮肤都是非常接近的,但是它还是能把这个轮廓分得非常清楚。同样的道理,对于右图这个斑马来说,其实斑马本身这个背上的花纹就已经很吸引人眼球了,是一个很强的一个特征,而且遮挡又这么严重。但即使是在这种情况下,DETR还是能准确地分出这个蓝色斑马的这边界,还有它的蹄子,还有绿色的斑马的边界和蹄子,还有黄色的斑马的这个轮廓。

        所以作者这里说这个 transformer encoder 和 decoder 一个都不能少

        encoder 在学什么呢? encoder 在学一个全局的特征,它是尽可能的让这些物体和物体之间分得开,但是光分开还是不够的。对于这些头尾巴这些极值点,最外围的这些点该怎么办?这个就交给 decoder 去做了,因为 encoder 已经把这个物体都分好了,所以 decoder 接下来就可以把所有的注意力都分到去学这个边缘了,去怎么更好地区分物体,以及解决这种遮挡问题。其实这也就有点像之前做分割的时候,我们用这种 unit 的结构,就是说 encoder 去抽一个更有语义的特征,然后 decoder 这边,一边一点儿一点儿把这个图片大小恢复出来,另外一边把更多的细节加进去,从而能导致最后的这个分割效果很好,或者说图片重建的效果很好。

        总之, DETR 用这种 encoder decoder 的方式,它的目的其实跟之前 CNN 里面用 encoder decoder 的这个目的差不多是一致的,最后达成的这个效果也是差不多一致的。只不过换成 transformer 之后,这个效果就更拔群了。

9.2.4object query 的可视化

        那另外一个比较有意思的图就是这个 object query 的可视化。作者这里就把 Coco 这个 validation set 里所有的图片,得到最后的所有的这个输出框全都可视化了出来

        虽然说 n 是100,但这里它只画了20,也就说这里有 20 个这个正方形,每个正方形就代表一个 object query。作者其实就想看看这个 object query 到底学了什么。然后我们从这个图 7 的这个屏幕里也可以看出来,图里这些绿色的点代表这些小的 bonding box,然后红色的点代表大的横向的这个 bonding box,然后蓝色这些点代表竖向的大的bonding box

        然后你看完这些分布之后你就会发现原来 object query 其实跟 Anchor 还是有一些像的, anchor 只不过是你提前先去定义好了一些 bonding box,然后你最后把你的预测跟这些提前定好的这个 bonding box 去做对比。而 object query 其实是一个可以学习的东西

        那比如说拿第一个这个 object query 来说,

        它学到最后就相当于每次给它一个图片,这个第一个 object query 都会去问这个图片的左下角,那你有没有看到一些小的物体?然后如果有的话你告诉我,或者说你有没有看到中间有一个大的这个横向的物体,如果有的话你告诉我。所以说第一个 object query 是负责这些的。

        然后比如说我们再换一个 object query,比如说我们换到这个 object query,

        那这个 object query 每次看到一张图片,它就会去问你右边有没有一些小的物体,然后或者说你的中间有没有一些大的物体,不论是横向还是竖向都可以,那如果有的话你告诉我。

        总之这 100 个 query 就相当于是 100 个不停的问题的人一样,每个人都有自己问题的方式,每当一个图片来的时候,他们就按照各自己的方式去问这个图片各种各样的问题,如果找到了合适的答案,他就把这个答案返回给你,而这个答案其实就是对应的那个 bonding box,如果他没找到,他就返回给你,什么也没有

        然后作者这里还发现,他发现所有的这些这个 object query,它中间都有这种,就是红色的这个竖线,它意思就是说每个 object query 它都会去问你这个图片中间有没有一个大的横向物体,它觉得之所以学出来了这个模式,是因为 Coco 这个数据集的问题。因为 Coco 这个数据集往往在中心都有一个大物体,就跟 image net 一样,它经常有一个大物体是占据整个空间的,所以模型最后就学出来了这个pattern。那从这个角度讲,其实 DETR 又是一个非常深度学习的模型,就是说它很简单,它什么参数也不用你调,它一切都是端到端。在你训练之前你也不知道 object query 是个什么东西,那反正我给你数据你就学去,结果最后发现,诶学的还挺好。这个 object query 学的还有模有样,直接就把生成 anchor 这一步给取代了。

总结

        那最后我们来总结一下这篇论文,作者说他们提出了 DETR 这个框架,这样是一个全新的做目标检测的框架主要就是利用了这个Transformer,而且用了这个二分图匹配,所以最后导致了这个框架是一个端到端可以学习的网络,非常的简单。

        然后在 Coco 这个数据集上,这个简单的 DETR 跟之前的这个 fast RCN 的基线模型打成了平手。然后在另外一个任务上,全景分割上反而取得了更好的结果而且因为它的这种简单易用性,它还有很大的潜力去应用到别的任务上。最后因为在 Coco 这个数据集上 44 这个 AP 实在是有点低,所以作者不去强调这件事情,他反而却强调了另外一件事,就是 DETR 在什么上面做的最好, DETR 是在这个大物体上做的最好。所以说作者这里又强调了一下, DETR 作为这种大物体的效果特别好,原因就是因为用了这个自助运力所带来的这种全局信息。所以总之就是什么好你卖什么,这样读者就能更容易的知道你这个方法的优点了。

        那最后因为这篇文章是一个比较新的想法,也是一个比较新的结构,肯定不可能是完美的,所以说与其让大家去挑刺,作者这里说还不如我自己就把我的缺点展示一下。那我的缺点就是说我的这个训练时间太长了,而且因为用 transformer在,所以可能不好优化,然后我们的性能也不是很好,尤其是在小物体上的性能,那就更不行了。那这个没关系,他说你说现在的这些特别好的这些检测器,全都是用了好几年的这个提升才把这些问题一一解决的。我们觉得因为我们这个框架特别好,特别容易用,肯定会有很多后续工作,立马就把 DETR 的这些问题来成功地解决了。事实上也的确如此,就在那一年的晚些时候, 10 月份 i clear 的一篇投稿 deformableDETR出来了。成功地使用 deformable attention,还有这种多尺度的特征,把 detr 里两个最头疼的问题,就这个训练的时长和这个小物体上的性能全都给提升上来了。 deformableDETR 就只需要普通了这个目标检测训练的时间,比如说 3X6X9X 就可以了,而且它的性能也跟之前最好的一些目标检测器打成了平手,它也有 50 多的AP。而且deformableDETR现在我看在另外一个网页上评价 i clear 那一年里中的论文里,把这个影响力排第二的论文相当有影响力的工作,而这也就证明了 DETR 其实是一个更有影响力的工作,因为deformableDETR只不过是它上面的一个改进而已,而且同时又能体现出 DETR 的另外一个好处,也就是第一条的这个简单性。DETR在摘要里就说过我们这个方法,任何一个这个深度学习库,只要你支持 CNN 和Transformer,然后你就可以做,但是deformableDETR它就需要有 CUDA 自己写的代码,它就需要自己写这么 deformable 这个算子。所以说不论是训练的时候这个平台的适配,还是说你在部署的时候都会带来不小的麻烦。所以说 DETR 真的是一个非常值得学习的论文。而在DETR 之后涌现了一大批的这个后续工作。比如说就用 Omni DETR up DETRPNPDETR, Smack DETR Deformal DETR DABDETR, Sam DETR DNDETROWDETROVDETR 还有好多可能我不知道的论文。那之前有这种待遇的论文,可能也就是Resnet、Vit 这种做模型骨干网络的,才会有这么多后续工作,直接用它的名字然后在上面去做这种更改了。那当然还有clip。

        所以说DETR真的是目标检测领域,乃至是整个计算机视觉领域里一个里程碑式的工作。 DETR 其实跟之前的目标检测的各种方法也有千丝万缕的联系,那其实就是使用 object query 去替代了原来这种生成Anchor 的机制,然后又用二分图匹配去替代了原来的Nms这一步,所以说就是把之前那些不可学的东西变成了可以学习的东西,从而得到了一个简单有效的端到端的网络

        而且也因为它使用了这个Transformer,所以接下来在它上面做这种多模态的工作也多了很多。然后也在它的推动之下,那后续的还有 Pixel to sequence 这篇论文,把输入输出一股脑全都搞成序列这种形式,从而能和 NLP 那边完美兼容。

        如果在你的研究工作中你还没有尝试过detr,其实不妨试一试。哪怕不用它整个的模型结构,试一试Transformer,或者试一试这个 learnable 的 object query,可能都会很有帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/120611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

博途PLC增量式PID(支持正反作用和归一化输出)

博途PLC增量式PID算法详细介绍请参考下面文章链接: 【精选】博途1200/1500PLC增量式PID算法(详细SCL代码)_西门子博途pid csdn_RXXW_Dor的博客-CSDN博客文章浏览阅读3.4k次,点赞2次,收藏12次。SMART200PLC增量式PID可以参看下面这篇博文,文章里有完整的增量式PID算法公式,…

【JavaSE】基础笔记 - 类和对象(下)

目录 1、this引用 1.1、为什么要有this引用 1.2、什么是this引用 1.3、 this引用的特性 2、 对象的构造及初始化 2.1、 如何初始化对象 2.2、构造方法 2.2.1、概念 2.2.2、特性 2.3、默认初始化 2.4、就地初始化 上篇:【JavaSE】基础笔记 - 类和对象&#…

要在CentOS中安装Docker

Docker部署 在CentOS中安装Docker要在CentOS中安装Docker,请按照以下步骤进行操作:启动和校验常用命令查看容器启动容器 配置镜像加速 在CentOS中安装Docker 要在CentOS中安装Docker,请按照以下步骤进行操作: 首先,确…

c语言从入门到实战——函数递归

函数递归 前言1. 递归是什么?2. 递归的限制条件3. 递归举例3.1 举例1:求n的阶乘3.1.1 分析和代码实现3.1.2 画图推演 3.2 举例2:3.2.1 分析和代码实现3.2.2 画图推演 4. 递归与迭代 前言 函数递归是指一个函数直接或间接地调用自身&#xff…

AirTag追踪汽车

美国华盛顿特区,11月4日,在一项全新的抗击车辆盗窃的措施中,市长穆里尔•鲍泽签署了一项新计划,将向该市车辆盗窃频率较高的社区居民免费提供苹果AirTag追踪器。 AirTag是苹果公司推出的一款蓝牙跟踪设备,它依靠Findm…

Android sqlite 使用简介

进行Android应用开发时经常会用到数据库。Android系统支持sqlite数据库,在app开发过程中很容易通过SQLiteOpenHelper使用数据库,SQLiteOpenHelper依赖于Context对象,但是基于uiatomator1.0和Java程序等无法获取Context的应用如何使用数据库呢…

JavaWeb课程复习资料——idea创建JDBC

1、创建空的Java Project 输入项目名称 空项目 2、引入jar包步骤 依次点击 File -> Project Structure(快捷键 Ctrl Alt Shift s),点击Project Structure界面左侧的“Modules”如图: 在 【Dependencies】 标签界面下&…

Bean的四种实例化方式以及BeanFactory和FactoryBean的区别

2023.11.8 Spring为Bean提供了多种实例化方式,通常包括4种方式。 第一种:通过构造方法实例化第二种:通过简单工厂模式实例化第三种:通过factory-bean实例化第四种:通过FactoryBean接口实例化 通过构造方法实例化 创…

【Linux】vim

文章目录 一、vim是什么?二 、命令模式三、插入模式四、底行模式五、vim配置 一、vim是什么? Vim是一个强大的文本编辑器,它是Vi的增强版,支持多种语法高亮、插件扩展、多模式操作等功能。Vim有三种基本的工作模式:命…

2023年【电工(中级)】模拟考试题及电工(中级)复审模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 2023年【电工(中级)】模拟考试题及电工(中级)复审模拟考试,包含电工(中级)模拟考试题答案和解析及电工(中级)…

《强化学习与机器人控制》:探索深度学习的应用宝典

《强化学习与机器人控制》是一本涵盖了广泛主题的深度著作,它不仅介绍了人机交互控制和强化学习的基本原理,还深入探讨了无模型强化学习控制器以及其在机器人控制中的应用。这本书对于研究生和执业工程师来说是一本极具价值的参考书,它为读者…

go程序获取工作目录及可执行程序存放目录的方法-linux

简介 工作目录 通常就是指用户启动应用程序时,用户当时所在的文件夹的绝对路径。 如:root用户登录到linux系统后,一顿cd(change directory)后, 到了/tmp文件夹下。此时,用户要启动某个应用程序&#xff0…

基于Kinect 动捕XR直播解决方案 - 技术实现篇

一 安装与部署 1. 安装与部署Kinect-v2设备: 安装硬件: Kinect-v2设备带线一台; Kinect-v2 原装适配器适配器组合件设备一台; Kinect-v2 USB 3.0 WIndows PC 一天,原主板支持USB3.0接口; Windows PC 系统 Win10( Win 10 Version 21H2更新, 基于x64系统), 特别…

初阶JavaEE(14)表白墙程序

接上次博客:初阶JavaEE(13)(安装、配置:Smart Tomcat;访问出错怎么办?Servlet初识、调试、运行;HttpServlet:HttpServlet;HttpServletResponse)-C…

Redis 线程、持久化和监控

Redis 线程、持久化和监控 Redis线程模型 Redis主线程模型 图1 Redis 6.0之前的主线程模型 IO多路复用程序指的是单个线程监听多个套接字连接(Socket),当IO多路复用程序将多个Socket上的就绪事件放置于队列中, Redis主线程一次处…

App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法

​ 根据近日工业和信息化部发布的《工业和信息化部关于开展移动互联网应用程序备案工作的通知》,相信不少要进行IOS平台App备案的朋友遇到了一个问题,就是apple不提供云管理式证书的下载,也就无法获取公钥及证书SHA-1指纹。 ​ 已经上架的应用…

1.UML面向对象类图和关系

文章目录 4种静态结构图类图类的表示类与类之间的关系依赖关系(Dependency)关联关系(Association)聚合(Aggregation)组合(Composition)实现(Realization)继承/泛化(Inheritance/Generalization)常用的UML工具reference欢迎访问个人网络日志🌹🌹知行空间🌹🌹 4种静态结构…

SHCTF-校外赛道

SHCTF-校外赛道 [WEEK1]babyRCE 1 (1)more:一页一页的显示档案内容2 (2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页3 (3)head:查看头几行4 (4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示5 (5)tail:查看…

建链时,please install openssl! use “openssl version“ command to check.

please install openssl! use “openssl version” command to check. 但是我已经安装了 编辑build_chain.sh文件 也可以用vi或者gedit命令 将 [ ! -z “ ( o p e n s s l v e r s i o n ∣ g r e p 1.0.2 ) " ] ∣ ∣ [ ! − z " (openssl version | grep 1.0.2)…

Maven中的继承与聚合

一,继承 前面我们将项目拆分成各个小模块,但是每个小模块中有很多相同的依赖于是我们创建一个父工程将模块中相同的依赖定义在父工程中,然后子工程继承父工程Maven作用:简化依赖配置,统一依赖管理,可以实现多重继承像J…