SiameseFC超详解

article/2025/9/30 19:50:07

SiameseFC

  • 前言
    • 论文来源
    • 参考文章
  • 论文原理解读
    • 首先要知道什么是SOT?(Siamese要做什么)
    • SiameseFC要解决什么问题?
    • SiameseFC用了什么方法解决?
    • SiameseFC网络效果如何?
    • SiameseFC基本框架结构
    • SiameseFC网络结构
    • SiameseFC基本流程
    • SiamFC完整的跟踪过程
  • 论文的思考与优化
    • SiameseFC的优点:
    • SiameseFC的不足:(Siamese一直有鲁棒性不好的问题)
  • 论文代码解读
    • 训练阶段:
    • 1.backbones.py分析
    • 2.heads.py分析
    • 3.train.py分析
    • 4.transforms.py分析
    • 5.ops.py分析(train相关部分)
    • 6.datasets.py
    • 7.siamfc.py分析(重点:train相关部分)
    • tracking部分:
    • siamfc.py(tracking部分)
  • 论文翻译+解读
    • Abstract
    • 1 Introduction
    • 2 Deep Similarity Learning for Tracking
    • 2.1 Fully-Convolutional Siamese Architecture
    • 2.2 Training with Large Search Images
    • 2.3 ImageNet Video for Tracking
    • 2.4 Practical Considerations
    • 3 Related Work
    • 4 Experiments
    • 4.1 Implementation Details
    • 4.2 Evaluation
    • 4.3 The OTB-13 Benchmark
    • 4.4 The VOT Benchmarks
    • 4.5 Dataset Size
    • 5 Conclusion

前言

论文来源

论文:Fully-Convolutional Siamese Networks for Object Tracking
项目官方地址(包括论文下载地址、源码地址等):这里

参考文章

论文阅读:SiameseFC
精读深度学习论文(31) SiameseFC
【SOT】siameseFC论文和代码解析
浅谈SiameseFC的优点与不足
siamfc-pytorch代码讲解(一):backbone&head
SiamFC完整的跟踪过程
其余的文章参考较少,在文中时会给出参考文章。

论文原理解读

首先要知道什么是SOT?(Siamese要做什么)

SOT的思想是,在视频中的某一帧中框出你需要跟踪目标的bounding box,在后续的视频帧中,无需你再检测出物体的bounding box进行匹配,而是通过某种相似度的计算,寻找需要跟踪的对象在后续帧的位置,如下动图所示(图中使用的是本章所讲siameseFC的升级版siameseMask),常见的经典的方法有KCF[2]等。

SiameseFC要解决什么问题?

而目前基于深度学习的方法,要不就是采用 shallow methods(如:correlation filters)利用网络的中间表示作为 feature;要不就是执行 SGD 算法来微调多层网络结构。但是,利用 shallow 的方法并不能充分发挥 end-to-end 训练的优势,采用 SGD 的方法来微调也无法达到实时的要求。

将DL用于tracking中,有两点制约其发展:

1、训练数据的稀缺。由于跟踪目标事先未知,只能通过最初的框选定,无法预先准备大量训练数据。

2、实时的约束。对于跟踪问题来说,基于DL的做法虽然能有效提升模型的丰富度,能够很好的提升跟踪的效果,但是在时效性这一方面却做的很差,因为DL复杂的模型往往需要很大的计算量,尤其是当使用的DL模型在跟踪的时候需要对模型进行更新的话,需要在线SGD调整网络参数,限制了速度,可能使用GPU都没法达到实时。

SiameseFC分别针对这两点,利用ILSVRC15 数据库中用于目标检测的视频来训练模型(离线训练),在跟踪时,不更新模型(也就没有fine-tuning),保证速度够快。成为了使用了CNN进行跟踪,同时又具有很高的效率的跟踪算法。并因其速度很快,效果很好,成为之后很多算法(例如CFNet、DCFNet)的baseline。

SiameseFC用了什么方法解决?

使用孪生网络(Siamese Net)结构来进行相似度比较,对比模版图片(在训练前应该指定好)和需比较的目标图片之间的相似度。

SiameseFC网络效果如何?

速度是SiameseFC的最大优势。
可以用于追踪任意物体(不需要预先训练)。
在当时某几个benchmark上达到了最优。

SiameseFC基本框架结构

在这里插入图片描述
图中z代表的是模板图像,算法中使用的是第一帧的groundtruth;x代表的是search region,代表在后面的待跟踪帧中的候选框搜索区域;ϕ代表的是一种特征映射操作,将原始图像映射到特定的特征空间,文中采用的是CNN中的卷积层和pooling层;66128代表z经过ϕ后得到的特征,是一个128通道66大小feature,同理,2222128是x经过ϕ后的特征;后面的代表卷积操作,让2222128的feature被66128的卷积核卷积,得到一个17*17的score map,代表着search region中各个位置与模板相似度值。score越大,相似度越大,越有可能是同一个物体。

总体来说,卷积网络将search image作为整体输入,直接计算两个输入图像的feature map的相似度匹配,节省了计算。计算得到相似度最高的位置,并反向计算出目标在原图中的位置。

