YOLOV++ 详解 | 网络结构、代码解析、YOLOV 论文阅读、初识 VID

前言

  代码地址:https://github.com/YuHengsss/YOLOV

  本文网络结构按 YOLOV++ SwinTiny 绘制,不同的模型主要差异在于 Backbone,VID 相关的部分基本相同。

Predict

Input

  代码基于 vid_demo。首先会读取视频中的所有帧(只能用短视频或者修改代码限制帧数,不然爆内存),然后把帧的顺序随机打乱,按照 gframe=32 划分若干组,每一组作为一个 batch。

Backbone

在这里插入图片描述
  整体结构与 YOLO 系列差不多,特征提取网络使用了 SwinTransformer,由于以 Transformer 为基础,而且计算方式比较复杂,本文略过其中细节。C3 模块的计算方式如下:
在这里插入图片描述

Head

1. 传统检测

在这里插入图片描述

  对于三个不同尺度的特征都会先通过一个 1 × 1 1\times 1 1×1 卷积将特征维度统一到256,然后连接多个分支(图中为3个)。
  其中两个是传统检测分支,回归分支 reg 负责检测框和是否存在目标,分类分支 cls 负责分类概率;
  另有两个分支用于获取后续 VID 环节所需的分类和回归特征(代码中可选择性启用),这里仅启用分类特征的分支得到 vid_cls_feat,而回归特征则直接使用回归分支的中间特征,即 vid_reg_feat = reg_feat

  对于传统分支所得到的检测输出 Output 会经过 DecodePostProcess 得到检测结果。
(1)Decode:将 box 的前两项 xy 加上 Anchor 坐标作为目标框中心坐标,box 的后两项 wh 通过 exp() 作为目标框的长宽。
(2)PostProcess:首先变换 box 格式 xywh -> xyxy,对于每个 batch,提取每个 Anchor 分类得分最高的类别 35 ( x y x y + o b j + 30 ) → 37 ( x y x y + o b j + c o n f + c l s + 30 ) 35(xyxy+\mathrm{obj}+30) \to 37(xyxy+\mathrm{obj}+\mathrm{conf} +\mathrm{cls}+30) 35(xyxy+obj+30)37(xyxy+obj+conf+cls+30)。对 obj * conf 做阈值筛选,并且此处设定了最少目标数量 minimal_limit=50,目标数量不足时按 obj * conf 排序取 Top50,最终得到图中 [32,n,37] 的检测结果。此处每个 batch 的 n 即检测数量并不相同,另外这里可以选择启用 NMS。

2. VID

  根据前面得到的检测结果,以及分类特征 vid_cls_feat 和 回归特征 vid_reg_feat,提取出检测结果对应 Anchor 位置的特征 feat_clsfeat_reg。由于两种特征的处理方式基本相同,以分类特征为例进行说明。
在这里插入图片描述
注:
(1) N = ∑ n N=\sum{n} N=n 为当前 batch 总的检测数量。
(2)分类和回归的计算有一处不同,回归在 scale 处不会乘上 reg_scorereg_score 为是否存在目标的得分 objcls_score 为最高的分类得分 conf

attn_cls = (q_cls @ k_cls.transpose(-2, -1)) * self.scale * cls_score * cls_score_mask
attn_reg = (q_reg @ k_reg.transpose(-2, -1)) * self.scale# * fg_score * fg_score_mask

(3)图中省略了对 qkv 的归一化操作,attn @ vv 使用的是归一化前的原始 v

q_cls = q_cls / torch.norm(q_cls, dim=-1, keepdim=True)
k_cls = k_cls / torch.norm(k_cls, dim=-1, keepdim=True)
q_reg = q_reg / torch.norm(q_reg, dim=-1, keepdim=True)
k_reg = k_reg / torch.norm(k_reg, dim=-1, keepdim=True)
v_cls_normed = v_cls / torch.norm(v_cls, dim=-1, keepdim=True)
v_reg_normed = v_reg / torch.norm(v_reg, dim=-1, keepdim=True)
x_cls = (attn @ v_cls).transpose(1, 2).reshape(B, N, C)
x_reg = (attn @ v_reg).transpose(1, 2).reshape(B, N, C)

