当前位置: 代码迷 >> 综合 >> siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
  详细解决方案

siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解

热度:58   发布时间:2023-10-20 19:26:35.0

论文地址
作者开源代码地址 还未公布训练代码,作者等VOT竞赛结束之后会公布训练代码
今天为大家带来一篇重量级文章,其实这篇是cvpr2019的poster不是oral,但在我看来仍然是重量级的,因为这是使用孪生网络做视频目标分割(VOS)的第一篇工作,意味着后续会有更多基于此改进的VOS方法会被提出,我自己也是做VOS的,更要好好读一下,期待自己能做出一些东西!!!
下面进入正文

思想来源

目前目标跟踪很多是使用相关滤波,最近两年,孪生网络为基础的目标跟踪取得了更不错的结果,而且速度和精度都有提高。作者依然采用孪生网络结构,同时补充了一个二值分割的任务。其实用另一个相关任务来提升一个任务效果的做法还有DFN,face++的语义分割模型。即作者想通过学习对特定目标的分割来refine跟踪结果。总体形成了一个简单高效的框架,在精度上是VOT2018上是state of the art的,在VOS任务目前是最快的(谷歌今年的FEELVOS估计没他快,但siammask用VOS精度不高,比2017年的OSVOS还差一点,我相信后续工作会基于此做更好的VOS的,我也会朝这个方向走!)

主要贡献

作者在论文中没写主要贡献,我这里自己总结下

  • 设计了一种基于孪生网络的框架,满足同时完成目标检测和视频目标分割两种任务
  • 通过设计了mask 分支,提高了目标跟踪的性能,并且能预测目标的旋转框(非水平框)
  • 在VOT2018达到了最高精度(不确定是不是,siamRPN+不知道表现有没有它好),同时对于VOS任务,速度是最快的。

我们先大体介绍,最后分模块仔细介绍。绝对要比其他博客详细哦,觉得好留个关注,点个赞,留下评论都是对我的支持

大体介绍

论文在方法那一章(第三章)先介绍了siamFC和siamRPN,因为siammask的两种类型的结构(siammask2b和siammask是基于这两种结构修改的)。我们在之后的细节部分说一下这两个网络的作用。
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
孪生网络其实是想寻找模板z(小点的图像)和搜索区域x(较大的图像)的区域相似度。而且模板来自第一帧由用户选择要跟踪哪一个目标。孪生网络是两个相同的网络,并且参数是共享的,最早用于人脸的相似度判断(人脸验证)
模板z是用户框的,搜索区域x是以z的中心为中心,crop出一个更大的区域作为搜索区域(因为帧之间相同目标移动应该不大。)z和x都经过一个backbone,作者选择resnet50(实际上没有用到conv5_x),那么就得到了两个特征,其中z对应的特征标记为zf,大小为15x15x256;x对应的特征标记为xf,大小为31x31x256。zf和xf经过一个叫做depthwise correlation操作,得到了一个更小的特征,标记为ROWs,大小是17x17x256。其实对于每一个分支,都有一个depthwise correlation操作,并不是上论文图中表示的那样只有一个depthwise correlation,代码中有三个depthwise correlation。至于这个depthwise correlation我们在代码详解部分解释。ROWs按照空间维度的每一个单元,称作ROW。整个ROWs送到对应的分支中继续计算特征,就是那三个绿色方块那里,h?,sψ,bσh_\phi,s_\psi,b_\sigmah??,sψ?,bσ?。我们可以在(a)中看到,下面两个分支其实和siamRPN很像,(b)如果仅仅保留score分支,则和siamFC很像,也许这就是reviewer觉得不能作为oral的原因吧
OK,我仅介绍图(a),下面就是RPN的结构,所以训练方式和RPN一致。mask 分支还有一个refine模块,作者放到了附录A部分,结构也是和语义分割模型差不多的,我放到后面介绍。
下面分模块仔细介绍

siamFC

