目标跟踪解析:ATOM:Accurate Tracking by Overlap Maximization

ATOM:Accurate Tracking by Overlap Maximization

关于siamese系列的跟踪网络,之前已经看得比较详细了,无论是anchor-free的还是anchor-based。然而,一直想完成一下Martin Danelljan的基于判别力的两个跟踪器的分析,今天终于有时间记录一下ATOM(CVPR2019 oral)了,之后有时间再来写DIMP(ICCV2019 oral)。
论文:ATOM: Accurate Tracking by Overlap Maximization
代码:https://github.com/visionml/pytracking

Results

这里先放一下结果吧,有个直观的性能印象:
速度:

ATOM 30 FPS GTX-1080

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Architecture

ATOM整体架构包括两部分:target estimate和classification component。其中target estimate是offline training的,在跟踪过程中保持不变了,主要就是一个IoU Predictor,根据输入的gt bbox的特征和proposals的特征,来直接预测两者之间的IoU;classification是online learning的【这部分还没看,所以先不敢乱说】,如下图所示:
在这里插入图片描述

Offline Training

离线训练只是针对target estimate,为的是让网络学习一种general representation for IoU prediction。因为motivation借鉴自目标检测里面的IoU-Net,所以对于跟踪这种target-specific的任务怎么去学习,作者就论证要充分利用第一帧的信息,这里就有三种方法:

  • concatenation: reference和test image的激活值在送入最后预测IoU之前拼接在一起
  • siamese: reference和test分支使用相同的网络结构,最后输出一个标量的IoU
  • modulation based: 把第一帧的特征作为调制向量来融入到IoU预测中(顺便说一句,这个思想他们用的还挺多的,比如KYS中的state vector)
    结果证明第三种方法最好,这一部分的IoU Predictor的网络如下图所示:其中为了得到固定的输出大小,还使用了PrPooling。

The IoU-predictor takes four inputs: i) backbone features from current frame, ii) bounding box estimates in the current frame, iii) backbone features from a reference frame, iv) the target bounding box in the reference frame.

具体的做法就是在reference image中获得图片,然后送入backbone获得特征,然后把对应目标位置的特征pooling下来,最后生成modulation vector,在test image中会在目标周围生成16个proposals,然后也把他们的特征pooling下来,和modulation vector相乘之后再concatenate之后再经过全连接得到16个IoU。(代码里面稍微有点不同,代码里面是先与modulation vector相融合再prpooling)
在这里插入图片描述
可以看一下代码的部分:

# Create network and actor
net = atom_models.atom_resnet18(backbone_pretrained=True)  # include backbone_net, iou_predictor
objective = nn.MSELoss()
actor = actors.AtomActor(net=net, objective=objective)

# Optimizer: keep backbone fixed
optimizer = optim.Adam(actor.net.bb_regressor.parameters(), lr=1e-3)
lr_scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=15, gamma=0.2)

# Create trainer
trainer = LTRTrainer(actor, [loader_train, loader_val], optimizer, settings, lr_scheduler)

# Run training (set fail_safe=False if you are debugging)
trainer.train(50, load_latest=True, fail_safe=True)
# Compute loss
# iou_pred shape: (4,16) iou_gt shape: (4,16) assume batch_size=4
loss = self.objective(iou_pred, iou_gt)

从上面可以看出:

  1. 使用了预训练的resnet18,定义了更新bb_regressor的参数初始学习率,也就是iou_predictor部分,backbone不更新参数
  2. 用了mean square error来衡量IoU之间的损失
  3. 在训练的时候同时用了训练数据和验证数据来看看训练的效果(验证集跑的频率会低一点)

这里其实是有个小问题的,就是PrPooling部分,送入的proposals的位置是原图上的,而不是对应到特征图上的位置,但是PrRoIPool2D(3, 3, 1/8)使用时会有第三个参数,就是原图到特征图的stride或者叫做scale factor,这样就能从特征图中pooling下来对应目标位置的特征了
更加直白的讲,就是给定一个真实目标框的特征,然后输入其他一些随机的框(已知与目标框的真实的IoU),然后训练iou_predictor,达到一个预测IoU的目的,可看下面的图示意:
在这里插入图片描述
他们之间的真实IoU分别是: 0.1749, 0.9444, 0.2505, 0.5073, 0.8344, 0.4946, 0.3811, 0.8253, 0.8629, 0.1295, 0.9223, 0.8482, 0.9558, 0.9312, 0.3689, 0.7361

Online classification