(4)v_normed 的用途在于计算相似度矩阵,根据下面代码理解计算过程。

  • 通过矩阵乘法得到相似度矩阵 attn_x_raw
  • 对多个头的相似度取均值 attn_x_raw
  • 通过阈值获取相似度较高的位置 x_mask
  • attn 即上图中 attn_clsattn_reg 的均值同样计算多个头的均值,再经过 softmax,记作 attn_new
  • x_masksim_round2 相乘并除以总和,所得的还是和为1的概率值,直观上理解就是只有 v 相似度较高的位置取 attn_new 的值得到 mask,作为新的融合特征的权重
attn_cls_raw = v_cls_normed @ v_cls_normed.transpose(-2, -1)
attn_reg_raw = v_reg_normed @ v_reg_normed.transpose(-2, -1)
attn_cls_raw = torch.sum(attn_cls_raw, dim=1, keepdim=False)[0] / self.num_heads
attn_reg_raw = torch.sum(attn_reg_raw, dim=1, keepdim=False)[0] / self.num_heads
# sim_thresh=0.75
sim_mask = torch.where(attn_cls_raw > sim_thresh, ones_matrix, zero_matrix)
# remove ave and conf guide in the reg branch, modified in 2023.12.5
# conf_sim_thresh=0.99
obj_mask = torch.where(attn_reg_raw > conf_sim_thresh, ones_matrix, zero_matrix)sim_attn = torch.sum(attn, dim=1, keepdim=False)[0] / self.num_heads
sim_round2 = torch.softmax(sim_attn, dim=-1)ave_mask = sim_mask * sim_round2 / (torch.sum(sim_mask * sim_round2, dim=-1, keepdim=True))
obj_mask = obj_mask * sim_round2 / (torch.sum(obj_mask * sim_round2, dim=-1, keepdim=True))

(5)mask 与输出特征经过如下操作得到最终的分类和回归特征
在这里插入图片描述
  个人理解:torch.norm 计算的是向量的 L2 范数,attn_x_raw 即计算每个目标 v 向量的余弦相似度。Attention 本身使用 attn(qk) 来引导 v 做特征的融合,这里用相似度矩阵加阈值来引导 attn,直观上理解就是想过滤掉相似度本身较低的目标之间的相互影响,attn 看作是每个目标对当前目标的权重,mask 便是将相似度较低的目标的权重强制变为 0。Attention 部分和当前使用 Mask 的部分都有 Concat 操作,可以把一个目标的特征向量划分为4份 v, attn + v, (mask + attn_new) + v, (mask + attn_new) + (attn + v),最终的特征可以看作包含原始特征和3种方式融合的特征。

(6)代码中 decouple_reg = True,以上计算仅保留分类的特征,而回归特征会从头开始重新计算一次。

features_cls, features_reg = self.agg(...)
_, features_reg = self.agg_iou()

  个人理解:分类和回归的特征分开融合效果更好,互相影响的点在于 attn = (attn_reg + attn_cls) / 2。从直觉上来说,同时用分类和回归的 attn 来引导特征融合感觉是个不错的选择,但是可能在融合分类特征时,希望 attn_cls 的强度要高于 attn_reg,反之亦是如此。直接设置权重可能比较僵硬(而且所谓的强度也只是猜想),例如 attn_cls_new = 0.7 * attn_cls + 0.3 * attn_reg ,干脆就多个分支,分别训练两种特征的 Attention。

(7)得到的特征经过全连接层输出新的 clsobj 结果
在这里插入图片描述
(8)后处理

  • cls_predsobj_preds 都经过 sigmoid 替换原始输出对应的结果
  • 筛选分类得分 ≥ 0.001 \ge 0.001 0.001 的结果(同一个 Anchor 有多个类别得分都高于阈值会一同保留)
  • 筛选 c l s s c o r e × o b j c o n f ≥ 0.001 \mathrm{cls\ score\times obj\ conf} \ge 0.001 cls score×obj conf0.001 的结果
  • NMS
  • 若 VID 结果中存在目标的帧数 ≤ 4 \le 4 4 则使用最初单帧检测的结果
  • 在绘制结果时,会再使用阈值筛选目标 c l s s c o r e × o b j c o n f ≥ 0.05 \mathrm{cls\ score\times obj\ conf} \ge 0.05 cls score×obj conf0.05

