论文地址:https://arXiv.org/abs/2109.10852
摘要
这篇文章提出了一种新的通用的物体检测框架。以往的方法利用了各种显示的先验知识来建模,而我们则把它简化成一种语言建模。我们把bounding boxes和物体类别看成是一系列的离散tokens(广润注:为了方便大家理解,我可以向大家解释一下这个词。大家不要被这个词吓唬,tokens就是英文字典里的词条的意思。所以,一个token序列就相当于一句描述),然后训练神经网络来感知所期待的描述。我们基于一个假设出发:假设神经网络知道物体是什么,物体在哪里,我们所要做的仅是把它们读出来就可以了。除了用到额外 的任务相关的data augmentation,我们几乎没有泄露其它任务信息(即data leak),我们在COCO取得要极佳的性能。
Introduction
现有的物体检测框架需要太多先验知识了,例如需要先验知识来设计网络框架和损失函数。例如在框架方面cnn中需要设计rpn和roi pooling,transformer中物体查询来进行物体绑定。在loss方面,需要有box回归,集合匹配、bounding box的iou做为metric等。这些先验知识太复杂了。虽然它们在许多任务,例如自动驾驶、医学图像、农业方面,这些专用人工智能领域取得了长足的进展,但它们离通用人工智能甚远。
本文基于一个假设出发:假设神经网络知道物体是什么,物体在哪里,我们所要做的仅是把它们读出来就可以了。给定一张图,我们的模型生成一个离散的tokens系列,这个tokens系列可以认为是一种语言描述(广润注:只是这个描述可能跟人类的语言未尽完全一致 。你可以认为是一种外星语言。所以这个方法与图像captioning有某种联系)。如此一来,我们就不需要设计复杂的需要先验知识的网络框架和loss funciton了。我们的方法可以支持通用人工智能,更具备解释性。
我们文章里面的一项关键技术是,利用一个离散化和序列化方案,把bounding box和类别标签,转换成一个离散化的tokens。然后我们用一个encoder-decoder架构来感知像素输入,并生成目标序列。目标函数是一个简单的关于像素输入与之前tokens的最大似然估计。虽然按照我们的上述定义,我们的框架和损失函数都是任务无关的,但是我们如果引入与任务相关的data augmentaion知识,可以让我们系统的性能与现有sota一致 。
方法
我们的方法主要包括以下几个模块。
图像增强 包括随机缩放与随机裁剪。这些都是很常见的。
序列构建与增强 把bounding box和物体类标转成离散的tokens序列。
框架 使用encoder-decoder。
损失函数 最大似然。使用了softmax cross-entropy(其实没有这么复杂)。
图像增强没有什么可讲的。大家都知道了。
接下来讲序列构建。其实也很简单。我们假设图像中有三个物体(如文章中的图4)。分别是人、人、摩托车,再考虑加上功能类似于句号的一个序列结束标志EOS,则序列的长度应该是4。由于序列中的每个单词都应该用一个向量来表示。则这个序列应该表示为:[向量1, 向量2, 向量3, 向量4]。在本文中,我们把每个向量都表示为5个维度,例如向量1=[y_min, x_min, y_max, x_max, c]。其中前四个代表坐标。第五个代表物体类别。用1004代表人,1001代表摩托车,用0代表EOS,则序列=[向量1, 向量2, 向量3, 向量4]=[ [[544 135 987 338 1004], [508 518 805 892 1004], [327 370 653 444 1001], [ignore, ingore, ignore, ignore, 0] ]。同时,作者把坐标与类别合并放进词典中。什么意思呢?假设一个图的长和宽都小于或等于600。则y_min, x_min, y_max, x_max这四维完全可以用字典里面的1~600表达。第五维作为类别,则用601到1600表达(假设1000类,实际没有这么多。coco才80类)。再加上,EOS用表达。则0~1600可以表示完所有的东西了。作者认为这个词典的词汇量才1600的话,远远小于NLU(自然语言理解)中的32k词汇量。(广润注:这个和NLU的对比,完全是错误的。因为网络还需要图像的输入。且每个向量是由5维表示的,每个向量才真正对应一个单词或tokens,所以本文的词典词汇量应该是600*600*600*600*1001才对,远远大于NLU。如果只考虑bins,那岂不是说所有图像才256 bin。因为每个像素才256 bins呀)。
上面这个例子,大家会发现一个问题。我是按人、人、摩托车、EOS来排序这个序列的。但是图像中给的是这四样东西的bounding box,并没有给它们的顺序。每个人对顺序的理解都不一样。那么,应该按什么顺序好呢?作者探索了随机顺序、面积大小顺序、左上到右下顺序、类别+面积顺序、类别+左上到右下顺序。作者发现,随机顺序最好。
接下来讲网络框架。网络框架用的是transformer,没什么好讲的。
接下来讲loss。作者说是似然估计,不过大家不要被吓倒。其实就是和NLP的transformer一样。输入全图x,让它预测向量1;输入原因+向量1,让它预测向量2;输入原图+向量1+向量2,让它预测向量3;输入原图+向量1+向量2+向量3,让它预测向量4。这里所谓的预测,指的是用softmax分类。例如预测向量2=[508 518 805 892 1004],则相当于输出5个分类器,分别预测0~1600的类别。就是这么简单。(广润合理猜测:最后一个向量EOS的预测,只需要预测向量4=[ignore, ingore, ignore, ignore, 0]的最后一维即可。因为它没有坐标值。)
接下来讲inference。感觉也没有什么好讲的。输入全图x,让它预测向量1;输入原因+向量1,让它预测向量2;输入原图+向量1+向量2,让它预测向量3;输入原图+向量1+向量2+向量3,让它预测向量4。
接下来讲序列augmentation。本来,到现在为止,已经讲完方法的全部了。但是,作者发现,预测的时候,到EOS就算序列预测结束,这样虽然能工作。但是,检测性能比传统sota方法差太远。怎么办呢?作者觉得,预到EOS不要终止,让它继续预测,直到预测序列长度达到一个最长序列长度才终止。于是作者为实现这种“预测序列长度达到一个最长序列长度才终止”的inference,他把训练也稍微改了一下,即为基于序列augmentation的训练。
修改后的序列构建和训练。修改前的序列构建如本博客前文所写,也可以参考论文图5(a)。修改方法是,在原有的序列上,加一些假的向量(单词)。即随机一些假的[y_min, x_min, y_max, x_max, c]。对这些随机的向量,训练时,只对它们分True or False就好了。并且,训练过程中,序列中的所有向量,都有可能被drop掉,来做类似于Dropout的正则化。具体如论文图5(b)所示。
修改后的inference。这回,测试不再是预测为EOS就终止了,而是一口气预测到序列长度上限。其中,过程中若预测为EOS,则class label为除掉EOS外其它类别的最大概率者,
实验
主要对比对象是DETR和Fast-RCNN。和DERT一样,训练300 epoch。则Fast-RCNN的epoch数少会亏了。因此,帮Fast-RCNN改一下,让它不亏。结果显示,本文的方法达到了sota。
文章还做了其他的alation study。
广润总结:这个文章的motivation很好。摘要也很好。introduction也很好。但是,读完方法,觉得还是没有很完美。还有完美的空间。
-----------------------------------
大家好,我来自fast lab。我开始不定时公开写作。这些写作主要通过两个渠道公布:一是FAST LAB官方网站;一是印象识堂(微信可访问)。欢迎大家订阅。谢谢!
FAST Lab的官方网址为:
https://wanggrun.github.io/projects/fast
除此外,还可以关注我的小伙伴王广润:
https://wanggrun.github.io/
王广聪:
https://wanggcong.github.io/
石阳:
https://www.linkedin.com/in/%E9%98%B3-%E7%9F%B3-381b521a4/
有时候这些网站打不开,请耐心多点几次。
多谢大家关注。
返回博客目录Return to all Blogs
返回主页Return to homepage