前言:
前段时间读了一些基于Transformer的方法,和它们一样,TraDeS同样也是端到端的方式,主要基于DCN和CenterNet,它最大的亮点是用跟踪结果来辅助检测,进而在困难场景下有更好的表现。而且TraDeS可以解决2D、3D和分割的问题。

论文: 论文


0.Abstract

前面提到,TraDeS仍然是联合检测跟踪(Joint detection and tracking,JDT)的模型,它利用跟踪的线索来辅助检测。它利用cost volume来预测跟踪偏移,这个跟踪偏移也被用来传播之前目标的信息,从而提高当前帧的检测和分割效果。

cost volume解释:
cost volume是立体视觉中的名词,用于深度估计和光流估计。它的本意是衡量双目匹配中衡量左右视图相似性的一个4D tensor,在本文中也是一个4D tensor,衡量两帧之间嵌入特征的相似度。

\space

1.Introduction

首先diss TBD(Tracking by detection)的缺点,常规操作了。

之后说当前的JDT算法有两个问题:

  1. 检测步骤仍然比较独立,并没有利用好跟踪的信息。作者认为跟踪结果有助于检测,尤其是一些困难的场景(例如部分遮挡和运动模糊)

  2. 通常的Re-ID loss和detection loss在一个骨干网络中并不兼容,甚至会损伤检测的精度。原因是re-ID主要关注类内方差,而检测的目的是扩大类间差异,最小化类内方差。

最后一个观点跟FairMOT中提到的类似。FairMOT的文章中说对于将Re-ID任务视为另一阶段的任务(也就是Re-ID是个相对独立的任务),这样Re-ID的精度会很大程度上依赖于检测的精度,且两个任务会相互竞争。

\space
TraDes解决上述两个问题的方法是将跟踪结合到检测中,并且用一个自习设计的Re-ID的学习策略。

具体地,作者提出了基于Cost volume的关联模块(Cost Volume based Association,CVA)和运动指导的特征整合模块(Motion-guided Feature Warper,MFW)。

与CenterNet相似,TraDeS中的feature map中的点不是代表目标就是代表背景。

CVA和MFW的大致工作流程:

  • CVA逐点(point wise)通过主干网络提取Re-ID的特征,来构建一个cost volume,这个cost volume可以存储相邻两帧的嵌入特征对的匹配相似度。

  • 之后,用cost volume来推算追踪偏移(tracking offset),也就是所有两帧中潜在目标中心的时空位移。追踪偏移和嵌入特征一起,用来指导简单的两轮长时间的数据关联。

  • 之后,MFW将追踪偏移作为运动线索来将前一帧的目标特征传递到当前帧。

  • 最后,传递过来的特征和当前特征一起被用来得到检测和分割。

大体的工作流程如下(数学细节见第3部分):

\space
之前说Re-ID和检测不能很好兼容的原因是Re-ID关注类内方差,而检测关注类间方差。作者提出的CVA模块中cost volume监督Re-ID的嵌入特征,隐式地考虑了不同目标类别和背景区域。因此Re-ID就可以较多地关注到类间方差。

此外,由于追踪偏移是基于外观特征相似度来预测的,因此在快速运动场景、低帧率、跨数据集(train和test用不同的数据集)都可以取得比较好的结果。因此,预测的追踪偏移就可以作为一个鲁棒的运动线索来指导MFW中的特征传播。当前帧被遮挡或者模糊的目标在之前的帧中可能是清晰的,所以通过MFW模块,前帧特征传播可以支撑当前帧特征去恢复潜在的不可见目标。
\space

2. Preliminaries

由于TraDeS是基于CenterNet的,因此在这里简单介绍了一下CenterNet。

对于三通道输入图像I∈RH×W×3\bm I\in \mathbb R^{H \times W \times 3}IRH×W×3并且产生feature mapf=ϕ(I)∈RH/4×W/4×64\bm f=\phi(\bm I)\in \mathbb R^{H/4 \times W/4 \times 64}f=ϕ(I)RH/4×W/4×64.

在产生feature map之后,一系列卷积head分支就会产生热度图P∈RH/4×W/4×Ncls\bm P\in \mathbb R^{H/4 \times W/4 \times N_{cls}}PRH/4×W/4×Ncls(其中NclsN_{cls}Ncls是类别的数目)和其他为特定任务服务的maps,例如2D和3D的目标大小map。

