siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head最近才真正开始研究目标跟踪领域(好吧,是真的慢)。就先看了一篇论文:Fully-ConvolutionalSiameseNetworksforObjectTracking【ECCV2016workshop】又因为学的是PyTorch框架,所以找了一份比较clean的代码,还是pytorch1.0的:https://github.com/huanglianghua/siamfc-pyto…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

最近才真正开始研究目标跟踪领域(好吧,是真的慢)。就先看了一篇论文:

Fully-Convolutional Siamese Networks for Object Tracking【ECCV2016 workshop】

又因为学的是PyTorch框架,所以找了一份比较clean的代码,还是pytorch1.0的:

https://github.com/huanglianghua/siamfc-pytorch

因为这个作者也是GOT-10k toolkit的主要贡献者,所以用上这个工具箱之后显得training和test会clean一些,要能跑训练和测试代码,还得去下载GOT-10k数据集,训练数据分成了19份,如果只是为了跑一下下一份就行。

论文概述

SiamFC这篇论文算是将深度神经网络较早运用于tracking的,比它还早一点的就是SINT了,主要是运用了相似度学习的思想,采用孪生网络,把127×127的exemplar image

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head 和255×255的search image

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head 输入同一个backbone(论文中就是AlexNet)也叫Embedding Network,生成各自的Embedding,然后这两个Embedding经过互相关计算的得到score map,其上大的位置就代表对应位置上的Embedding相似度大,反之亦然。整个训练流程可以用下图表示:

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head

SiamFC训练流程

个人感觉,训练就是为了优化Embedding Network,在见到的序列中生成一个更好embedding,从而使生成的score map和生成的ground truth有更小的logistic loss。更多细节在之后的几篇会和代码一起分析。

backbones.py分析

from __future__ import absolute_import

import torch.nn as nn

__all__ = [‘AlexNetV1’, ‘AlexNetV2’, ‘AlexNetV3’]

class _BatchNorm2d(nn.BatchNorm2d):

def __init__(self, num_features, *args, **kwargs):

super(_BatchNorm2d, self).__init__(

num_features, *args, eps=1e-6, momentum=0.05, **kwargs)

class _AlexNet(nn.Module):

def forward(self, x):

x = self.conv1(x)

x = self.conv2(x)

x = self.conv3(x)

x = self.conv4(x)

x = self.conv5(x)

return x

class AlexNetV1(_AlexNet):

output_stride = 8

def __init__(self):

super(AlexNetV1, self).__init__()

self.conv1 = nn.Sequential(

nn.Conv2d(3, 96, 11, 2),

_BatchNorm2d(96),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 2))

self.conv2 = nn.Sequential(

nn.Conv2d(96, 256, 5, 1, groups=2),

_BatchNorm2d(256),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 2))

self.conv3 = nn.Sequential(

nn.Conv2d(256, 384, 3, 1),

_BatchNorm2d(384),

nn.ReLU(inplace=True))

self.conv4 = nn.Sequential(

nn.Conv2d(384, 384, 3, 1, groups=2),

_BatchNorm2d(384),

nn.ReLU(inplace=True))

self.conv5 = nn.Sequential(

nn.Conv2d(384, 256, 3, 1, groups=2))

class AlexNetV2(_AlexNet):

output_stride = 4

def __init__(self):

super(AlexNetV2, self).__init__()

self.conv1 = nn.Sequential(

nn.Conv2d(3, 96, 11, 2),

_BatchNorm2d(96),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 2))

self.conv2 = nn.Sequential(

nn.Conv2d(96, 256, 5, 1, groups=2),

_BatchNorm2d(256),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 1))

self.conv3 = nn.Sequential(

nn.Conv2d(256, 384, 3, 1),

_BatchNorm2d(384),

nn.ReLU(inplace=True))

self.conv4 = nn.Sequential(

nn.Conv2d(384, 384, 3, 1, groups=2),

_BatchNorm2d(384),

nn.ReLU(inplace=True))

self.conv5 = nn.Sequential(

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

class AlexNetV3(_AlexNet):

output_stride = 8

def __init__(self):

super(AlexNetV3, self).__init__()

self.conv1 = nn.Sequential(

nn.Conv2d(3, 192, 11, 2),

_BatchNorm2d(192),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 2))

self.conv2 = nn.Sequential(

nn.Conv2d(192, 512, 5, 1),

_BatchNorm2d(512),

nn.ReLU(inplace=True),

nn.MaxPool2d(3, 2))

self.conv3 = nn.Sequential(

nn.Conv2d(512, 768, 3, 1),

_BatchNorm2d(768),

nn.ReLU(inplace=True))

self.conv4 = nn.Sequential(

nn.Conv2d(768, 768, 3, 1),

_BatchNorm2d(768),

nn.ReLU(inplace=True))

self.conv5 = nn.Sequential(

nn.Conv2d(768, 512, 3, 1),

_BatchNorm2d(512))

这个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:

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head

论文中backbone结构

注意:有些人会感觉这里输入输出通道对不上,这是因为像原本AlexNet分成了2个group,所以会有48->96, 192->384这样。

也可以在此py文件下面再加一段代码,测试一下打印出的tensor的shape:

if __name__ == ‘__main__’:

alexnetv1 = AlexNetV1()

import torch

z = torch.randn(1, 3, 127, 127)

output = alexnetv1(z)

print(output.shape) # torch.Size([1, 256, 6, 6])

x = torch.randn(1, 3, 256, 256)

output = alexnetv1(x)

print(output.shape) # torch.Size([1, 256, 22, 22])

# 换成AlexNetV2依次是:

# torch.Size([1, 32, 17, 17])、torch.Size([1, 32, 49, 49])

# 换成AlexNetV3依次是:

# torch.Size([1, 512, 6, 6])、torch.Size([1, 512, 22, 22])