算法本身是比较搜索区域与目标模板的相似度,最后得到搜索区域的score map。其实从原理上来说,这种方法和相关性滤波的方法很相似。其在搜索区域中逐个的对目标模板进行匹配,将这种逐个平移匹配计算相似度的方法看成是一种卷积,然后在卷积结果中找到相似度值最大的点,作为新的目标的中心。

上述互相关运算的步骤,像极了我们手里拿着一张目标的照片(模板图像),然后把这个照片按在需要寻找目标的图片上(搜索图像)进行移动,然后求重叠部分的相似度,从而找到这个目标,只不过为了计算机计算的方便,使用AlexNet对图像数据进行了编码/特征提取。

上图所画的ϕ其实是CNN中的一部分,并且两个ϕ的网络结构是一样的,这是一种典型的孪生神经网络,并且在整个模型中只有conv层和pooling层,因此这也是一种典型的全卷积(fully-convolutional)神经网络。

如果上面没看懂,下面给出另一种我觉得也很棒的解释:

孪生结构网络是卷积神经网络中的一种特殊结构。其结构如上图所示,它由两个结构相同的子网络构成,网络的输入是两张像,其中一张称为模板图像,通常选取的是序列第一帧,另外一张称为搜索图像,选取的是后续帧,每一个子网络负责处理一张图像,通过子网络的前向计算,可以提取图像的特征,最后将两者特征通过相似性度量函数,最终计算得到一个17×17×1的热力图,代表着搜索图像中各个位置与模板图像的相似度值。并根据以下函数计算相似度(卷积函数):
在这里插入图片描述

其中z是模板图像,x是搜索图像,
φ代表的是一种特征映射操作,将原始图像映射成特定的空间特征,这里采用的是卷积神经网络里的卷积层和池化层,f是相似性度量函数,这里代表的是卷积函数。模板图像虽然使用的是视频序列的第一帧,但是它是经过裁剪而来的,以待跟踪目标为中心,把原图像裁剪成127×127的尺寸。
也是经过裁剪而来的,它是以网络上一次输出的目标位置的中心点作为裁剪的中心,裁剪成固定的255×255的尺寸。
在这里就相当于充当一个待跟踪目标的外观模型,与后续图像帧里面的对象进行配对,热力图最里面分值最高的那个点则认为是与待跟踪对象外观模型最相似,就认为它是后续帧里的待跟踪对象。

SiameseFC网络结构

用模板的CNN特征与搜索图像的特征进行卷积,得到整个图像的相似图。网络结构如下:(有的博客中说整个网络结构类似与AlexNet,但是没有最后的全连接层,只有前面的卷积层和pooling层。 )
在这里插入图片描述
整个网络结构入上表,其中pooling层采用的是max-pooling,每个卷积层后面都有一个ReLU非线性激活层,但是第五层没有。另外,在训练的时候,每个ReLU层前都使用了batch normalization,用于降低过拟合的风险。

SiameseFC基本流程

一,获取输入数据:
SiameseFC需要的输入数据有模版图片z和候选图片x。

  1. 模版图片z的构建:
    1. 构建模版图片时,知道当前帧的bbox。
      1. 训练时,所有图片的bbox都是已知的。
      2. 预测时,第一帧bbox已知的,且预测是顺序预测,因此,预测过程中,预测帧前一帧的bbox是已知的。
    2. 总体过程:
      1. 以bbox的中心为中心,构建一个面积为127*127的区域,如果超出范围则通过平均值进行pad。
      2. 将该区域resize为127*127。(上一步中的长宽可能不是127)
    3. 构建127127区域的方式如下:其中A=127127,h和w代表bbox的长宽:
      在这里插入图片描述
  2. 候选图片x的构建:
    1. 构建时已知其上一帧bbox的信息。
    2. 总体过程:
      1. 以上一帧bbox的中心为中心,构建一个面积为255*255的区域,如果超出范围则通过平均值进行pad。
      2. 将该区域resize为255*255。(上一步中的长宽可能不是255)
      3. 构建255*255区域与构建模版图片z时采用相同的缩放比例。

二,通过分数矩阵获取追踪结果

总体过程:

  1. 首先,对分数矩阵进行线性变换,变换到原始图片的大小。
  2. 如图中,将图片1717分数矩阵转换为255255。
  3. 然后,结合位置信息,获取最终得分信息。
  4. 最后,选择得分最高的位置作为中心,获取最新的bbox。
  5. bbox的长宽跟之前一帧的长宽一致。

三,通过分数矩阵进行训练

  1. 使用交叉熵作为损失函数。对于score map中每个点,损失函数如下:

    1. 其中,其中v是score map中每个点真实值,y∈{+1,−1}是这个点所对应的标签。
      在这里插入图片描述
  2. 总体损失函数如下:
    6×6和22×22的feature map“卷积”得到17×17的score map。对于每个score map,计算其loss为每个卷积得到的6*6小图的loss的均值。即:
    在这里插入图片描述
    这里的u∈D代表score map中的位置。 卷积网络的参数由SGD方法最小化上图损失函数得到。这里采用的是卷积神经网络里的卷积层和池化层,f是相似性度量函数,这里代表的是卷积函数。

  3. 构建标签y
    比较预测bbox中心点与 ground truth 的bbox中心点之间的距离。
    在这里插入图片描述

  4. 计算相似度(卷积函数)
    根据以下函数计算相似度(卷积函数):
    在这里插入图片描述

    其中z是模板图像,x是搜索图像, φ代表的是一种特征映射操作,将原始图像映射成特定的空间特征