Train

Data

  训练数据为许多图像序列,train_seq.npy 中的内容如下,里面存放了多个图像序列构成的列表。

['ILSVRC2015/Data/VID/train/ILSVRC2015_VID_train_0002/ILSVRC2015_train_00575001/000000.JPEG', ...,'ILSVRC2015/Data/VID/train/ILSVRC2015_VID_train_0002/ILSVRC2015_train_00575001/000539.JPEG']
...

  先按照默认的训练参数 lframe = 0, gframe = 16 进行说明,把序列中的帧随机打乱,按 gframe 张图像为一组,作为一个 batch。简而言之,训练时一个 batch 的数据全部来自于一个视频,且帧的顺序是随机的。

  lframe != 0 的情况是先把所有帧按顺序,以 lframe 张图像为一组划分为 n 组。然后遍历每一组,当前组的所有图像记为 lf,然后在剩余所有组的图像中随机抽取 gframe 张图像记作 gflf+gf 作为一个 batch 进行训练。简而言之,是一些连续帧加上随机帧。

Loss

  与常见的损失计算并无太多区别,大致为
l o s s = w ∗ i o u + o b j + c l s + v i d _ o b j + v i d _ c l s loss=w*\mathrm{iou+obj+cls+vid\_obj+vid\_cls} loss=wiou+obj+cls+vid_obj+vid_cls
其中 w = 3 w=3 w=3 为权重,除了 i o u \mathrm{iou} iou 都用 nn.BCEWithLogitsLoss 计算。

总结&想法

1. 输入

  感觉只是对于 ILSVRC2015_VID 数据集中的视频有效。挑了几个视频看了下,基本有以下特点:视频长度短、场景或背景变化小、大多是针对一个或多个目标拍摄的视频且目标通常比较大。

2. VID

  牵扯到 VID 的部分其实只在 Head 中存在一点,模型在整个 Backbone 的部分和传统检测没有区别,所有的特征都只基于一帧的信息。
  VID 部分简单来说就是把所有帧的检测结果对应的特征拿出来,用 Attention 和相似度作为指引做特征融合,利用融合后的特征做新的预测。但新的预测仅限于 objcls,直观上就是对类别和是否为目标通过前后帧的信息做了修正,对于目标框的位置并没有任何改变。

  个人感觉 YOLOV++ 解决的主要问题是:某个目标在单帧中因为遮挡、视角、姿态、模糊等问题可能会被检测成别的类别,而在别的帧中可以清楚的检测到这个目标,于是通过融合特征来修正当前帧对这个目标的判断。但是可以看出,这依赖于 obj * conf 不能太低,如果在单帧检测中置信度不高,那么连修正的机会都没有。
  事实上对于时序数据做特征融合是个难点,YOLOV++ 应该是更倾向于检测速度,与单帧检测相比,增加的计算量并不多,不过会与目标数量 N 挂钩,目标越多特征融合的计算量越大,速度越慢。(代码中有与 minimal_limit=50 对应的最大数量限制参数,可以牺牲精度保障速度)

3. 初选 NMS

  为了方便,这里把单帧检测的结果称为初选目标,VID 后的结果最终目标。初选目标时默认不启用 NMS,对 YOLOV++ SwinTiny 做了下评估测试。

mAP不启用 NMS启用 NMS
total0.86560.8509
slow0.90710.8979
medium0.85820.8385
fast0.74070.7168

  评估具体的计算方式就不深究了,总之从结果来看,默认的不启用初选 NMS 效果更好。根据一般经验,对于一个目标通常会有多个 Anchor 的结果指向它,检测框位置、各种置信度略有不同,然后会通过 NMS 筛选得到其中一个对应此目标。在 VID 阶段,仅从特征相似度角度来看,可能同一帧中指向同个目标的多个 Anchor 的相似度会高于不同帧指向同个目标的 Anchor,但从代码中的最少目标限制和不启用初选 NMS 来看,保证融合的目标数量的优先级是更高的。

论文

  YOLOV++ 论文还没出,暂读 YOLOV 论文