在CenterNet的基础上,TraDeS增加了一个分支,来预测tracking offset mapOB∈RH/4×W/4×2\bm O^B \in \mathbb R^{H/4 \times W/4 \times 2}OBRH/4×W/4×2OB\bm O^BOB计算的是所有点在ttt时刻相对于t−τt-\tautτ时刻的时空位移。
\space

3.TraDeS tracker

这个图…无力吐槽

待补充 有空了回来写(精华都在开头的图里了)。这篇文章的启示意义比较大,用Cost volume来衡量了两时刻之间目标的位移,就是“用追踪结果反哺检测”的所在。

之前一些基于Transformer的方法在帧间传递信息的方法是传递queries,或者也将多帧的特征进行融合。TraDeS用了一种可解释性更强和更显式的方式。

最终的损失函数与CenterNet相似,但是多了一个CVA损失。CVA损失也是交叉熵的形式,如果当前帧ttt目标(i,j)(i,j)(i,j)t−τt-\tautτ时刻的时候在(k,l)(k,l)(k,l)处,记Yi,j,k,l=1Y_{i,j,k,l}=1Yi,j,k,l=1,否则为0.当Yi,j,k,l=1Y_{i,j,k,l}=1Yi,j,k,l=1时,loss取将cost volume池化后的向量Ci,j,lWC_{i,j,l}^WCi,j,lWCi,j,kHC_{i,j,k}^HCi,j,kH的加权对数和,否则为0,如下式所示:

最终的loss为:

L=LCVA+Ldet+LmaskL=L_{CVA}+L_{det}+L_{mask}L=LCVA+Ldet+Lmask

其中LdetL_{det}Ldet是2D和3D检测损失,LmaskL_{mask}Lmask是分割损失。

4. 代码解读

由于TraDeS结构有点复杂, 因此对代码作简单解读以备忘

顺着执行顺序整理.

4.1 前向传播

主要的模型都在在src/lib/model/base_model.py中. 我们先看forward函数:

forward函数首先提取当前图像特征, 如图中的PhiPhiPhi部分, 以DLA34作为backbone:

def forward(self, x, pre_img=None, pre_hm=None, addtional_pre_imgs=None, addtional_pre_hms=None, inference_feats=None):
"""x: 当前图像pre_img: 前一帧图像pre_hm: 前一帧head embeddingaddtional_pre_imgs: 更多的之前的图像addtional_pre_hms: 更多的之前的图像的head embeddinginference_feats: 训练时传入的为None"""cur_feat = self.img2feats(x)  # 转换为特征图

其中

    def img2feats(self, x):x = self.base(x)  # DLA34网络x = self.dla_up(x)  # DLAupy = []for i in range(self.last_level - self.first_level):y.append(x[i].clone())self.ida_up(y, 0, len(y))  # IDAupreturn [y[-1]]

随后进入TraDeS的剩余部分, 被封装在self.TraDeS中.

if self.opt.trades:feats, embedding, tracking_offset, dis_volume, h_volume_aux, w_volume_aux \= self.TraDeS(cur_feat, pre_img, pre_hm, addtional_pre_imgs, addtional_pre_hms, inference_feats)  # TraDes主要模块 前向传播

在得到加强特征feats后, 进入不同的head进行不同任务的推理:

if self.opt.model_output_list:  # 转为onnx才会用到for s in range(self.num_stacks):z = []for head in sorted(self.heads):z.append(self.__getattr__(head)(feats[s]))out.append(z)else:  # 正常走这里for s in range(self.num_stacks):z = {}if self.opt.trades:z['embedding'] = embeddingz['tracking_offset'] = tracking_offsetif not self.opt.inference:z['h_volume'] = dis_volume[0]z['w_volume'] = dis_volume[1]assert len(h_volume_aux) == self.opt.clip_len - 2for temporal_id in range(2, self.opt.clip_len):z['h_volume_prev{}'.format(temporal_id)] = h_volume_aux[temporal_id-2]z['w_volume_prev{}'.format(temporal_id)] = w_volume_aux[temporal_id-2]for head in self.heads:z[head] = self.__getattr__(head)(feats[s])  # 进行不同任务的预测out.append(z)if self.opt.inference:return out, cur_feat[0].detach().cpu().numpy()else:return out