四, 多尺寸处理

思路:

  1. 模版图片z保持不变。
  2. 对搜索图片x进行尺寸变换,同样提取255*255的区域,计算相似度,获取相似度最大点的坐标。
  3. 对于最终bbox进行等比例变换(比例就是对搜索图片x进行变换的比例)。

五,训练的一些细节

  1. 训练采用的框架是MatConvNet
  2. 训练采用的优化算法就是batch SGD,batch大小是8
  3. 跟踪时直接对score map进行线性插值,将1717的score map扩大为272272,这样原来score map中响应值最大的点映射回272*272目标位置。
  4. 对训练的数据库中数据进行一些处理
    1. 扔掉一些类别: snake,train,whale,lizard 等,因为这些物体经常仅仅出现身体的某一部分,且常在图像边缘出现;
    2. 排除太大 或者 太小的物体;
    3. 排除离边界很近的物体。

SiamFC完整的跟踪过程

参考:SiamFC完整的跟踪过程

  1. 准备两路输入图像:模板图像和检测图像。

    1. 设置模板图像和检测图像的边长,分别用z_sz和x_sz表示。

      1. 设置content,前后文信息
        在这里插入图片描述

        在这里插入图片描述

      2. 设置z_sz = sqrt(Az)
        在这里插入图片描述

        在这里插入图片描述

      3. 设置x_sz=sqrt(Ax)
        同上

    2. 对模板图像而言:在第一帧以z_sz为边长,以目标中心为中心点,截取图像补丁(如果超出第一帧的尺寸,用均值填充)。之后将其resize为127x127x3.成为模板图像

    3. 对检测图像而言:在第二帧及以后,分别以x_sz*1.0375^{[-2,-0.5,1]}为边长,以前一帧目标中心为中心点,截取图像补丁(如果超出第一帧的尺寸,用均值填充)。之后将三个图像补丁都resize为255x255x3.成为检测图像

  2. 将模板图像和检测图像输入CNN网络中,分别得到6x6x128和22x22x128的特征图。

  3. 最后使用交叉相关,将模板图像的特征图当做卷积核,对检测图像的特征进行滑窗检测,最后得到3x1x17x17的得分图(三个尺度)。交叉函数如下所示:
    f(x,z)=φ(z)∗φ(x)+bi​

  4. 使用双三次线性插值生成277x277的图像: 3x277x277.

  5. 获得三个得分图中最大值的位置(x,y)。

  6. 获得最大值位置与上一帧目标中心的相对位移。

  7. 因为之前是crop,再resize得到检测图像,之后CNN(包含交叉卷积)得到得分图,最后上采样得到[3,277,277]。所以将第(6)步得到的相对位移进行逆运算,最终获得视频帧之间的相对位移。

  8. 根据相对位移更新目标的中心点。

  9. 获得目标尺寸变换的比例(最大值所在的尺度(三个尺度中的一个)):
    在这里插入图片描述

    1. 更新目标尺寸:target_sz*scale
    2. 更新x_sz:x_sz*scale
    3. 更新z_sz:z_sz*scale
  10. 画出跟踪框。
    在这里插入图片描述
    这是我详细debug的记录:里面也有对其的一些理解:
    在这里插入图片描述

论文的思考与优化

SiameseFC的优点:

1、实时性(>24帧/s):
SiamFC-3s FPS : 86帧/s
SiamFC-5s FPS : 58帧/s

该网络把跟踪任务转换成一个模板匹配的问题而不是一个常见的二分类问题,整个跟踪过程中不需要更新模板,使得算法的速度大幅度提高。这也是深度学习领域神经网络在目标跟踪一直以来难以到达的一个关键点,直到孪生网络应用于目标跟踪使得在跟踪精度较高的条件下还达到了实时性,在深度学习领域不愧为重大的突破,继此网络后,基于此网络为基本框架的目标跟踪算法层出不尽并且精度、速度能达到一个兼顾,占据深度学习应用在目标跟踪中的主流方向。

2、小范围晃动

对于小范围晃动,背景信息变化不大使得模板匹配的结果较好
在这里插入图片描述
3、运动模糊
在这里插入图片描述
4、短时局部遮挡
模板匹配对短暂性局部遮挡处理较好
在这里插入图片描述

SiameseFC的不足:(Siamese一直有鲁棒性不好的问题)

SiameseFC是一个模板匹配的任务,在跟踪过程中并不更新目标模板和网络权值,这造成如下问题:

(1)当目标发生较大的形变时,会造成目标候选框与目标模板出现较大差异,从而导致跟踪失败。网络权值不更新导致要使用同一套网络结构和网络参数适应所有的跟踪场景,这是很难做到的。