Related Work

Object Detection in Still Images

  就是单帧检测,各种方法略过,重点在 One-stage 和 Two-stage 对于 VID 的影响。Two-stage 会先经过 RPN + ROI 得到候选区域的特征,One-stage 缺少这种特征,而这个特征在 VID 的特征融合中很好用。YOLOV 就是探索用 One-stage 的特征做融合的可行性。

  One-stage detectors are usually faster than two-stage ones, owing to the end-to-end manner. However, they lack explicit region-level semantic features that are widely used for feature aggregation in video object detection.

Object Detection in Videos

  文中把现有的 VID 方法大致分为两个分支

  One branch of existing video object detectors concentrate on tracklet-level post-processing. The methods in this category try to refine the prediction results from the still image detector in consecutive frames by forming the object tubelets. The final classification score of each box is adjusted according to the entire tubelet.
2016 -《Seq-NMS for video object detection》
2019 - VISIGRAPP -《Improving Video Object Detection by Seq-Bbox Matching》
2020 - IROS -《Robust and efficient post-processing for video object detection》

  第一个分支并没有太多介绍,看意思是单纯在后处理阶段通过整合对连续帧的检测结果来修正每个 box 的分类得分。下面的第二个分支是重点。

  Another branch aims to enhance the features of keyframes, expecting to alleviate degradation via utilizing the features from (selected) reference frames. These approaches can be roughly classified as optical flow-based, attention-based and tracking-based methods.
(1)optical flow-based
2017 - ICCV -《Flow-guided feature aggregation for video object detection》
2018 - CVPR -《Towards high performance video object detection》
(2)attention-based
2019 - ICCV -《Sequence level semantics aggregation for video object detection》
2019 - ICCV -《Relation distillation networks for video object detection》
2020 - CVPR -《Memory enhanced global-local aggregation for video object detection》
2021 - AAAI -《Temporal ROI align for video object recognition》
2021 - AAAI -《Mamba: Multi-level aggregation via memory bank for video object detection》
(3)tracking-based
2017 - ICCV -《Detect to track and track to detect》
2018 -《Integrated object detection and tracking with tracklet-conditioned detection》

(1)optical flow-based
  Deep Feature Flow 最先引入光流做图像级特征对齐,FGFA 使用光流沿运动路径融合特征。由于图像级特征融合计算成本太高,开发了 attention-based 方法。

(2)attention-based
  SESLA 根据 region-level 特征的语义相似性提出了 long-range 特征融合方法。受 Relation Networks 中 relation 模块的启发,RDN 提取了目标在空间和时间中的上下文关系。MEGA 设计了一个 memory enhanced global-local aggregation module 来更好地对目标之间的关系进行建模。TROIA 利用 ROI-Align 进行细粒度特征融合,HVR-Net 整合了视频内外的关系做进一步改进。MBMBA 通过 memory bank 扩大 reference feature set。QueryProp 通过 lightweight query propagation module 来提高 VID 速度。

(3)tracking-based
  D&T 通过构建不同帧特征的关联图(correlation maps),以 tracking 方式解决 VID 问题。

  最后提到以上这些方法大多基于 two-stage detectors,推理速度慢。

  所谓的 Image-level 图像级特征融合看起来就是会对全图的特征做融合,而后续的 attention-based 方法看起来是对局部,譬如仅对 region proposal 做特征融合来减少计算量,并且通常计算光流也很费时。

Methodology

(1)由于特征融合模块的权重是随机初始化的,如果直接在原始分类分支上融合特征并做反向传播反而会污染原本的权重,因此多了一个分支,也就是之前图中的 vid_cls_feat,但文中没说为什么回归分支不用一样加个分支。

In practice, we found that directly aggregating the collected features in the classification branch and backpropagating the classification loss of the aggregated features will result in unstable training. Since the weight of the feature aggregation module is randomly initialized, finetuning all the networks from the beginning will contaminate the pre-trained weights. To address the above concerns, we fix the weights in the base detector except for the linear projection layers in detection head. We further insert two 3 × 3 convolutional (Conv) layers into the model neck as a new branch, called video object classification branch, which generates features for aggregation. Then, we feed the collected features from the video and regression branches into our feature aggregation module.

