DETR
整体介绍:https://zhuanlan.zhihu.com/p/348060767
关于损失函数和二分图的匹配: 【论文】DETR_大白羊_Aries的博客-CSDN博客_detr object query
物体检测思路:首先使用CNN提取特征然后使用Transformer来检测物体,与之前的目标检测框架下相比,这篇文章的工作要简单很多。而且没有特别多需要调整的超参
前向过程:图1
- 首先输入CNN提取特征,提取到的特征图仍然具有图像的形式,只是通道数更深,尺寸更小,可以把特征图视为更高层次的特征表达
- 输入transformer encoder-decoder
- 输出一系列的框(set of box predictions),这个box是一个元组里面存储了类别c和框的位置,这box的类别可能为空(具体是空还是零我也不知道torch.zeors??),那么就代表这个box内没有物体。
训练:使用二分图匹配损失 - bipartite matching loss
- 一张输入图片里有两只海鸥
- 经过前向网络现在有N组prediction (c,b),这是一个固定的值,因为我们想要保证检测框的目标不要遗漏,
-
- 所以现在的情况是这样,这张图片里其实只有两个目标
- 我们将label 做成2个海鸥label,并pad出N-2个背景label ,保证gt的数量与prediction的数量相等
- 使用匈牙利算法匹配每一个gt,匈牙利匹配算法的评估指标就是这个二分图匹配损失,具体来说,如果prediction A 和 labels B的类别不相同,bbox的位置也是千里迢迢,这个loss就hi很大,反之亦然。这个过程中还隐藏了一个惩罚手段,考虑一直海鸥被多次预测的情况,在匈牙利匹配算法中,一个gt只能被一个prediction匹配,那么多余的prediction只能去匹配pad出的背景类,那么就会造成一个相对大的loss。这时就可以理解为网络正在惩罚这种情况的发生。
- 这里没提到DETR的匈牙利匹配具体是怎么做的,我需要再看一下
Transformer内部
- 将特征图和位置编码结合 positional encoding,因为trnasformer接受的是序列化的输入
- 展平为HW * C这样的特征序列
- 输入encoder 得到相同长度的特征序列
- decoder除了接受encoder的输出之外,还会接受一组object queries 长度为n,decoder的输出长度也为n ,与object queries的长度相同
object queries 究竟是什么?
- 一组随机的向量
- 没错,这很悬,根据这位老师的说法,this is so deep learning,当然也有一个很好的解释
- 随机向量n就好像n个人在对同一张图的不同特征提问,这也是这个向量叫queries的原因,对应attention is all your need里的Q
- 有个人会对图像中左边的目标感兴趣,有的人会对上面的目标感兴趣,有的人可能会对大尺寸的目标感兴趣等等
- 我们将这n个问题输入到decoder里面,得到n个V(transformer的那个V),然后经过deocder的注意力模式整合这些特征,比如确实发现了图片中左边有目标+发现图片上边有目标 = 图片的左上有目标。
- 从这里能看出来,object queries需要很不一样,最好能覆盖整个数据集的所有特征,课程中一直提到这些object queries是训练出来的,具体我也不知道是怎么训练出的。
文章的最后也设计了一个全景分割的网络模型搭建
———————————————————————————————————————————
Deformable DETR
DETR存在两个问题:
1)网络的设计中没有特征金字塔,在检测小物体的性能上相对较差,但一味的提高图像分辨率会带来无法接受的计算复杂度,因为DETR是全局注意力计算的Transformer,计算复杂度和图像尺寸成二次方比例关系
2)全局注意力的计算带来的另一个问题是,训练时间过长。导致训练时间过长的原因:根据self-attention的原始公式
图1
这里面的dk是跟图像尺寸成正比关系的,如果在训练之前采用了合适的初始化方式,QK两个向量的分布基本会在(0,1)那么过大的分子会使得注意力分布图在初始化阶段无限接近于0。虽然在经过训练之后,attention能够成功集中在那些有关联的物体上,但是这个训练过程耗时过长。
针对性的提出了解决方案:
1)借鉴FPN引入多尺度的特征,具体来说就是将同一张特征图分别下采样两次,然后在这3张特征图上针对同一点计算3轮attention,这个具体实现我后面会提到。
2)如果计算复杂度太高,就舍弃了全局计算attention的设计,转而采用就近计算,同时加入多个偏移,其实我觉得这么设计是合理的,因为目标不会出现在距离太远的物体上,swin transformer也是遵循的这个思路
重头戏:有关具体实现
下面是建立在你已经熟悉了Transformer的概念和self-attention以及DETR的基础之上的。
如果忘了也不必担心,这里我放两个链接,有助于你快速回忆起来,相关概念不是很难,可以快速上手。
https://zhuanlan.zhihu.com/p/44121378
https://blog.csdn.net/longxinchen_ml/article/details/86533005
不熟悉DETR的同学可以直接去读原论文,那篇文章写的真是太牛逼了,没有太多复杂的概念
下面进入正题。
首先,对于一个经典的多头注意力的self-attention模块,他的计算应该是这样的。
其中m代表多头注意力的个数
Wm :每个注意力头的权重
是一个可训练的权重 在于xk相乘之后,得到了图1中的V
的计算如下
其中U ; V都是可以训练的权重矩阵
zq * U对应了图1中的Q ,在self-attention的情况下,zq 可以被xk的转置替换。但是在cross-attention的时候,zq与xk的转置是不同的。
我打红色圈圈的位置是在进行self-attention的计算,即同一组数据x会被复制为3份输出到Multi-Head Attention模块分别去计算QKV三个向量。
我打蓝色圈圈和绿色圈圈的地方在进行的就是cross-attention计算,具体来说由encoder来提供attention计算所需的K和V这两个向量,由decoder来提供Q这个向量,这也是transformer中encoder和decoder之间的信息交互方式。
Vm * Xk对应了图1中的K
最终还会经过一个softmax归一化到(0,1)之内。
具体概念就是算出向量z与特征图x之间的关系。
在看懂了式(1)之后,再看Deformable Attention Module的设计应该就不难理解了
参照原文给出的参考图片
式(2)中的代表了基础采样点的选取位置,就是左下角 Input Feature map中那个红点。
则是Head1或Head2或Head3中的三个偏移量,换句话式2中的K = 3对应了三个偏移,M =3,对应了三个Head。
那么问题就来了,这三个偏移量是怎么产生的呢?
是根据Query Feature Zq经过线性变换产生的,Zq如果在cross-attention中就是decoder中输入的序列,如果在self-attention中,就是C*HW的向量。
总之,C向量会在经过线性变换之后产生一个通道数为3MK的向量,其中2Mk会被用于产生offset,在中就是9个offset,每个offset有两个方向所以乘2。
另外MK会被用于产生,这里的产生方式就与经典的Transformer有很大不同。这里面就产生了3*3 = 9个权重,分别代表了Head1中的各个offset与zq之间的密切程度。
图中Aggreagte就是相乘再相加。
当然,还有一个问题没有解决,那就是多尺度的问题
所以文中进一步提出了Multi-scale Deformable Attention Module
式(3)中进一步添加了一个L求和 和一个这样一个变换
L就代表将原feature map下采样了l次,
为了保证一致性,如(0,0)就代表了当前特征图的左上角,(1,1)就代表了当前特征图的右下角
是根据feature map的尺寸进行放缩的变换
下图中,就采用了三种不同尺度的特征图
这也是整个模型的流程图,里面的紫色三角点,紫色原点,红色方格点,和右边的decoder里面的三种不同颜色的矩形框框代表啥,红色线红色图形红色框之间有啥联系,不知道你能不能理解,反正我是理解不了,你能理解了教教我,球球了😍😍😍。
其他的就没什么重要的内容了,文章中没提训练策略,可能和DETR一样吧,性能也没看,想看的朋友自己去翻翻吧
———————————————————————————————————————————
Conditional DETR