MAST: A Memory-Augmented Self-Supervised Tracker论文解读和代码剖析

本文主要是介绍MAST: A Memory-Augmented Self-Supervised Tracker论文解读和代码剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

官方代码
作者开源的官方代码有一处错误,在代码剖析部分将指出。有人已经在github上提出了issue,作者一直没回应。我也是在阅读代码的时候发现了这个错误。

背景

VOS任务很少有使用自监督的,即在训练中不借助mask,只用frame image来训练。
作者巧妙的在STM的基础上,将value换成frame自身,使用过去帧重构当前帧作为代理任务(proxy),实现自监督的vos。效果还不错,在davis val上是64的J&F。

核心思想

在这里插入图片描述
仍然是采用STM的memory bank的思想。memory的特征和query的特征会使用transform,得到attention map。但不同的是,stm使用的是经过backbone得到的value,而MAST是直接使用raw frame或者mask。如果是训练阶段;使用raw frame,如果是test阶段,直接使用得到的mask。
在训练阶段,使用当前帧的特征作为query,和memory中的key,value是对应时刻的raw frame,直接使用qkv三元组重构出一个新的帧。这个输出又以当前帧为GT,用huber loss优化。整个过程没有使用到mask GT。在测试阶段,直接使用mask代替raw frame,则每次预测得到的都是重构出来的mask,作为当前帧的输出。

细节

颜色空间

作者认为,RGB颜色空间不适合作为输入,因为是重构作为代理任务。用huber loss是直接优化像素距离的。
比如说重构出来的输出的第i个像素,和raw frame的第i 个像素的matching 距离很小,但实际上他们可能是落在不同目标上。则说明,根据颜色匹配来优化网络,不适合推动模型学习语义特性。
作者也否决了随意丢弃一个channel的做法,因为RGB是关联的,可以通过其他两个通道推理得知另一个通道的像素。
作者使用LAB空间,在随机丢弃一个channel。lab空间解耦性较好。
在这里插入图片描述
作者统计了davis数据集的RGB数值和LAB数值的分布图。可以看出RGB是线性相关的。
输入的颜色值不是互相关联的,则网络将被push学习更好的表征,而并非仅仅依赖局部颜色信息。

loss

作为GT,raw frame使用RGB颜色空间。使用smooth l1 loss(huber loss)
在这里插入图片描述

 outputs = F.interpolate(outputs, (h, w), mode='bilinear')loss = F.smooth_l1_loss(outputs*20, tar_y*20, reduction='mean')

获取ROI区域

作者分析了STM的劣势,就是memory bank式的matching,需要的内存和计算量都很大,O(T*H*W*H*W)。
如果先获得了目标的大致位置,每一个pixel需要匹配的数目就会少很多(原始的是T*H*W)。
作者提出了一个两阶段的ROI localization。假设对query的第i个位置 q i q_i qi进行匹配。首先使用一个网格(应用空洞技巧),围绕在key的第i个位置上,得到网络上的特征,和 q i q_i qi做匹配(dot运算),得到的相似性系数直接加权相对坐标(和直推式vos的做法类似),这里是应用soft argmax,得到离第i个位置最相似的offset。
第二步就是围绕新的位置(i+offset),resample出一个小区域,作为需要匹配的对象。
在这里插入图片描述

其他细节

网络使用resnet18,修改stride,最低分辨率为1/4。训练也是先pretrain,在main train,接着dynamic train。

代码剖析

主要看看ROI那步。其他的步骤都很好读
作者先是在init里面设置了两种sampler。第一个是带dilate的,第二种是没有dilation的。前者用于long term的sampler,后者用于short term。

self.correlation_sampler_dilated = [SpatialCorrelationSampler(kernel_size=1,patch_size=self.memory_patch_P,stride=1,padding=0,dilation=1,dilation_patch=dirate) for dirate in range(2,6)]self.correlation_sampler = SpatialCorrelationSampler(kernel_size=1,patch_size=self.P,stride=1,padding=0,dilation=1)