4.2 TraDeS模块

下面来看self.TraDes(). 该部分的主要作用是把当前帧和过去帧的特征进行计算与打包, 传给CVA和MFW模块.

注意, MFW中的(5)式是在这部分计算的, 也就是代码里的support feature:

def TraDeS(self, cur_feat, pre_img, pre_hm, addtional_pre_imgs, addtional_pre_hms, inference_feats):"""cur_feat: 当前特征pre_img, pre_hm, addtional_pre_imgs, addtional_pre_hms: 同self.forward()inference_feats: None"""feat_list = []  # 存储帧的特征feat_list.append(cur_feat[0])  # 首先加入当前帧特征support_feats = []  # 论文(5)式 用以计算特征图和类别无关热度图的乘积if self.opt.inference:for prev_feat in inference_feats:feat_list.append(torch.from_numpy(prev_feat).to(self.opt.device)[:, :, :, :])while len(feat_list) < self.opt.clip_len:  # only operate in the initial framefeat_list.append(cur_feat[0])for idx, feat_prev in enumerate(feat_list[1:]):pre_hm_i = addtional_pre_hms[idx]pre_hm_i = self.avgpool_stride4(pre_hm_i)support_feats.append(pre_hm_i * feat_prev)else:feat2 = self.img2feats_prev(pre_img)  # 获取之前帧的featurepre_hm_1 = self.avgpool_stride4(pre_hm)  # 为了减少计算量 进行池化feat_list.append(feat2[0])  # 将之前帧的feature加入到feature listsupport_feats.append(feat2[0] * pre_hm_1)for ff in range(len(addtional_pre_imgs) - 1):  # 同理 加入更多的之前帧的特征与support featurefeats_ff = self.img2feats_prev(addtional_pre_imgs[ff])pre_hm_i = self.avgpool_stride4(addtional_pre_hms[ff])feat_list.append(feats_ff[0][:, :, :, :])  # 构成之前多少帧feature的集合support_feats.append(feats_ff[0][:, :, :, :]*pre_hm_i)return self.CVA_MFW(feat_list, support_feats)  # 主要模块 CVA + MFW

4.3 CVA_MFW模块

这是TraDeS的核心部分. 我们在有当前帧和之前帧的特征图后, 就要进入CVA进行运动的预测, 之后进入MFW对运动线索进一步预测, 和之前帧的特征结合得到更强的传播特征.

def CVA_MFW(self, feat_list, support_feats):prop_feats = []  # 帧间传播的特征attentions = []  # 为了计算特征增强的权重h_max_for_loss_aux = []w_max_for_loss_aux = []feat_cur = feat_list[0]  # 当前帧特征batch_size = feat_cur.shape[0]h_f = feat_cur.shape[2]  # 当前特征图高w_f = feat_cur.shape[3]  # 当前特征图宽h_c = int(h_f / 2)w_c = int(w_f / 2)prop_feats.append(feat_cur)  # 传播特征列表先加入当前特征embedding = self.embedconv(feat_cur)  # embedding conv为图中的\sigma网络 三层卷积层组成embedding_prime = self.maxpool_stride2(embedding)  # 减少计算量, 进行池化# (B, 128, H, W) -> (B, H*W, 128):embedding_prime = embedding_prime.view(batch_size, self.embed_dim, -1).permute(0, 2, 1)attention_cur = self.attention_cur(feat_cur)  # 预测当前特征的类别无关热度图 self.attention_cur 为一层卷积 shape: (bs, H, W, 1)attentions.append(attention_cur)for idx, feat_prev in enumerate(feat_list[1:]):  # 对于以前的帧# Sec. 4.1: Cost Volume based Association# 对当前帧进行与之前帧的cost volume计算  得到预测的运动tracking offsetc_h, c_w, tracking_offset = self.CVA(embedding_prime, feat_prev, batch_size, h_c, w_c)# tracking offset output and CVA loss inputsif idx == 0:tracking_offset_output = tracking_offseth_max_for_loss = c_hw_max_for_loss = c_welse:h_max_for_loss_aux.append(c_h)w_max_for_loss_aux.append(c_w)# Sec. 4.2: Motion-guided Feature Warper# 经过MFW 产生传播得到特征prop_feat = self.MFW(support_feats[idx], tracking_offset, feat_cur, feat_prev, batch_size, h_f, w_f)prop_feats.append(prop_feat)attentions.append(self.attention_prev(prop_feat))  # 对传播特征也预测attention 用以计算特征增强的权重attentions = torch.cat(attentions, dim=1)  # (B,T,H,W) T为帧数adaptive_weights = F.softmax(attentions, dim=1)  # shape: (bs, 1, H, W)adaptive_weights = torch.split(adaptive_weights, 1, dim=1)  # 3*(B,1,H,W)# feature aggregation (MFW)enhanced_feat = 0for i in range(len(adaptive_weights)):enhanced_feat += adaptive_weights[i] * prop_feats[i]  # 论文(6)式 为了解决遮挡等问题提出的特征增强# adaptive_weights通过softmax计算 自动赋予特征的权重return [enhanced_feat], embedding, tracking_offset_output, [h_max_for_loss, w_max_for_loss], h_max_for_loss_aux, w_max_for_loss_aux