(2)这里的 same problem 也就是 homogeneity issue 有点不清楚。猜测是使用相似度会导致跟差的目标匹配的同样是差的 proposal,例如对于因为运动模糊导致不容易检测的一只狗,与其最为匹配的不是在其他帧中静止清晰的狗,而是同样模糊的一些目标。文中具体解决这个问题的方式看起来是将分类和回归的相似度分离来引导 V 的融合,具体方式与 YOLOV++ 略有不同(get 不到为什么这样可以解决这种问题)。最后提到在较长的时间序列中不使用位置编码。

Simply referring to the cosine similarity will find features most similar to the target. However, when the target suffers from some degradation, the selected reference proposals using cosine similarity are very likely to have the same problem. We name this phenomenon the homogeneity issue.

To overcome the homogeneity issue, we further take predicted confidences from the raw detector into consideration, …
The positional information is not embedded, because the locations in a long temporal range would not be helpful as claimed in MEGA.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/41410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ 构造,析构,拷贝,移动构造函数

文章目录 概述1.构造函数2. 拷贝构造函数3.移动构造函数4.析构函数 例子QTUE4/5 c 小结 概述 对于c来说,最基础的是类。对于一个类来说,主要由以下函数构成。如下: 构造函数拷贝构造函数移动构造函数析构函数 当然,还有一个操作…

【简历】郑州某二本学院:JAVA实习简历指导,基本没有面试机会

注:为保证用户信息安全,姓名和学校等信息已经进行同层次变更,内容部分细节也进行了部分隐藏 简历说明 这份简历是一个25届二本同学找JAVA实习的简历,从整体来看,简历版式没有问题,非常清晰。 但是内容特…

数据操作10-15题(30 天 Pandas 挑战)

