【小白笔记】CFNet:End-to-end representation learning for Correlation Filter based tracking

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_27318881/article/details/82830202


这是CVPR17的一篇文章。 项目地址
该论文主要基于SiameseFC网络的改进,主要加入了CF层,并推导了前向和反向公式,也是端到端的网络,使得网络在浅层特征下也能有不错的性能,是整体网络轻量化,速度也更快。下面的分析将结合具体的代码,有不对的地方欢迎讨论~

1.网络结构

基础及背景这里就不说了,直接来看模型。
在这里插入图片描述
为什么要加这个CF层:
结合传统的DCF进行对比,DCF就是线性核的KCF,DCF分为训练和检测两步,训练时用最小二乘法解一个岭回归问题把CF模板w求出来,检测时w和搜索域的patch卷积就得到了response,所以CFNet的原版SiameseFC没有训练直接把目标和搜索域做相关,比较naive,所以CFNet把DCF的一套都整合到了网络中,是一个端到端的模型,由于加入了最小二乘的思想所以浅层也能有不错的性能,但是这样做的问题是把CF的边界问题也带到网络中去了,所以作者又加了crop层仅保留中间的一部分,这就把边界效应降低了。
CF层怎么设计:
这里首先要会推导岭回归的最小二乘解w,然后把计算w的过程拆成能用网络表示的3步如下:
在这里插入图片描述
不要忘了DCF的重要性质样本x是循环样本,这样可以利用频域加速求解,卷积变成了点乘,如下:
在这里插入图片描述
这样就可以表示成一个网络流的形式如下图:
在这里插入图片描述

2. 构建基础特征网络

CFNet的两个支流的提特征部分是完全一样的,这也是Siamese的意思,训练也是只要训一支就好了,就是共享参数,这里使用了AlexNet的五层卷积结构,代码中解释如下:
以第一层为例,包括卷积,normalization和pooling操作

net = add_block(net, opts, '1', 11, 11, ...
                opts.num_in(i), opts.num_out(i), ...
                opts.conv_stride(i), 0, 1) ;
net = add_norm(net, opts, '1') ;
net.layers{end+1} = struct('type', 'pool', 'name', 'pool1', ...
                           'method', 'max', ...
                           'pool', [3 3], ...
                           'stride', opts.pool_stride(i), ...
                           'pad', 0) ;

(11,11)是滤波器大小,pooling的stride为2,且只有前两层有pooling,卷积层stride除了第一层是2,其余都是1;
卷积层输入输出通道数表示如下,至于输出为什么是输入的两倍这是因为AlexNet网络是用2台GPU跑的,计算量分到了两台GPU上。

层数 1 2 3 4 5
输入 3 48 256 192 192
输出 96 256 384 384 256

3. 构建CF层

在构建CF层之前作者加了加窗层,目的和传统一样,抑制边界效应。

join.addLayer('cf_window', MulConst(), ...
                  {'in1'}, {'cf_example'}, {'window'});

这里的MulConst函数是作者设计的,MulConst中前传反传的核心代码在mul_const函数中如下:

function varargout = mul_const(x, h, der_y)
% x is [m1, m2, p, b]
% h is [m1, m2]
% der_y is same size as x

if nargin < 3
    der_y = [];
end

if isempty(der_y)
    y = bsxfun(@times, x, h);
    varargout = {y};
else

else
    der_x = bsxfun(@times, der_y, h);
    der_h = sum(sum(der_y .* x, 3), 4);
    varargout = {der_x, der_h};
end

end

反传的时候的误差是用前一层的误差和窗点乘,再按通道和batch求和。
然后加入CF层

join.addLayer('cf', ...
                      CorrFilter('lambda', join_opts.lambda, ...
                                 'bias', join_opts.bias), ...
                      {'cf_example'}, cf_outputs, {'cf_target'});

看看具体CF函数是如何构建的

未完待续~

猜你喜欢

转载自blog.csdn.net/sinat_27318881/article/details/82830202