(2)对于没有处于复杂背景下的跟踪来说,该算法能基本平衡实时性与准确性要求,但是跟踪目标一旦发生遮挡、快速运动、相似外观,搜索图像的大小可能就覆盖不了目标,通过最后的相似性度量函数得出来的结果就是错误的,随着跟踪过程中发生的错误累加,导致跟踪不可恢复,所以孪生结构网络的跟踪性能在背景复杂的情况下会下降。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
失败原因:

  1. 目标特征不够具体、突出、全面 (AlexNet提取特征不够细致)

  2. 没能利用好空间信息、运动信息 (运动模型不够合理)

  3. 搜索域方法的局限性 (多尺度增加计算量,无法适应尺度变化)

  4. 匹配与分类的本质差别 (分类对背景前景区分较好)

解决思路:

  1. 加入在线更新的策略(增加目标信息,牺牲速度或者增强特征的提取)

  2. 需要对首帧标注图像做处理(抑制背景信息,增加前景和背景的区分度)
    SiamFC选用第一帧作为模板并不予更新,因此首帧目标信息为关键信息,而SiamFC模型中,最后采用相似度学习,如果不能降模板图像中背景信息的干扰,则必然会对结果造成影响。 因此应当对标注图像进行进一步的目标提取,并对背景信息进行抑制。

  3. 利用空间信息,估计运动模型
    在存在较多相似目标的场景中,可能特征匹配难以准确地判断哪个才是真正的目标。而人在这种场景下追踪目标的策略往往是根据
    (1)目标的空间信息,例如一队人中的第几个,或者目标周围有哪些参照物。这一点可以通过对目标旁边的背景进行建模实现。
    (2)根据目标的运动轨迹进行预测,因为目标的变化(无论是位置还是外观)在序列中往往是连续可微的。

论文代码解读

这里主要参考:siamfc-pytorch代码讲解(三):demo&track
更简洁的请参考:【SOT】siameseFC论文和代码解析讲的也很棒~

训练阶段:

1.backbones.py分析

功能分析:

这个module主要实现了3个AlexNet版本作为backbone,开头的__all__ = [‘AlexNetV1’, ‘AlexNetV2’, ‘AlexNetV3’]主要是为了让别的module导入这个backbones.py的东西时,只能导入__all__后面的部分。
后面就是三个类AlexNetV1、AlexNetV2、AlexNetV3,他们都集成了类_AlexNet,所以他们都是使用同样的forward函数,依次通过五个卷积层,每个卷积层使用nn.Sequential()堆叠,只是他们各自的total_stride和具体每层卷积层实现稍有不同(当然跟原本的AlexNet还是有些差别的,比如通道数上):
AlexNetV1和AlexNetV2:
共同点:conv2、conv4、conv5这几层都用了groups=2的分组卷积,这跟原来的AlexNet会更接近一点
不同点:conv2中的MaxPool2d的stride不一样大,conv5层的输出通道数不一样
AlexNetV1和AlexNetV3:前两层的MaxPool2d是一样的,但是中间层的卷积层输入输出通道都不一样,最后的输出通道也不一样,AlexNetV3最后输出经过了BN
AlexNetV2和AlexNetV3:conv2中的MaxPool2d的stride不一样,AlexNetV2最后输出通道数小很多。
其实感觉即使有这些区别,但是这并不是很重要,这一部分也是整体当中容易理解的,所以不必太去纠结为什么不一样,最后作者用的是AlexNetV1,论文中是这样的结构,其实也就是AlexNetV1:
在这里插入图片描述
代码分析

1.def __init__(self, num_features, *args, **kwargs):中*args和**kwargs到底是什么
参考Python中*args、**args到底是什么、有啥区别、怎么用
*args的用法:当传入的参数个数未知,且不需要知道参数名称时。
**args的用法:当传入的参数个数未知,但需要知道参数的名称时(立马想到了字典,即键值对)

也就是说**args在输入的时候一般是键值对,而*args任意。
注意:这里的args不是必须的,也就是说可以换成kwargs等等,但是星号是必须的。

2.BatchNorm2d函数分析:
参考:BatchNorm2d原理、作用及其pytorch中BatchNorm2d函数的参数讲解
例如BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

  1. num_features:一般输入参数为batch_sizenum_featuresheight*width,即为其中特征的数量,即为输入BN层的通道数;
  2. eps:分母中添加的一个值,目的是为了计算的稳定性,默认为:1e-5,避免分母为0;
  3. momentum:一个用于运行过程中均值和方差的一个估计参数(我的理解是一个稳定系数,类似于SGD中的momentum的系数);
  4. affine:当设为true时,会给定可以学习的系数矩阵gamma和beta
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    3.nn.ReLU(inplace=True)代码分析
    参考:PyTorch------nn.ReLU(inplace = True)详解
    inplace = False 时,不会修改输入对象的值,而是返回一个新创建的对象,所以打印出对象存储地址不同,类似于C语言的值传递
    inplace = True 时,会修改输入对象的值,所以打印出对象存储地址相同,类似于C语言的址传递
    即当inplace = True 时,在原地改变值而不是赋予新值。

4.output stride = 4解析:
output stride为该矩阵经过多次卷积pooling操作后,尺寸缩小的值(这个还保留疑问)

5.__all__ = ['AlexNetV1', 'AlexNetV2', 'AlexNetV3']中__all__解析
参考:python中【all】的用法
__all__是一个字符串list,用来定义模块中对于from XXX import 时要对外导出的符号,即要暴露的接口,但它只对import *起作用,对from XXX import XXX不起作用。
控制 from xxx import * 的行为

