Date: 2020/07/19
Coder: CW
Foreword:
本文是该系列的最后一篇,解析的源码内容包括如何将模型输出转化为预测结果以及评估验证过程,在该系列前面的文章中解析模型实现的源码时,只涉及到DETR模型中backbone与Transformer的部分,但是DETR自身也是一个nn.Module,本文会先对这部分的实现进行解析,然后讲解如何对DETR的输出进行后处理生成预测结果。
原计划对评估验证部分的源码也进行解析,但是发现其中内容主要是调用coco api来实现,因此就不对这部分内容作解析了,感兴趣的朋友们可参考源码: coco_eval.py。
Outline
I. DETR 模型
II. PostProcess 生成预测结果
DETR 模型
num_classes不包含背景,aux_loss代表是否要对Transformer中Decoder的每层输出都计算loss。
class_embed生成分类的预测结果,最后一维对应物体类别数量,并且加上背景这一类;bbox_embed生成回归的预测结果,MLP就是多层感知机的缩写,顾名思义,由多层nn.Linear()组成,根据下图的参数所示,这里有3层线性层,中间每层的维度被映射到hidden_dim,最后一层维度映射为4,代表bbox的中心点横、纵坐标和宽、高。
input_proj是将CNN提取的特征维度映射到Transformer隐层的维度,转化为序列;query_embed用于在Transformer中对初始化query以及对其编码生成嵌入。
顺便瞄下MLP的实现。注意在最后一层生成bbox的时不需要ReLU激活。
接下来是DETR的前向过程。输入是一个NestedTensor类的对象,这个类的实现在该系列的第三篇文章 源码解析目标检测的跨界之星DETR(三)、Backbone与位置编码 中有讲到。
前向过程可分解为两部分,第一部分如下所示,先利用CNN提取特征,然后将特征图映射为序列形式,最后输入Transformer进行编、解码得到输出结果。
第二部分就是对输出的维度进行转化,与分类和回归任务所要求的相对应。
PostProcess 生成预测结果
上一部分DETR的输出并不是最终预测结果的形式,还需要进行简单的后处理。但是这里的后处理并不是NMS哦!DETR预测的是集合,并且在训练过程中经过匈牙利算法与GT一对一匹配学习,因此不存在重复框的情况。
如doc string所述,这个后处理指的是将DETR的输出转换为coco api对应的格式。
以下需要关注的点有两个,一个是由于coco api中的评估不包含背景类,于是这里在生成预测结果时直接排除了背景类;另一个是模型在回归部分的输出是归一化的值,需要根据图像尺寸来还原。
那么这里问题就来了,在测试的时候,预测结果就有num_queries(默认100)个,而图片中实际的物体数量通常并没有那么多,这时候该如何处理呢?
如传统套路一致,我们可以对预测分数设置一个阀值,只有预测的置信度大于阀值的query objects,我们将其输出显示(画出bbox),官方show给我们的notebook如下:
@结语
至此,DE⫶TR: End-to-End Object Detection with Transformers 源码解析系列完结撒花~!
本人能力有限,如系列文章中出现不当之处,还请各位指定,谢谢!
该系列其余平篇幅汇总如下:
源码解析目标检测的跨界之星DETR(二)、模型训练过程与数据处理
源码解析目标检测的跨界之星DETR(三)、Backbone与位置编码