当前位置: 首页 > news >正文

公司网站建设苏州劳伦深圳购物网站建

公司网站建设苏州劳伦,深圳购物网站建,织梦网站最下面的网站建设去除,天津建设工程信息网投标信息系统什么是目标跟踪 使用视频序列第一帧的图像(包括bounding box的位置)#xff0c;来找出目标出现在后序帧位置的一种方法。 什么是孪生网络结构 孪生网络结构其思想是将一个训练样本(已知类别)和一个测试样本(未知类别)输入到两个CNN(这两个CNN往往是权值共享的)中#xff0…什么是目标跟踪 使用视频序列第一帧的图像(包括bounding box的位置)来找出目标出现在后序帧位置的一种方法。 什么是孪生网络结构 孪生网络结构其思想是将一个训练样本(已知类别)和一个测试样本(未知类别)输入到两个CNN(这两个CNN往往是权值共享的)中从而获得两个特征向量然后通过计算这两个特征向量的的相似度相似度越高表明其越可能是同一个类别。 给你一张我的正脸照没有经过美颜处理的)你该如何在人群中找到我呢一种最直观的方案就是:“谁长得最像就是谁”。但是对于计算机来说如何衡量“长得像”并不是个简单的问题。这就涉及一种基本的运算——互相关(cross-correlation)。互相关运算可以用来度量两个信号之间的相似性。互相关得到的响应图中每个像素的响应高低代表着每个位置相似度的高低。 在目标领域中最早利用这种思想的是SiamFC其网络结构如上图。图中的φ就是CNN编码器上下两个分支使用的CNN不仅结构相同参数也是完全共享的说白了就是同一个网络并不存在孪生兄弟那样的设定)。z和x分别是要跟踪的目标模版图像(尺寸为127x127和新的一帧中的搜索范围(尺寸为255x255)。二者经过同样的编码器后得到各自的特征图对二者进行互相关运算后则会同样得到一个响应图(尺寸为17x17)其每一个像素的值对应了x中与z等大的一个对应区域出现跟踪目标的概率。 互相关运算的步骤像极了我们手里拿着一张目标的照片模板图像然后把这个照片按在需要寻找目标的图片上搜索图像进行移动然后求重叠部分的相似度从而找到这个目标只不过为了计算机计算的方便使用AlexNet对图像数据进行了编码/特征提取。 下面这个版本中有一些动图还是会帮助理解的https://github.com/rafellerc/Pytorch-SiamFC SiamFC代码分析 我们对siamese的结构大致就讲完了还有一些内容结合代码来讲效果更好。 3.0 SiameseFC的结构 主要由以下几部分构成 特征提取网络AlexNet互相关运算网络 3.0.1 图像特征提取网络 class AlexNet(nn.Module):def __init__(self):super(AlexNet, self).__init__()self.conv1 nn.Sequential(nn.Conv2d(3, 96, 11, stride2, padding0),nn.BatchNorm2d(96),nn.ReLU(inplaceTrue),nn.MaxPool2d(kernel_size3, stride2, padding0))self.conv2 nn.Sequential(nn.Conv2d(96, 256, 5, stride1, padding0, groups2),nn.BatchNorm2d(256),nn.ReLU(inplaceTrue),nn.MaxPool2d(kernel_size3, stride2, padding0))self.conv3 nn.Sequential(nn.Conv2d(256, 384, 3, stride1, padding0),nn.BatchNorm2d(384),nn.ReLU(inplaceTrue))self.conv4 nn.Sequential(nn.Conv2d(384, 384, 3, stride1, padding0, groups2),nn.BatchNorm2d(384),nn.ReLU(inplaceTrue))self.conv5 nn.Sequential(nn.Conv2d(384, 256, 3, stride1, padding0, groups2))def forward(self, x):conv1 self.conv1(x)conv2 self.conv2(conv1)conv3 self.conv3(conv2)conv4 self.conv4(conv3)conv5 self.conv5(conv4)return conv53.0.2 互相关运算网络 class _corr(nn.Module):def __init__(self):super(_corr, self).__init__()#互相关运算设batch_size8def forward(self, z, x):kernel z #[8,128,6,6]group z.size(0) #8input x.view(-1, group*x.size(1), x.size(2), x.size(3))#输出为[8,1,17,17], 那么反推input[8,128,22,22]kernel[1,1024,6,6] group128/1024错误#所以先输出[1,8,17,17],再view变换维度成[8,1,17,17],那么input[1,1024,22,22],kernel[8,128,6,6],group1024/1288batch_sizeresponse_maps F.conv2d(input, kernel,groupsgroup)response_maps response_maps.view(x.size(0),-1,response_maps.size(2), response_maps.size(3))return response_maps至此完成了对网络框架architecture的代码分析!!! 3.1 training 3.1.1图像预处理 小超up给出训练的框图如下。训练过程中首先要获取训练数据集的所有视频序列(每个视频序列的所有帧)我采用的是GOT-10k数据集训练获取数据集之后进行图像预处理对每一个视频序列抽取两帧图像并作数据增强处理(包括裁剪、resize等过程)分别作为目标模板图像和搜索图像把经过图像处理的所有图像对加载并以batch_size输入网络得到预测输出建立标签和损失函数损失函数的输入是预测输出目标是标签设置优化策略梯度下降损失最终得到网络模型。 先贴代码再分析 def train(data_dir, net_pathNone,save_dirpretrained):#从文件中读取图像数据集seq_dataset GOT10k(data_dir,subsettrain,return_metaFalse)#定义图像预处理方法transforms SiamFCTransforms( exemplar_szcfg.exemplar_sz, #127instance_szcfg.instance_sz, #255contextcfg.context) #0.5#从读取的数据集每个视频序列配对训练图像并进行预处理裁剪等train_dataset GOT10kDataset(seq_dataset,transforms)data_dir是存放GOT-10k数据集的文件路径GOT-10k一共有9335个训练视频序列seq_dataset返回的是所有视频序列的图片路径列表seq_dirs及对应groundtruth列表anno_files及一些其他信息如下 接下来是定义好图像预处理方法在GOT10kDataset方法中对每个视频序列配对两帧图像并使用定义好的图像处理方法接下来直接进入该方法分析代码GOT10kDataset的代码如下 class GOT10kDataset(Dataset): #继承了torch.utils.data的Dataset类def __init__(self, seqs, transformsNone,pairs_per_seq1):def __getitem__(self, index): #通过_sample_pair方法得到索引返回item(z,x,box_z,box_x),然后经过transforms处理def __len__(self): #返回9335*pairs_per_seq对def _sample_pair(self, indices): #随机挑选两个索引这里取的间隔不超过T100def _filter(self, img0, anno, vis_ratiosNone): #通过该函数筛选符合条件的有效索引val_indices这里最重要的方法就是__getitem__该方法最终返回处理后的图像在内部首先调用了_sample_pair方法用于提取两帧有效图片(有效的定义是图片目标的面积和高宽等有约束条件)的索引 因为这里我对网络在训练和测试时需要的数据集有一些疑问通过源码以及网上博文做以下总结 答在训练过程中一对图片即模板图和搜索图共同构成一个数据样本而不是单独的每一帧。这意味着在Siamese网络的训练中数据集是由多个这样的图像对组成的每个图像对代表一个单独的训练样本。 在测试阶段算法逐帧处理视频序列每次只处理一个搜索图和对应的模板图。 def track(self, img_files, box, visualizeFalse):frame_num len(img_files)boxes np.zeros((frame_num, 4))boxes[0] boxtimes np.zeros(frame_num)for f, img_file in enumerate(img_files):img ops.read_image(img_file)begin time.time()if f 0:self.init(img, box)else:boxes[f, :] self.update(img)times[f] time.time() - begin可见在测试阶段在视频序列的第一帧选择目标区域作为模板图。这个模板图将用于整个视频序列的跟踪过程。 在得到这两帧图片和对应groundtruth之后通过定义好的transforms进行处理transforms是SiamFCTransforms类的实例化对象该类中主要继承了resize图片大小和各种裁剪方式等如代码所示 class SiamFCTransforms(object):def __init__(self, exemplar_sz127, instance_sz255, context0.5):self.exemplar_sz exemplar_szself.instance_sz instance_szself.context context#transforms_z/x是数据增强方法self.transforms_z Compose([RandomStretch(), #随机resize图片大小,变化再[1 1.05]之内CenterCrop(instance_sz - 8), #中心裁剪 裁剪为255-8RandomCrop(instance_sz - 2 * 8), #随机裁剪 255-8-255-8-8CenterCrop(exemplar_sz), #中心裁剪 255-8-8-127ToTensor()]) #图片的数据格式从numpy转换成torch张量形式self.transforms_x Compose([RandomStretch(), #s随机resize图片CenterCrop(instance_sz - 8), #中心裁剪 裁剪为255-8RandomCrop(instance_sz - 2 * 8), #随机裁剪 255-8-255-8-8ToTensor()]) #图片数据格式转化为torch张量def __call__(self, z, x, box_z, box_x): #zx表示传进来的图像z self._crop(z, box_z, self.instance_sz) #对z(x类似)图像 1、box转换(l,t,w,h)-(y,x,h,w)并且数据格式转为float32,得到center[y,x],和target_sz[h,w]x self._crop(x, box_x, self.instance_sz) #2、得到size((h(hw)/2)*(w(h2)/2))^0.5*255(instance_sz)/127z self.transforms_z(z) #3、进入crop_and_resize:传入z作为图片imgcentersizeoutsize255(instance_sz),随机选方式填充均值填充x self.transforms_x(x) # 以center为中心裁剪一块边长为size大小的正方形框(注意裁剪时的padd边框填充问题)再resize成out_size255(instance_sz)return z, x实例化对象后直接从__call__开始运行代码首先关注的应该是_crop函数该函数将原始的两帧图片分别以目标为中心裁剪一块包含上下文信息的patchpatch的边长定义如下 式中w、h分别表示目标的宽和高。下面具体讲里面的_crop函数 def _crop(self, img, box, out_size):# convert box to 0-indexed and center based [y, x, h, w]box np.array([box[1] - 1 (box[3] - 1) / 2,box[0] - 1 (box[2] - 1) / 2,box[3], box[2]], dtypenp.float32)center, target_sz box[:2], box[2:]context self.context * np.sum(target_sz)size np.sqrt(np.prod(target_sz context))size * out_size / self.exemplar_szavg_color np.mean(img, axis(0, 1), dtypefloat)interp np.random.choice([cv2.INTER_LINEAR,cv2.INTER_CUBIC,cv2.INTER_AREA,cv2.INTER_NEAREST,cv2.INTER_LANCZOS4])patch ops.crop_and_resize(img, center, size, out_size,border_valueavg_color, interpinterp)return patch因为GOT-10k里面对于目标的bbox是以ltwh(即left, top, weight, height)形式给出的上述代码一开始就先把输入的box变成center based坐标形式变为[y, x, h, w]结合下面这幅图就非常好理解 crop_and_resize def crop_and_resize(img, center, size, out_size,border_typecv2.BORDER_CONSTANT,border_value(0, 0, 0),interpcv2.INTER_LINEAR):# convert box to corners (0-indexed)size round(size) # the size of square cropcorners np.concatenate((np.round(center - (size - 1) / 2),np.round(center - (size - 1) / 2) size))corners np.round(corners).astype(int)# pad image if necessarypads np.concatenate((-corners[:2], corners[2:] - img.shape[:2]))npad max(0, int(pads.max()))if npad 0:img cv2.copyMakeBorder(img, npad, npad, npad, npad,border_type, valueborder_value)# crop image patchcorners (corners npad).astype(int)patch img[corners[0]:corners[2], corners[1]:corners[3]]# resize to out_sizepatch cv2.resize(patch, (out_size, out_size),interpolationinterp)return patch在裁剪过程中会出现越界的情况需要对原始图像边缘填充填充值固定为图像的RGB均值填充大小根据图像边缘越界最大值作为填充值具体实现过程由以下代码完成。 # padding操作#corners表示目标的[ymin,xmin,ymax,xmax]pads np.concatenate((-corners[:2], corners[2:] - img.shape[:2]))npad max(0, int(pads.max())) #得到上下左右4个越界值中最大的与0对比0代表无越界if npad 0:img cv2.copyMakeBorder(img, npad, npad, npad, npad,cv2.BORDER_CONSTANT, valueimg_average)实验结果 3.1.2加载训练数据、标签及损失函数 图像预处理完成后得到了用与训练的9335对图像将图像加载批量加载输入网络得到输出结果作为损失函数的input损失函数的target是制定好的labels。 #加载训练数据集loader_dataset DataLoader( dataset train_dataset,batch_sizecfg.batch_size,shuffleTrue,num_workerscfg.num_workers,pin_memoryTrue,drop_lastTrue, )#初始化训练网络cuda torch.cuda.is_available() #支持GPU为Truedevice torch.device(cuda:0 if cuda else cpu) #cuda设备号为0model AlexNet(init_weightTrue)corr _corr()model model.to(device)corr corr.to(device)# 设置损失函数和标签logist_loss BalancedLoss()labels _create_labels(size[cfg.batch_size, 1, cfg.response_sz - 2, cfg.response_sz - 2])labels torch.from_numpy(labels).to(device).float()本小节主要讲网络输出的labels和损失函数接下来只是小超up个人的一些理解代码与论文理论部分形式不一致但效果一样。先上图论文中labels以及损失函数如下图 然而代码中的labels值却是1和0损失函数使用的是二值交叉熵损失函数F.binary_cross_entropy_with_logits如下图推导所示解释了为什么代码实现部分真正使用的labels值是1和0而理论部分使用的是1和-1。 利用下面代码的这个_creat_labels方法可以得到标签。 def _create_labels(size):def logistic_labels(x, y, r_pos):# x^2y^24 的位置设为为1其他为0dist np.sqrt(x ** 2 y ** 2)labels np.where(dist r_pos, #r_os2np.ones_like(x), #np.ones_like(x),用1填充xnp.zeros_like(x)) #np.zeros_like(x),用0填充xreturn labels#获取标签的参数n, c, h, w size # [8,1,15,15]x np.arange(w) - (w - 1) / 2 #x[-7 -6 ....0....6 7]y np.arange(h) - (h - 1) / 2 #y[-7 -6 ....0....6 7]x, y np.meshgrid(x, y) #建立标签r_pos cfg.r_pos / cfg.total_stride # 16/8labels logistic_labels(x, y, r_pos)#重复batch_size个label因为网络输出是batch_size张response maplabels labels.reshape((1, 1, h, w)) #[1,1,15,15]labels np.tile(labels, (n, c, 1, 1)) #将labels扩展[8,1,15,15]return labels验证结果如下图只截取了部分labels得到的labels对应输入大小都是[8,1,15,15] if __name__ __main__:labels _create_labels([8,1,15,15]) #返回的label.shape(8,1,15,15)其中关于np.tile、np.meshgrid、np.where函数的使用可以去看这篇博客最后出来的一个batch下某一个通道下的label就是下面这样的 3.1.3 优化策略 这里主要说一下学习率lr随着训练次数epoch增多而减小具体值如下公式式中initial为初始学习率gamma是定义的超参epoch为训练次数。整个优化器及学习率调整实现代码如下 #建立优化器设置指数变化的学习率optimizer optim.SGD(model.parameters(),lrcfg.initial_lr, #初始化的学习率后续会不断更新weight_decaycfg.weight_decay, #λ5e-4正则化momentumcfg.momentum) #v(now)dx∗lrv(last)∗momemtumgamma np.power( #np.power(a,b) 返回a^bcfg.ultimate_lr / cfg.initial_lr,1.0 / cfg.epoch_num)lr_scheduler ExponentialLR(optimizer, gamma) #指数形式衰减lrinitial_lr*(gamma^epoch)3.1.4 模型的训练与保存 一切准备工作就绪后就开始训练了。代码中设定epoch_num为50次训练时密切加上model.train()告诉网络处于训练状态这样网络运行时就会利用pytorch的自动求导机制求导在测试时改为model.eval()关闭自动求导。模型训练的步骤如代码所示 # loop over epochs for epoch in range(self.cfg.epoch_num):# update lr at each epochself.lr_scheduler.step(epochepoch)# loop over dataloaderfor it, batch in enumerate(dataloader):loss self.train_step(batch, backwardTrue)print(Epoch: {} [{}/{}] Loss: {:.5f}.format(epoch 1, it 1, len(dataloader), loss))sys.stdout.flush()# save checkpointif not os.path.exists(save_dir):os.makedirs(save_dir)net_path os.path.join(save_dir, siamfc_alexnet_e%d.pth % (epoch 1))torch.save(self.net.state_dict(), net_path)至此此份repo的训练应该差不多结束了 3.2 testing 3.2.1 init(初始帧) 这一步目的是要得到6x6x128的目标模板feature map在后续跟踪过程中一直使用它作为卷积核不变这也是一大SiamFC的缺点所在init内还要初始化目标的中心所在位置、宽高、汉宁窗等后续跟踪使用。 #传入第一帧的gt和图片初始化一些参数计算一些之后搜索区域的中心等等def init(self, img, box):#设置成评估模式测试模型时一开始要加这个属于Pytorch训练模型前要加self.net.train()self.model.eval()#将原始的目标位置表示[l,t,w,h]-[center_y,center_x,h,w]yxhw ltwh_to_yxhw(ltwhbox)self.center, self.target_sz yxhw[:2], yxhw[2:]#创建汉宁窗口update使用self.response_upsz cfg.response_up * cfg.response_sz # 16*17272self.hann_window creat_hanning_window(sizeself.response_upsz)#三种尺度1.0375**(-1,0,1) 三种尺度self.scale_factors three_scales()# patch边长,两种边长目标模板图像z_sz和搜索图像x_zscontext cfg.context * np.sum(self.target_sz) # 上下文信息(hw)/2self.z_sz np.sqrt(np.prod(self.target_sz context)) # (h(hw)/2)*(w(h2)/2))^0.5self.x_sz self.z_sz * cfg.instance_sz / cfg.exemplar_sz # (h(hw)/2)*(w(h2)/2))^0.5*255/127#图像的RGB均值返回(aveR,aveG,aveB)self.avg_color np.mean(img, axis(0, 1))#裁剪一块以目标为中心边长为z_sz大小的patch,然后将其resize成exemplar_sz的大小z z_to127(img, self.center, self.z_sz, cfg.exemplar_sz, self.avg_color)z torch.from_numpy(z).to( #torch.size([1,3,127,127])self.device).permute(2, 0, 1).unsqueeze(0).float()self.kernel self.model(z) #torch.size([1,128,6,6])follow代码先设置model.eval()原因在training过程中讲了初始化目标的位置信息self.center和self.target_sz分别代表目标的中心位置和高宽接着是汉宁窗口和尺度因子汉宁窗口如下图展示的是17x17大小的它与response map相乘会突出response map的中心并抑制边缘。窗口大小是17*16272而不是response map的大小17这样做的好处是找到更加精确的位置相比于在17x17大小的特征图上寻找最大值272x272大小的特征图分辨率更高位置更精确所以在后续跟踪过程中得到的17x17大小的response map会resize成272x272大小代码使用的是SiamFC_3s所以定义了三个不同的尺度包含上下文信息的patch边长与training不同训练时是将两张图片以相同的patch裁剪再resize成255x255x3大小之后在一系列数据增强的过程中将其中一张图片裁剪成127x127x3作为目标模板图像。而test过程中目标模板图像和搜索图像的patch边长不同如代码所示成比例255/127关系最后就是对init传入的初始帧图片裁剪并输入网络得到跟踪过程使用的卷积核大小为[1,128,6,6]。 3.2.2 update(后续帧) Update就是tracking过程传入的参数是后续帧图片一共可以分为三个阶段1、经过网络的正向推导得到response map2、根据response map的最大值反推目标在原始图片中的位置3、参数更新。 #传入后续帧然后根据SiamFC跟踪流程返回目标的box坐标def update(self, img):self.model.eval()----------------正向推导得到response map最大值位置---------------------#三种patch边长 patch*3scalesx x_to3s255(img,self.center,self.x_sz,self.scale_factors,cfg.instance_sz,self.avg_color)#numpy转为float的torch型张量x torch.from_numpy(x).to(self.device).permute(0, 3, 1, 2).float()#[3,255,22,22]x self.model(x)#得到三种尺度下的response mapresponses self.corr(self.kernel, x) * cfg.out_reduce #[311717]responses responses.squeeze(1).cpu().numpy() #压缩为[31717]并转为numpy作后续计算处理#将17x17大小的response map-[3,272,272]responses map_to272(responses,out_sizeself.response_upsz)#对尺度变化做出相应惩罚responses[:cfg.scale_num // 2] * cfg.scale_penalty #response[0]*0.9745惩罚项responses[cfg.scale_num // 2 1:] * cfg.scale_penalty #response[2]*0.9745惩罚项#找到最大值属于哪个response map并把该response map赋给responsescale_id np.argmax(np.amax(responses, axis(1, 2))) #里面求得三个map的最大值 再对三个值求最大值 得到索引response responses[scale_id] #[272272]#一系列数据处理重点在汉宁窗惩罚response map_process(response,self.hann_window)loc np.unravel_index(response.argmax(),response.shape) #unravel_index该函数可返回索引response.argmax()的元素的坐标逐行拉伸返回第几行第几个---------------由response map最大值位置反推目标在原图像的位置------------disp_in_response np.array(loc) - (self.response_upsz - 1) / 2 #峰值点相对于response中心的位移disp disp_in_response / 16disp disp * 8disp disp * self.x_sz * self.scale_factors[scale_id] / cfg.instance_szself.center disp---------------参数更新------------参考文档 siameseFC论文和代码解析 SiamFC 学习论文、总结与分析 siamfc-pytorch代码讲解一backbonehead siamfc-pytorch代码讲解二trainsiamfc SiamFC代码分析(architecture、training、test) siamfc前世今生 Siamese跟踪发展历程 视频推荐 目标跟踪零基础代码入门一SiamFC_哔哩哔哩_bilibili
http://www.w-s-a.com/news/410266/