siamFC仅仅有一个分支,使用的cross correlation操作得到的特征仅仅有一个通道(当然这个时候不能叫做特征了,应该叫相似度度量,我们记cross correlation的结果为
gθ(z,x)=fθ(z)?fθ(x)g_\theta (z,x)=f_\theta (z) \star f_\theta(x)gθ?(z,x)=fθ?(z)?fθ?(x)
其中gθ(z,x)g_\theta (z,x)gθ?(z,x)中的空间维度上的元素记作RoW,代表着模板z和搜索区域中的某一个区域的相似度。比如gθn(z,x)g^n_\theta (z,x)gθn?(z,x)就是说z和在x中的第n个区域的相似度。siamFC的目的是让gθ(z,x)g_\theta (z,x)gθ?(z,x)这个map的最大值出现的地方,还原回原图的位置恰好就是模板中的目标,从而达到跟踪的目的。作者和SiamFC有一点的不同的是使用depthwise cross-correlation来代替产生单通道的cross-correlation。这个分支使用logistic loss,我们记作lsiml_{sim}lsim?

siamRPN

siamRPN是在siamFC的基础上,增加了RPN结构,使得网络评估目标在下一帧的位置能够使用不同比例的框来预测。在siamRPN中,对每一个RoW,都对应有k个box和对应的前景背景分数。就是说siamRPN有两个分支,box和score,其中box是对每一个ROW都预测k个框,score为k个框描述是前景的概率。box分支使用 smooth L1作为损失函数,score使用交叉熵,这部分和faster rcnn是一样的。两个损失函数分别记作lbox,lscorel_{box},l_{score}lbox?,lscore?

siamMask 的新分支 mask branch

siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
注意,使用depthwise cross correlation得到的是多通道的(论文中是256个通道)特征,每一个row都是1x1x256维的,记住Row是代表z和在x中某一个区域的相似度,希望能为第n个Row,即gθn(z,x)g^n_\theta (z,x)gθn?(z,x)分配一个标签yny_nyn?yny_nyn?为1则说明第n个区域和z很像,第一个关键点就是如何给yny_nyn?分配标签。

如何给yny_nyn?分配标签?
一种方法是求Row的均值,就是多通道的特征值加起来看看大不大,如果够大则网络认为这个RoW和z蛮相似的,但这种方法没有利用到RPN。
论文的做法是用RPN的box分支的结果,和训练样本的标签做IOU,IOU大于0.6则yny_nyn?为1,反之亦然。
而对于两个分支的siammask2b,作者直接选取score分支最大位置的row的标签为1,其他的row的标签都是-1

当然我们还要有目标的分割标签,训练数据集应该给出,我们把它记作cnc_ncn?,尺寸是wxh的,和模板z一致。
我们还要根据Row还原回wxh尺寸的分割结果。这个过程涉及到refine 模块,放到后面讲,现在仅仅将refine 模块的过程看做下面的公式
mn=h?(gθn(z,x))m_n=h_\phi(g_\theta^n(z,x))mn?=h??(gθn?(z,x))
mnm_nmn?就是针对第n个搜索区域得到的mask
那么,mask分支的loss就是这样的

siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
一共有17x17个候选区域,所有n的变化是从1到17x17的,看1+yn2wh\frac{1+y_n}{2wh}2wh1+yn??这一项,仅仅对被认为是目标临近区域(IOU>0.6)的第n个搜索区域才计算mask loss;再往后看,Σ\SigmaΣ的下标是i,j,就是说对wxh的像素遍历,求每个像素的loss还求和。使用的是 logistic regression loss。


我觉得siammask分割精度低的原因很有可能就是上面的loss,对很多个符合IOU>0.6的候选区域都进行了分割处理,如果实际上有特征的偏移,仍然强行用固定的label训练,自然是不合适的


mask分支的具体结构

我们注意到绿色的小块h?h_\phih??的输出和g是一样的,这个h?h_\phih??的结构是两个1x1的卷积,在refine之前设计这个模块是有重大意义的。我们知道孪生网络有个缺点,就是不能抑制在搜索区域x内和模板z很相似的目标的响应值。作者希望通过两个1x1的卷积,能够区分开相似的实例个体,请见论文原文:
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解

总的损失函数

siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
针对两个变体,siammask2b和siammask,总的函数如上,参数设置如下。
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解

另外呢,因为DAVIS数据集只有mask label,作者考虑了三种策略为DAVIS数据集生成bounding box 的label。不过论文没有提如何为VOT数据集生成mask label 呢,真是奇怪呢
一种是 水平齐的框,另一种就是旋转框,最后是根据VOT2016的bencnmark提出的方法为mask自动生成框,这是最优的策略

refine 模块

siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
如果了解语义分割的同学,应该很容易看的明白,相当于解码器的作用,同时用到了低级特征。

测试阶段的pipeline

对于两个变体,都选择在score branch最大响应的row,抽取出来送到mask branch中得到mask。在siammask2b结构中,得到mask之后进而得到水平框。使用水平框作为参考,选择下一帧的搜索区域x。对于siammask,即三分支的网络,选择box 分支最高分数的box作为参考,即用score分支最大值对应的box分支的box。

depthwise cross correlation

class DepthCorr(nn.Module):def __init__(self, in_channels, hidden, out_channels, kernel_size=3):super(DepthCorr, self).__init__()# adjust layer for asymmetrical features   不对称的self.conv_kernel = nn.Sequential(nn.Conv2d(in_channels, hidden, kernel_size=kernel_size, bias=False),nn.BatchNorm2d(hidden),nn.ReLU(inplace=True),)self.conv_search = nn.Sequential(nn.Conv2d(in_channels, hidden, kernel_size=kernel_size, bias=False),nn.BatchNorm2d(hidden),nn.ReLU(inplace=True),)self.head = nn.Sequential(nn.Conv2d(hidden, hidden, kernel_size=1, bias=False),nn.BatchNorm2d(hidden),nn.ReLU(inplace=True),nn.Conv2d(hidden, out_channels, kernel_size=1)  # 没有batch和relu)def forward_corr(self, kernel, input):kernel = self.conv_kernel(kernel)input = self.conv_search(input)feature = conv2d_dw_group(input, kernel)return featuredef forward(self, kernel, search):feature = self.forward_corr(kernel, search)out = self.head(feature)return out

我们先看看源码中是怎么写的。直接看forward部分。kernel代表zf,zf是之前标记的字符,代表模板z的特征,search是xf。这两个特征先经过forward_corr,从函数forward_corr(self, kernel, input)我们可以看出,zf和xf分别经过了不同的3x3的卷积(并不是论文中所述用1x1的卷积),然后才进行depth cross correlation的操作。
我们进而看看这个conv2d_dw_group函数

def conv2d_dw_group(x, kernel):batch, channel = kernel.shape[:2]x = x.view(1, batch*channel, x.size(2), x.size(3))  # 1 * (b*c) * k * kkernel = kernel.view(batch*channel, 1, kernel.size(2), kernel.size(3))  # (b*c) * 1 * H * Wout = F.conv2d(x, kernel, groups=batch*channel)out = out.view(batch, channel, out.size(2), out.size(3))return out

先做了reshape再conv再reshape,**大家看懂了吗,我是没看懂,为啥这样就能达到描述相似度的效果呢?**估计需要看看siamFC才能知道答案了。

源码中模型主要结构

class Custom(SiamMask):def __init__(self, pretrain=False, **kwargs):super(Custom, self).__init__(**kwargs)self.features = ResDown(pretrain=pretrain)self.rpn_model = UP(anchor_num=self.anchor_num, feature_in=256, feature_out=256)self.mask_model = MaskCorr()self.refine_model = Refine()

self.features 用于提取特征,是resnet50作为backbone,其中没有用到最后一stage,同时在最高层加了一个1x1的卷积用于降维。
self.rpn_model是score分支和box分支的集合
self.mask_model是mask分支的head部分
self.refine就是解码器,用于把17x17的特征图变化成wxh的mask。

实验结果

模型正在下载中,未完待续!
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
速度真的没得说,就是棒!!

写在后面

这篇论文也是激起了相当活跃的讨论,见第一作者的知乎专栏
其中有几条我认为挺能突出细节的。
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解

siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解
siammask:Fast Online Object Tracking and Segmentation: A Unifying Approach论文解读和代码详解

  相关解决方案