SiamRPN 论文阅读
这是来自商汤的一篇文章 发表在CVPR2018上http://openaccess.thecvf.com/content_cvpr_2018/papers/Li_High_Performance_Visual_CVPR_2018_paper.pdf
这个是官方的一个github链接,里边包含了siamFC,siamRPN,siamRPN++,DasiamRPN,siamMask:https://github.com/STVIR/pysot
摘要
提出了 Siamese region proposal network (Siamese-RPN),一个端到端的线下使用大尺度图像对的网络。
在原来的siamese网络上加上了两分支的区域提案网络,一个分支是分类,一个分支是回归。
在推理阶段,这个框架是一个本地的单样本检查任务。
即siamese网络对模板提取特征,提取一次放在那里,然后每次只提取搜索区域的特征,然后将模板的特征拿过来和搜索区域的特征做DW卷积就好。
1 介绍
现代的跟踪器可以粗略的分为两类,
第一类是基于correlation filter,相关滤波器,就是利用循环相关的一个特性训练一个回归量,并在傅里叶域进行操作。
它可以有效的实现在线追踪并更新滤波器的权重。
近期的相关滤波使用深层次的特征来提升准确度,但是模型大是模型更新缓慢。
另一类方法使用使用强壮的深度特征并且不更新模型,但是没有使用域的信息,所以表现不如相关过滤好。
这篇文章我们提出的siamrpn很好,不啦不啦不啦。
贡献:
1 为跟踪任务提出端到端的离线训练的大尺度图片对的siamrpn网络。
2 提出的单样本检查,可以不需要昂贵的多尺度检测。(这难道不是siamFC的吗。。。,人家早就说把搜索区域定在上一帧目标的位置,这样就避免的检测很多区域,也规避了多尺度变化)
3 效果很好(。。。。这样能算贡献,效果不好你能出来混?不应该写由于什么贡献所以效果好吗???)
2 相关工作
2.1. Trackers based on Siamese network structure
总结了siamFC,和CFnet,然后提出不足。
说siamfc第一次提出了相关层,大大提升了精度。
The reason of its success is the densely supervised heatmap when comparing to GOTURN’s one proposal regression, which enables Siamese-FC more robust to fast-moving objects.
这就我是这样理解的:使用了密集摆法anchor的方式,使得siamfc能够应付快速移动的物体。
但Siamese-FC和CFNet都缺乏边界框的回归和需要做多尺度测试使它不太优雅。
siamfc做多尺度测试了???
然后没有最先进的相关滤波方法准确和鲁棒性强。(不知道是用siamfc和哪个算法对比的)
2.2. RPN in detection
RPN是Faster R-CNN提出来的,之前的提案方法太耗时了,例如Selective Search。
多个anchor和分享卷积特征使得RPN的效率和准确性较高。
RPN可以提取更加精细的提议,因为更强的前后景分类和bbox回归。
不啦不啦不啦
2.3. One-shot learning
解决one-shotlearning的两个主要方法是贝叶斯统计方法和元学习方法
3. Siamese-RPN framework
3.1. Siamese feature extraction subnetwork
在siamese网络中我们采用全卷积的网络并且不使用padding。
backbone使用的是修改过的AlexNet。
3.2. Region proposal subnetwork
RPN网络一共两个分支,一个分支是分类分支,一个分支是回归分支。
分类分支每个anchor输出两个结果,一个是是与目标相同的类别,另一个是不是与目标同一个类别。
回归分支输出4个数值,xywh。
所以如果每个anchor点位有k个anchor的话,那么分类分支每个点输出2k个值,回归分支每个anchor点输出4k个值。
假如最后的score map大小为17 * 17,那么最终输出的是一个17 * 17 * 2k的分类答案,和一个17 * 17 * 4k的回归答案。
注意这里的xywh都是处理过的,要恢复成真实值才能使用。
恢复方法如下:
假设输出的四个值为lx,ly,lw,lh
真实的位置为Tx,Ty,Tw,Th
当前anchor的位置和大小为Ax, Ay, Aw, Ah
$$ lx = \frac{Tx-Ax}{Aw}, ly = \frac{Ty-Ay}{Ah} $$
$$ lw = ln\frac{Tw}{Aw}, lh = ln\frac{Th}{Ah} $$
相当与是相对与当前anchor的一个归一化,然后又因为对w,h要求较高一点,所以使用ln函数,将原来$\frac{Tw}{Aw}\in(0,1)$的范围扩展到(-无穷,0),这样可以更精细的调参。
损失函数是参照Faster R-CNN的损失函数,分类损失是cross-entropy loss,然后使用smooth L1 loss给正则化的回归候选。
$$ smooth_{L_1}(x, \delta) = \begin{cases} 0.5\delta^2x^2,&|x|<\frac{1}{\delta^2}\\ |x|-\frac{1}{2\delta^2},&|x|\geq\frac{1}{\delta^2} \end{cases} $$
最后的损失是:
$$ loss = L_{cls}+\lambda L_{reg} $$
$\lambda$是一个平衡这两个损失的一个超参数。
设$\delta[i],i\in[0,3]$分别代表lx,ly,lw,lh
$$ L_{reg} = \sum_{i=0}^3smooth_{L_1}(\delta[i],\delta) $$
3.3. Training phase: End to end train SiameseRPN
由于目标在相邻的两帧不会变化太远,所以我们在跟踪任务使用比检测任务更少的anchor数量。所以只有一种尺度,对应不同方向的anchor被我们使用了,长宽比分别为[0.33,0.5,1,2,3].
这一点不是人家siamfc提出的嘛,别以为我不知道,局部选择搜索区域,从而提高了跟踪速度。然后仅仅选择几个不同的长宽比的anchor。
挑选正负样本的方式也很重要。
这里选择的判别条件是iou,有两个iou域值,$th_{hi}$, $th_{lo}$, 当iou大于$th_{hi}$时,我们才认为是一个正样本,当iou小于$th_{lo}$时我们才认为是一个负样本,理论上这样会使算法能够更好的定位目标,以为对于正负样本的定义更加合理了,那些只有一般iou的anchor我们不去修正他们,以为有一般iou的anchor你即不好说他是错误的位置,也不好说他是正确的位置。
这里作者设定$th_{hi}=0.6$,$th_{lo}$=0.3.
然后应该是考虑到正负样本均衡,作者限制每个训练对中,只允许挑选最多16个正样本,和最多64个样本。
就是说,你去在一个视频中的一帧找了一个模板图像,然后再在同一个视频中找一个大小更大的搜索图像嘛,搜索图像你要给label嘛,这个label咋给呢,就是iou大于$th_{hi}=0.6$的地方才允许设置为1,正样本,iou小于$th_{lo}$的地方才允许设置为-1,负样本,其他位置不给label,设置为0,最后算loss的时候,只算那些label为1或-1的地方。
我记得官方代码中正样本是1,负样本是0,无效是-1,这个无所谓了。明白就好。
我们把one-shot 检测当作一个有判别力的任务,目的是找到一个参数W,使得在一个数据集上预测函数$\psi(x;W)$的平均损失最小。
$l_i$表示真实标签d
$$ \underset{W}{min}\frac{1}{n}\sum_{i=1}^nL(\psi(x_i;W),l_i) $$
one-shot learning 旨在学到一个W从一个单一的模板图像。
对于一个要有判别力的one-shot learning来说学会一个找到包含类别信息的机制是很有挑战性的,即学会学习,为了达到这个挑战,我们提出了一种使用元学习的过程学习参数W的一个方法。
一个前馈函数$\omega$去映射$(z;W^{'})$到W,设$z_i$为一个批次的模板,那么有公式:
$$ \min_{W^{'}}\frac{1}{n}\sum_{i=1}^nL(\psi(x_i;\omega(z_i;W^{'}));l_i) $$
$\psi$指siamese的特征提取函数。
令$\zeta$为RPN网络。
那么one-shot learning 检测任务可以写为:
$$ \min_W\frac{1}{n}\sum_{i=1}^nL(\zeta(\psi(x_i;W);\psi(z_i;W)),l_i) $$
这个图说,模板图像的特征只需要在跟踪之前提取一次,特征保留着,等着相关操作就好了,提高了算法的运行效率。
4.2. Inference phase: Perform oneshot detection
不啦不啦,还是之前哪个xywh如何转换为真实值的问题。
4.3. Proposal selection
RPN网络提议的选择。
第一个选择条件是丢去距离目标中心位置太远的anchor的提议,就是说,即使距离较远的anchor相应较高也不用,因为通常目标在相邻的两帧图像中并不会相差很远。
假如我们有w * h个anchor,我们只用靠近中心的g * g个anchor的答案。本论文选择的g=7,就是中间7 * 7 =49 个anchor的答案,来确定目标的位置。
第二个策略是使用余弦窗和尺度变化惩罚对提案进行重拍等级。然后去找到分数最高的哪个提案。
当把较远的排除掉后,在加上余弦窗,可以防止目标方法发生大幅度的不正常位移,加上尺度变化惩罚,可以防止目标大小发生大的变化。
惩罚公式如下:
$$ penalty = e^{k * \max(\frac{r}{r^{'}}, \frac{r^{'}}{r}) * \max(\frac{s}{s^{'}},\frac{s^{'}}{s})} $$
k是一个超参数,r表示上一帧目标的长宽比,$r^{'}$是现在目标的长宽比,s是表示上一帧的一个类似面积的东西,$s^{'}$是当前帧的。s的计算如下:
$$ (w+p)*(h+p)=s^2, p=(w+h)/2 $$
这两个策略使用过后使用NMS(Non-maximum-suppression)来找到最终的目标位置和大小。
After the final bounding box is selected, target size is updated by linear interpolation to keep the shape changing smoothly.
这句说的是自己又用插值法调整了目标的大小.
lr = penalty[best_idx] * score[best_idx] * cfg.TRACK.LR
# smooth bbox
width = self.size[0] * (1 - lr) + bbox[2] * lr
height = self.size[1] * (1 - lr) + bbox[3] * lr
5 Experiments
测试结果,不写了