在forward里面,大致有下面几个步骤:

  • 先对long term key进行第一步粗糙采样,得到ROI的位置,然后在截取主要特征作为matching对象得到系数。
  • 在对short term key同样操作
  • 用得到的offset,对raw frames,也截取对应的value。
  • 所有的attention map以及value都齐了,开始使用qkv公式得到输出。
 for searching_index in range(nsearch):  # long term: need dilation##### GET OFFSET HERE.  (b,h,w,2)samplerindex = dirates[searching_index]-2coarse_search_correlation = self.correlation_sampler_dilated[samplerindex](feats_t, feats_r[searching_index])  # b, p, p, h, wcoarse_search_correlation = coarse_search_correlation.reshape(b, self.memory_patch_N, h*w)coarse_search_correlation = F.softmax(coarse_search_correlation, dim=1)coarse_search_correlation = coarse_search_correlation.reshape(b,self.memory_patch_P,self.memory_patch_P,h,w,1)_y, _x = torch.meshgrid(torch.arange(-self.memory_patch_R,self.memory_patch_R+1),torch.arange(-self.memory_patch_R,self.memory_patch_R+1))grid = torch.stack([_x, _y], dim=-1).unsqueeze(-2).unsqueeze(-2)\.reshape(1,self.memory_patch_P,self.memory_patch_P,1,1,2).contiguous().float().to(coarse_search_correlation.device)# 每个query像素在mem bank中的一帧该以哪个位置为中心采样offset0 = (coarse_search_correlation * grid ).sum(1).sum(1) * dirates[searching_index]  # 1,h,w,2col_0 = deform_im2col(feats_r[searching_index], offset0, kernel_size=self.P)  # b,c*N,h*wcol_0 = col_0.reshape(b,c,N,h,w)##corr = (feats_t.unsqueeze(2) * col_0).sum(1)   # (b, N, h, w)corr = corr.reshape([b, self.P * self.P, h * w])corrs.append(corr)
 for ind in range(nsearch, nref):  # short termcorrs.append(self.correlation_sampler(feats_t, feats_r[ind]))_, _, _, h1, w1 = corrs[-1].size()corrs[ind] = corrs[ind].reshape([b, self.P*self.P, h1*w1])

得到T帧的匹配系数的softmax值

  corr = torch.cat(corrs, 1)  # b,nref*N,HWcorr = F.softmax(corr, dim=1)corr = corr.unsqueeze(1)

得到value

im_col0 = [deform_im2col(qr[i], offset0, kernel_size=self.P)  for i in range(nsearch)]# b, 3*N, h*w
im_col1 = [F.unfold(r, kernel_size=self.P, padding=self.R) for r in qr[nsearch:]]
image_uf = im_col0 + im_col1  # memory value list.

得到预测结果

  out = (corr * image_uf).sum(2).reshape([b,qr[0].size(1),h,w])

采用使用的是spatial correlation sapmle,是计算光流的cost valume的重要操作。不知道啥是cost valume可以去知乎搜索一下。作者这里用他是计算 q i q_i qi和在key上以i为中心的网格中被选取的特征的相似度。

所谓的截取,就是已知 q i q_i qi应该在哪个位置截取,就使用grid sample取出来。

这篇关于MAST: A Memory-Augmented Self-Supervised Tracker论文解读和代码剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/247398

相关文章

解读GC日志中的各项指标用法

《解读GC日志中的各项指标用法》:本文主要介绍GC日志中的各项指标用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基础 GC 日志格式(以 G1 为例)1. Minor GC 日志2. Full GC 日志二、关键指标解析1. GC 类型与触发原因2. 堆

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL之InnoDB存储页的独立表空间解读

《MySQL之InnoDB存储页的独立表空间解读》:本文主要介绍MySQL之InnoDB存储页的独立表空间,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、独立表空间【1】表空间大小【2】区【3】组【4】段【5】区的类型【6】XDES Entry区结构【

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

MySQL主从复制与读写分离的用法解读

《MySQL主从复制与读写分离的用法解读》:本文主要介绍MySQL主从复制与读写分离的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、主从复制mysql主从复制原理实验案例二、读写分离实验案例安装并配置mycat 软件设置mycat读写分离验证mycat读

Python的端到端测试框架SeleniumBase使用解读

《Python的端到端测试框架SeleniumBase使用解读》:本文主要介绍Python的端到端测试框架SeleniumBase使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录SeleniumBase详细介绍及用法指南什么是 SeleniumBase?SeleniumBase