6.nn.Conv2d(384, 32, 3, 1, groups=2))这个groups=2

这个groups=2,是将卷积分为两组:
在这里插入图片描述

2.heads.py分析

from __future__ import absolute_importimport torch.nn as nn
import torch.nn.functional as F__all__ = ['SiamFC']class SiamFC(nn.Module):def __init__(self, out_scale=0.001):super(SiamFC, self).__init__()self.out_scale = out_scaledef forward(self, z, x):return self._fast_xcorr(z, x) * self.out_scaledef _fast_xcorr(self, z, x):# fast cross correlation# x size 8,256,20,20# z size 8,256,6,6nz = z.size(0)  #size(0)即取第一个shape值#nz = 8nx, c, h, w = x.size()#nx = 8,c = 256,h = 20,w = 20x = x.view(-1, nz * c, h, w)#x.shape = [1,2048,20,20]out = F.conv2d(x, z, groups=nz)# out.shape = [1,8,15,15]#输入是4维,输出也是4维,高层补1# print(out.size())out = out.view(nx, -1, out.size(-2), out.size(-1))# out.shape = [8,1,15,15]return out

功能分析:
为什么这里会有个out_scale,根据作者说是因为, z zz和x xx互相关之后的值太大,经过sigmoid函数之后会使值处于梯度饱和的那块,梯度太小,乘以out_scale就是为了避免这个。
重点:nn.conv2d和nn.function2d解析
_fast_xcorr函数中最关键的部分就是F.conv2d函数了,可以通过官网查询到用法:

torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1) → Tensor
input – input tensor of shape (\text{minibatch} , \text{in_channels} , iH , iW)(minibatch,in_channels,iH,iW)
weight – filters of shape (\text{out_channels} , \frac{\text{in_channels}}{\text{groups}} , kH , kW)(out_channels, groups in_channels ,kH,kW)
bias – optional bias tensor of shape (\text{out_channels})(out_channels). Default: None
stride – the stride of the convolving kernel. Can be a single number or a tuple (sH, sW). Default: 1
padding –implicit paddings on both sides of the input. Can be a string {‘valid’, ‘same’}, single number or a tuple (padH, padW). Default: 0 padding=‘valid’ is the same as no padding. padding=‘same’ pads the input so the output has the shape as the input. However, this mode doesn’t support any stride values other than 1.

这里nn.Con2d要与nn.function.conv2d区分开:
参考:pytorch中nn.Conv2d和nn.function.conv2d的区别

  1. nn.Conv2d
    torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode=‘zeros’)
    in_channels-----输入通道数
    out_channels-------输出通道数
    kernel_size--------卷积核大小
    stride-------------步长
    padding---------是否对输入数据填充0
  2. nn.function.conv2d
    torch.nn.functional.conv2d(input,weight,bias=None,stride=1,padding=0,dilation=1,groups=1)
    input-------输入tensor大小(minibatch,in_channels,iH, iW)
    weight------权重大小(out_channels, in_channels/groups, kH, kW)
    注意:权重参数中,第一个卷积核的输出通道数,第二个是输入通道数

这里针对nn.function.conv2d讨论
例如:torch.nn.functional.conv2d(self, input, weight, bias=None, stride=1, padding=0, dilation=1, groups=2)
input:
minibatch:batch中的样例个数
in_channels:每个样例数据的通道数
iH:每个样例的高(行数)
iW:每个样例的宽(列数)

weight(就是filter):
out_channels:卷积核的个数
in_channels/groups:每个卷积核的通道数
kH:每个卷积核的高(行数)
kW:每个卷积核的宽(列数)
groups作用:对input中的每个样例数据,将通道分为groups等份,即每个样例数据被分成了groups个大小为(in_channel/groups, iH, iW)的子数据。对于这每个子数据来说,卷积核的大小为(in_channel/groups, kH, kW)。这一整个样例数据的计算结果为各个子数据的卷积结果拼接所得。

举例:

import torch.nn.functional as F
inputs = torch.arange(1, 21).reshape(1, 2, 2, 5)
filters = torch.arange(1, 7).reshape(2, 1, 1, 3)
print(inputs)
print(filters)
res = F.conv2d(input=inputs, weight=filters, stride=(1, 1), groups=2)
print(res)

输出如下:

tensor([[[[ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10]],[[11, 12, 13, 14, 15],[16, 17, 18, 19, 20]]]])tensor([[[[1, 2, 3]]],[[[4, 5, 6]]]])tensor([[[[ 14,  20,  26],[ 44,  50,  56]],[[182, 197, 212],[257, 272, 287]]]])

样例数据:

[ [ [ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10] ],[ [11, 12, 13, 14, 15],[16, 17, 18, 19, 20] ] ]

被分成:

[ [ [ 1,  2,  3,  4,  5],			 [ [ [11, 12, 13, 14, 15],[ 6,  7,  8,  9, 10] ] ] 	和		[16, 17, 18, 19, 20] ] ]

卷积核:

[ [ [ [ 1, 2, 3 ] ] ],[ [ [ 4, 5, 6 ] ] ] ]