heads.py

先放代码为敬:

class SiamFC(nn.Module):

def __init__(self, out_scale=0.001):

super(SiamFC, self).__init__()

self.out_scale = out_scale

def forward(self, z, x):

return self._fast_xcorr(z, x) * self.out_scale

def _fast_xcorr(self, z, x):

# fast cross correlation

nz = z.size(0)

nx, c, h, w = x.size()

x = x.view(-1, nz * c, h, w)

out = F.conv2d(x, z, groups=nz) # shape:[nx/nz, nz, H, W]

out = out.view(nx, -1, out.size(-2), out.size(-1)) #[nx, 1, H, W]

return out

为什么这里会有个out_scale,根据作者说是因为,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head互相关之后的值太大,经过sigmoid函数之后会使值处于梯度饱和的那块,梯度太小,乘以out_scale就是为了避免这个。

_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 (

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head ,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head)

weight – filters of shape (

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head,

siamfc代码解读_siamfc-pytorch代码讲解(一):backbone&head)

所以根据上面条件,可以得到:x shape:[nx/nz, nz*c, h, w] 和 z shape:[nz, c, hz, wz],最后out shape:[nx, 1, H, W]

其实最后真实喂入此函数的z embedding shape:[8, 256, 6, 6], x embedding shape:[8, 256, 20, 20], output shape:[8, 1, 15, 15]【这个之后再回过来看也行】

同样的,也可以用下面一段代码测试一下:

if __name__ == ‘__main__’:

import torch

z = torch.randn(8, 256, 6, 6)

x = torch.randn(8, 256, 20, 20)

siamfc = SiamFC()

output = siamfc(z, x)

print(output.shape) # torch.Size([8, 1, 15, 15])

好了,这部分先讲到这里,这一块还是算简单的,一般看一下应该就能理解,之后的代码会更具挑战性,嘻嘻,放一个辅助链接,下面这个版本中有一些动图,还是会帮助理解的:

还有下面是GOT-10k的toolkit,可以先看一下,但是训练部分代码还不是涉及很多:

下一篇

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187213.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 深入浅出 超详细 从 线程锁 到 redis 实现分布式锁(篇节 2)「建议收藏」

    深入浅出 超详细 从 线程锁 到 redis 实现分布式锁(篇节 2)「建议收藏」redis实现分布式锁上节我们讲了线程锁在单体项目中的作用,和放在分布式项目里产生的问题,那接下来我们就来解决分布式架构上怎么保证数据的一直性使用redisTemplate实现//设置锁setIfAbsent(“lock”,”1213″)—>SETNXlock”1213″//释放锁redisTemplate.delete(“lock”);@GetMapping(“/cut”)publicObjectkc(){

    2022年6月21日
    21
  • 通俗讲解 同步、异步、阻塞、非阻塞 编程

    通俗讲解 同步、异步、阻塞、非阻塞 编程#真正意义上的异步IO是说内核直接将数据拷贝至用户态的内存单元,再通知程序直接去读取数据。#select/poll/epoll都是同步IO的多路复用模式1.同步和异步#同步和异步关注的是消息通信机制#所谓同步,就是在发出一个*调用*时,没得到结果之前,该*调用*就不返回。但是一旦调用返回就得到返回值了,*调用者*主动等待这个*调用*的结果#所谓异步,就是在发出一个*调用*时,这个*调用*就直接返回了,不管返回有没有结果。当一个异步过程调用发出后,*被调用者*.

    2022年6月1日
    32
  • MATLAB画图——基础篇「建议收藏」

    MATLAB画图——基础篇「建议收藏」MATLAB画图——基础篇在MATLAB使用的过程中,学会画图是一项必要的技能。在这里,我总结了部分简单的画图函数,同时附上代码(本文中的程序为了方便给出的数据都很简单,大家可以自己去尝试其他数据)。这对刚刚开始接触MATLAB的小白来说,我认为还是很有帮助的。文章目录一、plot()函数1.二维图形(1)绘图选项(2)图形的辅助标注和窗口的分割(3)格式2.三维图形(1)格式(2)网格矩阵生成函数:meshgrid(3)mesh函数(4)surf函数二、特殊图形1.对数坐标图2.极坐标图3.条形图一

    2022年9月20日
    1
  • MySQL:MySQL 存储过程

    MySQL:MySQL 存储过程MySQL存储过程(了解)1什么是存储过程MySQL5.0版本开始支持存储过程存储过程(StoredProcedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象

    2022年7月3日
    21
  • 阿里云上实现DDNS公网解析「建议收藏」

    阿里云上实现DDNS公网解析「建议收藏」目录阿里云官网购买域名服务器pip安装阿里云python-ddns库获取AccessKey复制DDNS代码创建定时任务验证DDNS是否成功阿里云官网购买域名注册阿里云账号,登录,进入控制台,点击域名进行购买,购买时会提示你登记身份信息。我的5年129元,不贵吧。不要买.com,.cn等等重要域名,因为非常贵。服务器pip安装阿里云python-ddns库因为有的人机器上同时有python2和python3,如果用pip安装就不起作用,所以以下六条命令都要执行一下,以防万一。pipins

    2022年5月29日
    457
  • 大数据流量分析[通俗易懂]

    大数据流量分析[通俗易懂]数据分析工具:FineBI商业智能工具http://www.finebi.com/数据分析的本质其实是做数据对比分析,没有数据对比,单一的指标统计往往难以发挥数据价值。像我们常见的数据对比分析方法有同比、环比、占比等一系列分析指标,那是不是所有的数据业务场景都可以直接进行套用分析呢?比如我们统计企业2018年1月29日的同比流量,是不是可以直接对比2017年1月29日?表面上看好像2017年1…

    2022年4月28日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号