相关文章:

  • 德州有名的网站建设公司网站如何做引流
  • 建设一个收入支出持平的网站网络推广计划书格式
  • 什么是网站黑链全球新冠疫苗接种率
  • 网站开发 chrome gimp网站不备案做seo没用
  • 织梦校园招生网站源码沪佳哪个好
  • 建设企业网站可信度软件产品如何做网站推广
  • 网站建设企业号助手贵阳景观设计公司
  • 网站开发第三方建设银行个人网站显示不了
  • 无锡兼职做网站郑州网站建设搜索优化
  • iis禁止通过ip访问网站品牌策划案例ppt
  • 电子商务网站建设实习seo黑帽优化
  • 如何做好网站建设销售闸北集团网站建设
  • 重庆装饰公司北京官网seo推广
  • 深圳网站设计灵点网络品牌网站充值接口
  • 建设书局 网站国内国际时事图片
  • 成都 网站建设培训学校屏蔽wordpress自带编辑器
  • 公司网站制作工作室中天建设集团有限公司第五建设公司
  • 网站的网页设计毕业设计苏州宣传册设计广告公司
  • 商城网站优化方案注册公司制作网站
  • 政务服务网站建设整改报告wordpress的导航代码
  • 图片素材网站建设做教育网站用什么颜色
  • 快站淘客中转页wordpress商业插件
  • 可信网站网站认证免费软件下载网站免费软件下载网站
  • 小学生网站制作最新域名网站
  • 奖励网站代码设计制作ppt时
  • 茂名优化网站建设门户网站和部门网站的区别
  • 一尊网 又一个wordpress站点wordpress获取当前文章名称
  • 营销型网站多少钱新建网站的外链多久生效
  • 网站空间怎么选择tp5企业网站开发百度云
  • 网站建设saas排名成立公司的流程和要求及费用