被分成:

[ [ [1, 2, 3] ] ]	和	 [ [4, 5, 6] ] ]

结果中:

[ [ 14,  20,  26],[ 44,  50,  56] ]

[ [ [ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10] ] ]	和	 [ [ [ 1, 2, 3 ] ] ]	卷积所得。

3.train.py分析

作者使用了GOT-10k这个工具箱,train.py代码非常少
具体可以参考官方文档:Downloads - GOT-10k

4.transforms.py分析

顺着代码流看到调用了siamfc.py中类TrackerSiamFC的train_over方法,在这个类里面就是进行数据增强,构造和加载,然后进行训练,这里先讨论transforms:

SiamFCTransforms是transforms.py里面的一个类,主要是对输入的groung truth的z, x, bbox_z, bbox_x进行一系列变换,构成孪生网络的输入,这其中就包括了:
RandomStretch:主要是随机的resize图片的大小,其中要注意cv2.resize()的一点用法,可以参考这篇博客:cv2.resize()的一点小坑
CenterCrop:从img中间抠一块(size, size)大小的patch,如果不够大,以图片均值进行pad之后再crop
RandomCrop:用法类似CenterCrop,只不过从随机的位置抠,没有pad的考虑
Compose:就是把一系列的transforms串起来
ToTensor: 就是字面意思,把np.ndarray转化成torch tensor类型
代码分析:

  1. torch.from_numpy(img).float().permute((2, 0, 1))中permute(2,0,1)分析
    参考:Pytorch之permute函数
    permute(dims):将tensor的维度换位。
>>> x = torch.randn(2, 3, 5) 
>>> x.size() 
torch.Size([2, 3, 5]) 
>>> x.permute(2, 0, 1).size() 
torch.Size([5, 2, 3])
  1. if isinstance(size, numbers.Number):中isinstance分析
    参考Python isinstance() 函数
    isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
    isinstance() 与 type() 区别:
    type() 不会认为子类是一种父类类型,不考虑继承关系。
    isinstance() 会认为子类是一种父类类型,考虑继承关系。
    如果要判断两个类型是否相同推荐使用 isinstance()。
    在这里,isinstance是判断size是否为正常数。
  2. np.random.choice
    参考:理解python中的random.choice()
    random模块在python中起到的是生成随机数的作用,random模块中choice()可以从序列中获取一个随机元素,并返回一个(列表,元组或字符串中的)随机项。
  3. 图像处理: 五种插值法
    参考:图像处理: 五种 插值法
    在这里插入图片描述
    下面具体讲里面的_crop函数:
    因为GOT-10k里面对于目标的bbox是以ltwh(即left, top, weight, height)形式给出的,上述代码一开始就先把输入的box变成center based,坐标形式变为[y, x, h, w],结合下面这幅图就非常好理解:在这里插入图片描述
    在这里插入图片描述

5.ops.py分析(train相关部分)

crop_and_resize
在这里插入图片描述
在这里插入图片描述
代码分析:

 img = cv2.copyMakeBorder(img, npad, npad, npad,npad,border_type,value=border_value)

参考:OpenCV-Python: cv2.copyMakeBorder()函数详解
在这里插入图片描述

6.datasets.py

现在继续回到train_over方法,里面构造dataset的时候用了Pair类,所以从代码角度具体来看一下,因为继承了Dataset类,所以要overwrite __getitem__和__len__方法:
getitem:分析代码,这个方法就是通过index索引返回item = (z, x, box_z, box_x),然后经过transforms返回一对pair(z, x),就需要像论文里面说的:The images are extracted from two frames of a video that both contain the object and are at most T frames apart 。
_filter:通过该函数筛选符合条件的有效索引val_indices,这里不详细分析,因为我也不知道为什么会有这样的filter condition。
_sample_pair:如果有效索引大于2个的话,就从中随机挑选两个索引,这里取的间隔不超过T=100
len:这里定义的长度就是被索引到的视频序列帧数×每个序列提供的对数

7.siamfc.py分析(重点:train相关部分)

train_step
现在来到siamfc.py里面最后一个关键的地方,数据准备好了,经过变换和加载进来就可以训练了,下面代码是常规操作,具体在train_step里面实现了训练和反向传播:

而train_step里面难度又是在于理解_create_labels,具体的一些tensor的shape可以看我的注释,我好奇就把他打印出来了,看来本来__getitem__返回一对pair(z, x),经过dataloader的加载,还是z堆叠一起,x堆叠一起,并不是(z, x)绑定堆叠一起

而且criterion使用的BalancedLoss,是调用F.binary_cross_entropy_with_logits,进行一个element-wise的交叉熵计算,所以创建出来的labels的shape其实就是和responses的shape是一样的:

创建标签,论文里是这么说的:
在这里插入图片描述
因为我们的exemplar image z zz 和search image x xx都是以目标为中心的,所以labels的中心为1,中心以外为0。
对于np.tile、np.meshgrid、np.where函数的使用:
参考:np.tile、np.meshgrid、np.where学习总结
最后出来的一个batch下某一个通道下的label就是下面这样的:
在这里插入图片描述
还有train_over部分,就是保存模型,没什么说的。