其中的CVA模块:

def CVA(self, embedding_prime, feat_prev, batch_size, h_c, w_c):embedding_prev = self.embedconv(feat_prev)_embedding_prev = self.maxpool_stride2(embedding_prev)_embedding_prev = _embedding_prev.view(batch_size, self.embed_dim, -1)# Cost Volume Map# 将当前帧的每个位置的embedding都与之前帧的进行相似度计算c = torch.matmul(embedding_prime, _embedding_prev)  # (B, H*W/4, H*W/4)c = c.view(batch_size, h_c * w_c, h_c, w_c)  # (B, H*W, H, W)c_h = c.max(dim=3)[0]  # (B, H*W, H)  # 求W维度的最大值 即最大池化c_w = c.max(dim=2)[0]  # (B, H*W, W)  # 求H维度的最大值 即最大池化c_h_softmax = F.softmax(c_h * self.tempature, dim=2) # 在W维度作softmaxc_w_softmax = F.softmax(c_w * self.tempature, dim=2) # 在H维度作softmaxv = torch.tensor(self.v, device=self.opt.device)  # (1, H*W, H)m = torch.tensor(self.m, device=self.opt.device)# 一通改变维度off_h = torch.sum(c_h_softmax * v, dim=2, keepdim=True).permute(0, 2, 1)  # 与模板相乘 预测offsetoff_w = torch.sum(c_w_softmax * m, dim=2, keepdim=True).permute(0, 2, 1)off_h = off_h.view(batch_size, 1, h_c, w_c)off_w = off_w.view(batch_size, 1, h_c, w_c)off_h = nn.functional.interpolate(off_h, scale_factor=2)  # 插值off_w = nn.functional.interpolate(off_w, scale_factor=2)tracking_offset = torch.cat((off_w, off_h), dim=1)return c_h, c_w, tracking_offset

MFW模块:

def MFW(self, support_feat, tracking_offset, feat_cur, feat_prev, batch_size, h_f, w_f):# deformable conv offset input# 将CVA预测的offset与特征图之差结合(结合通过concat实现)进一步对运动进行预测off_deform = self.gamma(tracking_offset, feat_cur, feat_prev, batch_size, h_f, w_f)mask_deform = torch.tensor(np.ones((batch_size, 9, off_deform.shape[2], off_deform.shape[3]),dtype=np.float32)).to(self.opt.device)# feature propagation# 通过可变型卷积 以gamma输出的offset 和 与类别无关中心热度图相乘的特征 为输入 计算可变型卷积prop_feat = self.dcn1_1(support_feat, off_deform, mask_deform)  # 得到传播特征return prop_feat