因为target estimation module提供了准确的bounding box的回归,但是缺少对目标和背景干扰物的辨别能力,所以用一个taget classification module去补上这块,提出两层的全卷积(兼顾效率和收敛性)来在线分类,提供一个粗略的2D目标位置,以j减少错误的检测来提高鲁棒性。Online classification用的是resnet18 block4的特征,而target estimation用的是block3和block4的特征。模型如下:
f ( x ; w ) = ϕ 2 ( w 2 ∗ ϕ 1 ( w 1 ∗ x ) ) (2) f(x;w)=\phi_{2}(w_{2}*\phi_{1}(w_{1}*x)) \tag{2} f(x;w)=ϕ2(w2ϕ1(w1x))(2)
其中 ϕ 1 \phi_{1} ϕ1, ϕ 2 \phi_{2} ϕ2是两个激活函数,, w 1 w_{1} w1是一个 1 ∗ 1 1*1 11,输出通道为64的卷积层, w 2 w_{2} w2一个 4 ∗ 4 4*4 44,输出通道为1的卷积层。这里的输入 x x x就是training sample的从backbone提取出来的特征。
然后我们可以把在线训练的目标函数写成一个L2形式的优化问题:
L ( w ) = ∑ j = 1 m γ j ∥ f ( x j ; w ) − y j ∥ 2 + ∑ k λ k ∥ w k ∥ 2 (3) L(w)=\sum_{j=1}^{m} \gamma_{j} \Vert f(x_{j};w)-y_{j}\Vert ^2+\sum_{k} \lambda_{k} \Vert w_{k} \Vert^2 \tag{3} L(w)=j=1mγjf(xj;w)yj2+kλkwk2(3)
我们把残差记作:  r j ( w ) = γ j ( f ( x j ; w ) − y j ) , j ∈ { 1 , . . . , m } r_{j}(w)=\sqrt{\gamma_{j}}(f(x_{j};w)-y_{j}), j \in \{ {1,...,m}\} rj(w)=γj (f(xj;w)yj),j{ 1,...,m} r m + k ( w ) = λ k w k , k = 1 , 2 r_{m+k}(w)=\sqrt{\lambda_{k}}w_{k}, k=1,2 rm+k(w)=λk wk,k=1,2,然后我们就能把目标函数写作 L ( w ) = ∥ r(w) ∥ 2 L(w)= \Vert \textbf{r(w)} \Vert^2 L(w)=r(w)2 r(w) \textbf{r(w)} r(w)是所有 r j ( w ) r_{j}(w) rj(w)的concatenation。而这种平方和最小化问题是可以用一种特定的优化方法来解决的:高斯牛顿法。
下面我们来推导一下论文中的几个公式:
一阶泰勒展开这是容易的: r ( w + Δ w ) ≈ r w + ∂ r ∂ w Δ w = r w + J w Δ w r(w+\Delta w) \approx r_{w}+\frac{\partial r}{\partial w}\Delta w=r_{w}+J_{w}\Delta w r(w+Δw)rw+wrΔw=rw+JwΔw
又因为 L ( w ) = ∥ r(w) ∥ 2 L(w)= \Vert \textbf{r(w)} \Vert^2 L(w)=r(w)2,所以
L ( w + Δ w ) = ∥ r ( w + Δ w ) ∥ 2 = ∥ r w + J w Δ w ∥ 2 = Δ w T J w T J w Δ w + 2 Δ w T J w T r w + r w T r w (4) L(w+\Delta w)= \Vert r(w+\Delta w) \Vert^2=\Vert r_{w}+J_{w}\Delta w \Vert^2=\Delta w^TJ_{w}^TJ_{w}\Delta w+2\Delta w^TJ_{w}^T r_{w}+ r_{w} ^Tr_{w} \tag{4} L(w+Δw)=r(w+Δw)2=rw+JwΔw2=ΔwTJwTJwΔw+2ΔwTJwTrw+rwTrw(4)
但是 L ~ w ( Δ w ) ≈ L ( w + Δ w ) \widetilde{L}_{w}(\Delta w) \approx L(w+\Delta w) L w(Δw)L(w+Δw)我还是不太明白,估计就是转移到学习 Δ w \Delta w Δw上来。而共轭梯度法是解决线性方程组问题的。论文后面的算法部分确实看不懂了,虽然花了点时间看了Conjugate Gradient还有Gauss-Newton还是啃不动论文理论部分(这就是follow马丁难的一部分原因),这里还是贴一下吧:
在这里插入图片描述
看不懂上面的没事,只要明白下面的也行:

  • 第一帧: 在第一帧用translation, rotation, blur, dropout数据增强手段产生30个初始的training samples x j x_{j} xj,然后用算法1进行 N G N = 6 N_{GN}=6 NGN=6次的高斯牛顿, N C G = 10 N_{CG}=10 NCG=10次的共轭梯度优化 w 1 w_{1} w1, w 2 w_{2} w2,这里可视化一下训练样本和标签,有一个直观的感受:
    这是23个initial patched,另外的7个是从提取到的特征再用dropout生成7个特征,所以最后就是这样30个训练样本
    在这里插入图片描述

下面左边这幅图就是30个resnet18 block4的经过数据增强的特征图(代码中的layer3),最后7个特征图是第一幅图经过dropout得到的,所以和第一幅图比较像,右边是他们对应的标签,可以看到位置是对应的。
在这里插入图片描述

  • 后续帧:当后续帧输入进来的时候,就先经过classification model更新得到当前一个粗糙的2D位置,而根据前一帧的宽高信息就会得到一个初始框B,当然这时输入给IoU predictor就会得到一个预测出来的IoU,可能并不会很高,这时候就要去优化refine。这时作者提出更好的做法是根据B生成10个proposals,用5步梯度上升来优化框的坐标来获得更高的IoU,这其中也会每10帧进行 N G N = 1 N_{GN}=1 NGN=1次的高斯牛顿, N C G = 5 N_{CG}=5 NCG=5次的共轭梯度优化 w 2 w_{2} w2,取最后的最高IoU的三个框的平均值为最后预测结果,这一部分主要在refine_target_box函数。【第一次看会不会觉得很绕,可是就是这样,其实这里面还有很多坐标平滑,判断跟踪flag为’not_found’,‘hard_negative’,'uncertain’等不同情况而用不同的量去update state,所以代码的话是有很多细节堆起来的】

Bonus

视频讲解链接:https://www.bilibili.com/video/BV1H54y167rG

猜你喜欢

转载自blog.csdn.net/laizi_laizi/article/details/109455080