tracking部分:

现在就来看一下类TrackerSiamFC下的track方法。这个函数的作用就是传入video sequence和first frame中的ground truth bbox,然后通过模型,得到后续帧的目标位置,可以看到主要有两个函数实现:init和update,这也是继承Tracker需要重写的两个方法:
在这里插入图片描述

siamfc.py(tracking部分)

init(self, img, box):
init:就是传入第一帧的标签和图片,初始化一些参数,计算一些之后搜索区域的中心等等
在这里插入图片描述
update:
update:就是传入后续帧,然后根据SiamFC网络返回目标的box坐标,之后就是根据这些坐标来show,起到一个demo的效果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
补充一些函数:
1.getatter()
参考:Python getatter() 通过方法名字符串调用方法
getattr()这个方法最主要的作用是实现反射机制。也就是说可以通过字符串获取方法实例。
获取函数/属性/从模块获取类
2.enumerate()
参考:python中enumerate()函数的用法
enumerate(sequence, start=0),返回一个枚举对象。sequence必须是序列或迭代器iterator,或者支持迭代的对象。enumerate()返回对象的每个元素都是一个元组,每个元组包括两个值,一个是计数,一个是sequence的值,计数是从start开始的,start默认为0。

论文翻译+解读

Abstract

在这里插入图片描述

1 Introduction

在这里插入图片描述

2 Deep Similarity Learning for Tracking

在这里插入图片描述
全卷积在我另一篇文章有一个简单的分析:FCN全卷积网络随笔

2.1 Fully-Convolutional Siamese Architecture

在这里插入图片描述
这里讲解一下:

The position of the maximum score relative to the centre of the score map, multiplied by the stride of the network, gives the displacemen of the target from frame to frame.

我们假设有三个帧,第二帧的中心截取是按照第一帧的目标位置来截取的,如果要进行第三帧的中心截取,那我们需要按照第二帧对于第一帧的相对位移,来获取第三帧的截取位置–也就是帧与帧之间的位移.网络步长是指缩小的倍数.再经过一系列的卷积层之后,图像缩小了一定的倍数,这个倍数就是网络步长.当我们得到第二帧的map中目标点位置时,要与网络步长相乘,就能知道第二帧目标相对第一帧的目标位移,第三帧就通过这个位移来进行中心截取.

2.2 Training with Large Search Images

在这里插入图片描述

2.3 ImageNet Video for Tracking

在这里插入图片描述

2.4 Practical Considerations

在这里插入图片描述
这里来讲解一下这个公式在这里插入图片描述
实际上,s是缩小的倍数,(h,w)是指长宽,而p是指边框厚度,其结果A就是面积
在这里插入图片描述

3 Related Work

在这里插入图片描述

4 Experiments

4.1 Implementation Details

在这里插入图片描述
双三插值的理解请看这个:插值(五)Bicubic interpolation(双三次插值)

4.2 Evaluation

在这里插入图片描述

4.3 The OTB-13 Benchmark

在这里插入图片描述

4.4 The VOT Benchmarks

在这里插入图片描述

4.5 Dataset Size

在这里插入图片描述

5 Conclusion

在这里插入图片描述


http://chatgpt.dhexx.cn/article/6ePOBdBH.shtml

相关文章

Siamese网络代码详解 训练自定义数据集 模型推理

开门见山,Siamese网络结构如下所示: 主干网络:VGG16。整个VGG16的网络结构比较简单,如下图所示,主要分为5个部分: stage1为 2次33卷积+1次22最大池化,输出特征为64通道;stage2为 2次33卷积+1次22最大池化,输出特征为128通道;stage1为 3次33卷积+1次22最大池化,输出…

深度学习(自监督:SimSiam)——Exploring Simple Siamese Representation Learning

文章目录 前言SimSiam简述实验 前言 该文章是何凯明组发表于CVPR2021上的文章,目前已获得最佳论文提名,主要解决自监督对比学习中的奔溃解问题。奔溃解即不论什么输入,特征提取器输出的特征向量都相同。 本文将简单介绍SimSiam,…

siamese模型码详解(每一句代码都有解释!!!)

最近在研究Siamese模型来进行文本相似度的计算,今天就做一期代码详解,每一行的代码都会做出相应的解释,对于初学LSTM的人来说读懂代码是非常有必要的,Siamese模型就是将两个句子(训练数据)通过embeding层&a…

孪生神经网络(Siamese Network)详解

1. 要解决什么问题? 主要解决以下两类分类问题: 第一类,分类数量较少,每一类的数据量较多,比如ImageNet、VOC等。这种分类问题可以使用神经网络或者SVM解决,只要事先知道了所有的类。第二类,分…

Siamese Network (原理篇)

1. Siamese Network 用途 Siamese网络是一种相似性度量方法,当类别数多,但每个类别的样本数量少的情况下可用于类别的识别、分类等。传统的用于区分的分类方法是需要确切的知道每个样本属于哪个类,需要针对每个样本有确切的标签。而且相对来说…

siamese(孪生) 网络

siamese 网络, 是05年Yann Lecun提出来的。它的特点是它接收两个图片作为输入,而不是一张图片作为输入。 文献资料: 摘抄自caffe github的issue697 Siamese nets are supervised models for metric learning [1]. 译:孪生网络…