论文阅读笔记8——Track to Detect and Segment:An Online Multi-Object Tracker(TraDeS)相关推荐

  1. 【论文阅读笔记】Learning To Detect Unseen Object Classes by Between-Class Attribute Transfer

    摘要: 本文主要研究训练和测试类别不相交时(即没有目标类别的训练示例)的对象分类问题.在此之前并没有对于毫无关联的训练集和测试集进行对象检测的工作,只是对训练集所包含的样本进行分类.实验表明,通过使用 ...

  2. 论文阅读笔记五十三:Libra R-CNN: Towards Balanced Learning for Object Detection(CVPR2019)

    论文原址:https://arxiv.org/pdf/1904.02701.pdf github:https://github.com/OceanPang/Libra_R-CNN 摘要 相比模型的结构 ...

  3. 【目标检测论文阅读笔记】QueryDet: Cascaded Sparse Query for Accelerating High-Resolution Small Object Detection

    Abstract 虽然深度学习的通用目标检测在过去几年取得了巨大成功,但检测小目标的性能和效率却远不尽如人意.促进小目标检测的最常见和有效的方法是使用高分辨率图像或特征图.然而,这两种方法都会导致昂贵 ...

  4. 【多目标跟踪论文阅读笔记——2021年CVPR论文粗读记录】

    [阅读心得] 多目标跟踪经典论文--2021CVPR论文粗读记录 前言 一.学习策略类 QDTrack 二.Temporal-Spatial 类 TADAM Alpha-Refine TraDes C ...

  5. 全卷积(FCN)论文阅读笔记:Fully Convolutional Networks for Semantic Segmentation

    论文阅读笔记:Fully Convolutional Networks forSemantic Segmentation 这是CVPR 2015拿到best paper候选的论文. 论文下载地址:Fu ...

  6. DnCNN论文阅读笔记【MATLAB】

    DnCNN论文阅读笔记 论文信息: 论文代码:https://github.com/cszn/DnCNN Abstract 提出网络:DnCNNs 关键技术: Residual learning an ...

  7. Learning Multiview 3D point Cloud Registration论文阅读笔记

    Learning multiview 3D point cloud registration Abstract 提出了一种全新的,端到端的,可学习的多视角三维点云配准算法. 多视角配准往往需要两个阶段 ...

  8. FCGF论文阅读笔记

    FCGF论文阅读笔记 0. Abstract 从三维点云或者扫描帧中提取出几何特征是许多任务例如配准,场景重建等的第一步.现有的领先的方法都是将low-level的特征作为输入,或者在有限的感受野上提 ...

  9. PointConv论文阅读笔记

    PointConv论文阅读笔记 Abstract 本文发表于CVPR. 其主要内容正如标题,是提出了一个对点云进行卷积的Module,称为PointConv.由于点云的无序性和不规则性,因此应用卷积比 ...

最新文章

  1. 【Redis系列】深入浅出Redis主从复制之读写分离【一篇搞懂Redis复制】
  2. ESXI6.5 最新版尝鲜安装图解
  3. 神经网络可视化,真的很像神经元!
  4. Python3的方法解析顺序(MRO)
  5. 怎么用Python获取全网最全的杰尼龟表情包
  6. python 38day--CSS简介
  7. 被美列入投资黑名单后 商汤重启公开招股发行规模定价没变
  8. leetcode笔记(Python版)待更新
  9. 图像梯度-Sobel算子
  10. cs229 学习笔记四 学习理论
  11. 软件测试02_软件生命周期软件测试流程
  12. APS系统在注塑行业的应用
  13. Unity3d:UGUI,UI与特效粒子层级,2018.2以上版本BakeMesh,粒子在两个Image之间且在ScrollView
  14. STM32CubeMX的使用教程
  15. 814 Div2 C
  16. 为 a.out 举行一个特殊的告别仪式
  17. linux运维是什么
  18. 安装ubuntu服务器版本
  19. git@gitlab invalid privatekey
  20. MySQL错误码解释

热门文章

  1. (2.2.8.10) Android多module下的构建版本区分
  2. python数据挖掘建模实战_#Python3组数据挖掘实战总结#
  3. vSphere Data Protection(VDP)----需求与规划
  4. (二)SpringCloud,Alibaba微服务架构之——核心模块及相应技术
  5. uniapp base64转图片
  6. jq选择器 常用方法总结 data数据存储
  7. js对对象按照值进行排序
  8. 判断一棵树是否是搜索二叉树 判断一棵树是否是完全二叉树
  9. 学习Kotlin~类
  10. 考研专业课微机原理和c语言,哪个学校自动化考研是考微机原理????