数据操作 1. 相关知识点1.12 分组与连表1.13 排名 2. 题目2.10 第N高的薪水2.11 第二高的薪水2.12 部门工资最高的员工2.13 分数排名2.14 删除重复的电子邮箱2.15 每个产品在不同商店的价格 1. 相关知识点 1.12 分组与连表 分组max_salaryemployee.groupby(departmentId)[sal…

搜索+动态规划

刷题刷题刷题刷题 ​​​​​​​​​​​​​​Forgery - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路: 需要两个数组,一个数组全部初始化为".",另一个数组输入数据,每碰到一个“.”就进行染色操作,将其周围的…

Java后端每日面试题(day3)

目录 Spring中Bean的作用域有哪些?Spring中Bean的生命周期Bean 是线程安全的吗?了解Spring Boot中的日志组件吗? Spring中Bean的作用域有哪些? Bean的作用域: singleton:单例,Spring中的bean默…

已经安装deveco-studio-4.1.3.500的基础上安装deveco-studio-3.1.0.501

目录标题 1、执行exe文件后安装即可2、双击devecostudio64_3.1.0.501.exe2.1、安装Note (注意和4.1的Note放不同目录)2.2、安装ohpm (注意和4.1版本的ohpm放不同目录)2.3、安装SDK (注意和4.1版本的SDK放不同目录) 1、执行exe文件后安装即可 2、双击devecostudio64_3.1.0.501.e…

Ubuntu 22.04.4 LTS 安装 php apache LAMP 环境nginx

1 安装php-fpm apt update apt-get install php-fpm #配置php-fpm服务启动 systemctl enable php8.1-fpm systemctl start php8.1-fpm #查看服务 systemctl status php8.1-fpm #查看版本 rootiZbp1g7fmjea77vsqc5hmmZ:~# php -v PHP 8.1.2-1ubuntu2.18 (cli) (built: J…

HTML内容爬取:使用Objective-C进行网页数据提取

网页爬取简介 网页爬取,通常被称为网络爬虫或爬虫,是一种自动浏览网页并提取所需数据的技术。这些数据可以是文本、图片、链接或任何网页上的元素。爬虫通常遵循一定的规则,访问网页,解析页面内容,并存储所需信息。 …

mars3d加载wms服务或者wmts服务注意事项

1.wms只支持4326、3857、4490的标准切片,其他坐标系不支持 Mars3D三维可视化平台 | 火星科技 2.wmts同理,Mars3D三维可视化平台 | 火星科技 3.对应级别tilematrix找到的瓦片tilerow&tilecol这两个参数使用常见报错无效参考: 【Mars3d】…

护航端侧大模型平稳健康发展,百度大模型内容安全Lite版正式发布

6月28日,WAVE SUMMIT深度学习开发者大会 2024 “智变应用、码动产业”平行论坛在北京召开。与会,百度大模型内容安全Lite版正式发布,可面向低算力和超低算力的终端大模型提供离线场景下的一站式安全解决方案,为各类终端大模型平稳…

国际工业巨头遭勒索,亚信安全《勒索家族和勒索事件监控报告》

本周态势快速感知 本周全球共监测到勒索事件94起,事件数量有小幅下降。从整体上看,Lockbit3.0仍然是影响最严重的勒索家族;本周RansomHub是影响最严重的勒索家族;Akira和Dragonforce恶意家族紧随其后,需要注意防范。拉…

ython 使用 cx_Freeze 打包,不想要打包文件中能直接看到依赖的代码,如何处理

背景:因为使用 cx_Freeze 打包时,添加需要依赖的文件 cx_Freeze 是一个用于将 Python 程序打包成独立可执行文件的工具,支持多个平台。当你需要打包包含多个 .py 文件的项目时,你可以通过编写一个 setup.py 文件来指定哪些模块应…

基于Spring Boot框架的EAM系统设计与实现

摘 要:文章设计并实现一个基于Spring Boot框架的EAM系统,以应对传统人工管理模式存在的低效与信息管理难题。系统利用Java语言、JSP技术、MySQL数据库等技术栈,构建了一个B/S架构的高效管理平台,提升了资产管理的信息化水平。该系…

独立站外链的重要性是什么?

独立站外链在提升网站排名和增加流量方面有着重要的作用。简单来说,外链就是从其他网站指向你网站的链接。谷歌和其他搜索引擎会根据这些外链来判断你网站的权威性和相关性。 有了高质量的外链,搜索引擎会更倾向于认为你的网站内容是有价值的&#xff0c…

c++ 附赠课程的知识点记录

(1) 静态变量的赋值 再一个例子: (2) 一般在定义类的赋值运算符函数时, operator ( const A& a ) 函数,应避免自赋值的情况,就是把对象 a 又赋值给 对象a 如同 a a 这样的情况…

如何摆脱反爬虫机制?

在网站设计时,为了保证服务器的稳定运行,防止非法数据访问,通常会引入反爬虫机制。一般来说,网站的反爬虫机制包括以下几种: 1. CAPTCHA:网站可能会向用户显示CAPTCHA,要求他们在访问网站或执行…

空状态页面设计的艺术与科学

空状态界面是用户在网站、APP中遇到的因无数据展示而中断体验的界面,这个界面设计对于解决用户疑惑有着很大的帮助。那么我们应该如何设计空状态界面呢?空状态是指在界面设计中,没有内容或数据时所显示的状态。它可能出现在各种情况下&#x…

CentOS 7 搭建rsyslog日志服务器

CentOS 7 搭建rsyslog日志服务器 前言一、IP地址及主机名称规划1.修改主机名 二、配置rsyslog日志服务器1.安装rsyslog服务2.编辑/etc/rsyslog.conf 文件3.启动并启用rsyslog服务4.验证端口是否侦听 三、在rsyslog日志服务器上配置firewalld防火墙四、配置rsyslog日志客户端1.编…

超实用的VS Code插件推荐

VS Code代码编辑器中提供了丰富的插件,满足不同开发者的需求。这里为大家推荐一些强大的VS Code插件,帮助你打造一个个性化的开发环境,让你的编码体验更加舒适和高效。 打开扩展模块,输入安装包名称,回车进行搜索&…

【WSL】常用命令

文章目录 启动 WSL列出 Linux 发行版安装 Linux 发行版设置默认的 Linux 发行版卸载 Linux 发行版更新 WSL检查 WSL 状态启动和关闭 WSL跨系统文件访问其他命令 Windows Subsystem for Linux (WSL) 提供了一系列命令用于管理 Linux 发行版在 Windows 系统中的运行。下面是一些常…