Siamese Network(孪生网络)

模型结构 上图是孪生网络的简单模型结构,思路很简单,就是输入两个样本到同样的网络(参数结构相同),最后计算两个网络输出的距离,如果距离较近就认为是同一类,较远就认为是不同的类别&#xff0c…

51、目标的相似度检测模型Siamese部署rk3399pro、ncnn、mnn进行推理加速

基本思想:需要一个判断目标相似度的模型,来比对被检测目标和既定目标的相似度,测试图片仅有的几张图片,感觉一般,量化图片尽量多点对于rknn 链接: https://pan.baidu.com/s/1NFjnCBh5RqJXDxEjl9TzHg?pwdxev4 提取码:…

SPCL:Siamese Prototypical Contrastive Learning

论文链接:https://arxiv.org/abs/2208.08819 BMVC 2021 abstract CSL(Contrastive Self-supervised Learning)的一个缺点是,对比损失函数需要大量的负样本,以提供更好的理想互信息边界。 通过变大batch size来增加负样本数理,同…

Exploring Simple Siamese Representation Learning论文笔记

写在前面 大三狗随手记录,不喜勿喷。 主要思想 Siamese network常常被用来计算图像的两个增强之间的相似性,但可能会造成模型坍塌(即输出恒定)。作者在本文提出了一个非常简单的Simple Siamese network,简称Simsiam…

SiamCAR:Siamese Fully Convolutional Classification and Regression for Visual Tracking

文章目录 AbstractIntroductionProposed MethodFeature ExtractionBounding Box PredictionThe Tracking Phase 值得关注的几个问题Q1:输入的图片大小不一?Q2:在两者做相关性之前,如何得到特征图?Q3:两者的相关性计算是如何实现的&#xff1f…

TensorFlow搭建VGG-Siamese网络

TensorFlow搭建VGG-Siamese网络 Siamese原理 Siamese网络,中文称为孪生网络。大致结构如下图所示: Siamese网络有两个输入,一个输出。其中,两个输入经过相同的网络层知道成为一个n维向量,再对这个n维向量进行求距离&…

mesa 概述

技术关键词:mesa、OpenGL、dri、gpu、kmd、xsever 目录 一、mesa概述 二、mesa架构 1. 架构设计 2. 模块划分 三、mesa与linux图形系统中的其他模块的关系 四、mesa的编译 五、链接资源 总结 一、mesa概述 mesa是OpenGL、OpenGL ES、Vulkan、OpenCL的一个开…

Siamese 网络(Siamese network)

来源:Coursera吴恩达深度学习课程 上个文章One-Shot学习/一次学习(One-shot learning)中函数d的作用就是输入两张人脸图片,然后输出相似度。实现这个功能的一个方式就是用Siamese网络。 上图是常见的卷积网络,输入图片…

MISF:Multi-level Interactive Siamese Filtering for High-Fidelity Image Inpainting 论文解读与感想

深度学习模型被广泛应用于各种视觉任务的同时,似乎传统的图像处理方式已经被人们渐渐遗忘,然而很多时候传统图像处理方式的稳定性和可解释性依然是深度学习模型所不能达到的。本文是CVPR2022的一篇将传统与深度相结合进行inpainting的文章。 在图像inpa…

Siamese系列文章

说明 在学习目标追踪方面,慢慢读懂论文,记录论文的笔记,同时贴上一些别人写的非常优秀的帖子。 文章目录 说明综述类型笔记SiamFC笔记 SiamRPN笔记 DaSiamRPN笔记 SiamRPN笔记复现 SiamDW笔记 SiamFC笔记 UpdateNet笔记 SiamBAN笔记 SiamMa…

SiamRPN阅读笔记:High Performance Visual Tracking with Siamese Region Proposal Network

这是来自商汤的一篇文章 发表在CVPR2018上 论文地址 目录: 文章目录 摘要1.引言2.相关工作2.2 RPN2.3 One-shot learning 3.Siamese-RPN framework3.1 孪生特征提取子网络3.2 候选区域提取子网络3.3 训练阶段:端到端训练孪生RPN 4. Tracking as one-sho…

【度量学习】Siamese Network

基于2-channel network的图片相似度判别 一、相关理论 本篇博文主要讲解2015年CVPR的一篇关于图像相似度计算的文章:《Learning to Compare Image Patches via Convolutional Neural Networks》,本篇文章对经典的算法Siamese Networks 做了改进。学习这…

【论文阅读】Learning to Rank Proposals for Siamese Visual Tracking

Learning to Rank Proposals for Siamese Visual Tracking:2021 TIP 引入 There are two main challenges for visual tracking: 首先,待跟踪目标具有类不可知性和任意性,关于目标的先验信息很少。 其次,仅仅向跟踪器…

深度学习笔记-----多输入网络 (Siamese网络,Triplet网络)

目录 1,什么时候需要多个输入 2,常见的多输入网络 2.1 Siamese网络(孪生网络) 2.1 Triplet网络 1,什么时候需要多个输入 深度学习网络一般是输入都是一个,或者是一段视频切片,因为大部分的内容是对一张图像或者一段…