ByteTrack多目标跟踪——YOLOX详解
文章目录
- 1 before train
- 1.1 dataset
- 1.2 model
- 2 train
- 2.1 Backbone
- 2.2 PAFPN
- 2.3 Head
- 2.3.1 Decoupled Head
- 2.3.2 anchor-free
- 2.3.3 标签分配
- ① 初步筛选
- ② simOTA
- 2.3.4 Loss计算
项目地址: ByteTrack
ByteTrack使用的检测器是YOLOX,是一个目前非常流行并且效果非常好的检测器,ByteTrack的跟踪效果也完全离不开YOLOX的检测性能。
1 before train
训练之前的准备,主要是初始化模型以及数据集。
1.1 dataset
在ByteTrack中图像输入大小为:(896,1600)
1.2 model
初始化
YOLOXPAFPN
YOLOXHead
2 train
2.1 Backbone
采用Darknet-53
self.backbone = CSPDarknet(depth, width, depthwise=depthwise, act=act)
backbone的输入input为一个batch的图片 (B,C,H,W)
out_features = self.backbone(input)
out_features的输出为3个特征层(分别为’dark3’,‘dark4’,‘dark5’)组成的字典,举个例子,各特征层的shape如下:
{‘dark3’:(B,320,112,200),
‘dark4’:(B,640,56,100),
‘dark5’:(B,1280,28,50)}
均为(B,C,H,W),只是尺寸和特征维度不同。
2.2 PAFPN
在Neck结构中,Yolox采用PAFPN的结构进行融合。如下图所示,将高层的特征信息,先通过上采样的方式进行传递融合,再通过下采样融合方式得到预测的特征图,最终输出3个特征层组成的元组结果,各特征层的shape如下:
{‘dark3’:(B,320,112,200),
‘dark4’:(B,640,56,100),
‘dark5’:(B,1280,28,50)}
均为(B,C,H,W),只是尺寸和特征维度不同。
2.3 Head
2.3.1 Decoupled Head
在Yolox中,作者增加了三个Decoupled Head,俗称“解耦头”。
总共有三个分支:
- cls_output:主要对目标框的类别,预测分数。因为只有行人一个类别,所以大小为1,这里为(B,1,112,200)。
- obj_output:主要判断目标框是前景还是背景,这里为(B,1,112,200)。
- reg_output:主要对目标框的坐标信息(x,y,w,h)进行预测,这里为(B,4,112,200)。
2.3.2 anchor-free
首先,相对anchor-based参数量大大减小。
举个例子,最后8400个预测框中,其中有400个框,所对应锚框的大小,为32*32。中间的分支,最后有1600个预测框,所对应锚框的大小,为16*16。最下面的分支,最后有6400个预测框,所对应锚框的大小,为8*8。
当有了29400个预测框的信息,每张图片也有标注的目标框的信息。
这时的锚框,就相当于桥梁。
这时需要做的,就是将29400个锚框,和图片上所有的目标框进行关联,挑选出正样本锚框。
而相应的,正样本锚框所对应的位置,就可以将正样本预测框,挑选出来。
这里采用的关联方式,就是标签分配。
2.3.3 标签分配
① 初步筛选
yolo_head.py的get_in_boxes_info
函数中,如果 anchor bbox 中心落在 groundtruth bbox或 fixed bbox,则被选中为候选正样本。
- 根据中心点判断
anchor box的中心点落在人工标注框(Ground Truth Boxes)的矩形范围中的所有anchor;
- 通过groundtruth的[x_center,y_center,w,h],计算出每张图片的每个groundtruth的左上角、右下角坐标
gt_bboxes_per_image_l = ((gt_bboxes_per_image[:, 0] - 0.5 * gt_bboxes_per_image[:, 2]).unsqueeze(1).repeat(1, total_num_anchors)
) # [n_gt, n_anchor]
gt_bboxes_per_image_r = ((gt_bboxes_per_image[:, 0] + 0.5 * gt_bboxes_per_image[:, 2]).unsqueeze(1).repeat(1, total_num_anchors)
) # [n_gt, n_anchor]
gt_bboxes_per_image_t = ((gt_bboxes_per_image[:, 1] - 0.5 * gt_bboxes_per_image[:, 3]).unsqueeze(1).repeat(1, total_num_anchors)
) # [n_gt, n_anchor]
gt_bboxes_per_image_b = ((gt_bboxes_per_image[:, 1] + 0.5 * gt_bboxes_per_image[:, 3]).unsqueeze(1).repeat(1, total_num_anchors)
) # [n_gt, n_anchor]
- 前4行代码计算锚框中心点(x_center,y_center)和gt标注框左上角(gt_l,gt_t),右下角(gt_r,gt_b)两个角点的相应距离。
b_l = x_centers_per_image - gt_bboxes_per_image_l
b_r = gt_bboxes_per_image_r - x_centers_per_image
b_t = y_centers_per_image - gt_bboxes_per_image_t
b_b = gt_bboxes_per_image_b - y_centers_per_image
bbox_deltas = torch.stack([b_l, b_t, b_r, b_b], 2)
is_in_boxes = bbox_deltas.min(dim=-1).values > 0.0
is_in_boxes_all = is_in_boxes.sum(dim=0) > 0
- 而在第五行,将四个值叠加之后,通过第六行,判断是否都大于0?就可以将落在groundtruth矩形范围内的所有anchors,都提取出来了。因为ancor box的中心点,只有落在矩形范围内,这时的b_l,b_r,b_t,b_b都大于0。
- .根据目标框来判断
以Ground Truth Boxes中心点为基准,四周向外扩展2.5倍stride,构成边长为5倍stride的正方形,挑选anchor box中心点落在正方形内的所有锚框。
- 以groundtruth中心点为基准,设置边长为5的正方形,挑选在正方形内的所有锚框。
- 如果图片的尺寸为 640 × 640,且当前特征图的尺度为 80 × 80,则此时stride为 8, 将 5 × 5 的正方形映射回原图,fixed bbox 尺寸为 400 × 400。
- 找出所有中心点(x_center,y_center)在正方形内的锚框。
- 未选中的预测框为负样本,直接打上负样本标签。
总体来说get_in_boxes_info返回两个值,fg_mask和is_in_boxes_and_center,fg_mask为29400维数组,即29400个框的正负性,用ture和false表示,is_in_boxes_and_center为[gt_num, 正样本个数]
② simOTA
假定图片上有3个目标框,即3个groundtruth,且检测类别为1。
上一节中,我们知道有29400个锚框,但是经过初步筛选后,假定有1000个锚框是正样本锚框。
- 初筛正样本信息提取
根据位置,可以将网络预测的候选检测框位置bboxes_preds、前景背景目标分数obj_preds、类别分数cls_preds等信息,提取出来。
bboxes_preds_per_image = bboxes_preds_per_image[fg_mask] # [1000, 4]
cls_preds_ = cls_preds[batch_idx][fg_mask] # [1000, 1]
obj_preds_ = obj_preds[batch_idx][fg_mask] # [1000, 1]
num_in_boxes_anchor = bboxes_preds_per_image.shape[0] # 1000
- Loss函数计算
针对筛选出的1000个候选检测框,和3个groundtruth计算Loss函数。
- 首先是位置信息的loss值:
pair_wise_ious_loss
[3,1000]
pair_wise_ious = bboxes_iou(gt_bboxes_per_image, bboxes_preds_per_image, False) # [gt_num, matched_anchor]
gt_cls_per_image = ( # [gt_num, matched_anchor, class_num]F.one_hot(gt_classes.to(torch.int64), self.num_classes).float().unsqueeze(1).repeat(1, num_in_boxes_anchor, 1)
)
pair_wise_ious_loss = -torch.log(pair_wise_ious + 1e-8)
- 然后是综合类别信息和目标信息的loss值:
pair_wise_cls_loss
[3,1000]
cls_preds_ = ( # [gt_num, matched_anchor, 1]cls_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() # [gt_num, matched_anchor, 1]* obj_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() # [gt_num, matched_anchor, 1]
)
pair_wise_cls_loss = F.binary_cross_entropy( # [gt_num, matched_anchor]cls_preds_.sqrt_(), gt_cls_per_image, reduction="none"
).sum(-1)
- cost成本计算
有了reg_loss和cls_loss,就可以将两个损失函数加权相加,计算cost成本函数了。
cost = (pair_wise_cls_loss+ 3.0 * pair_wise_ious_loss+ 100000.0 * (~is_in_boxes_and_center)
)
- SimOTA
采用一种简化版的SimOTA方法,求解近似最优解。这里对应的函数,是get_assignments函数中的self.dynamic_k_matching
:
num_fg,gt_matched_classes, gt_matched_ids, pred_ious_this_matching, matched_gt_inds,)
= self.dynamic_k_matching(cost, pair_wise_ious, gt_classes, gt_ids, num_gt, fg_mask)
此部分详见深入浅出Yolo系列之Yolox核心基础完整讲解
2.3.4 Loss计算
loss_iou = (self.iou_loss(bbox_preds.view(-1, 4)[fg_masks], reg_targets) # [matched_anchor, 4]
).sum() / num_fg
loss_obj = (self.bcewithlog_loss(obj_preds.view(-1, 1), obj_targets) # [all_anchor, 1]).sum() / num_fg
loss_cls = (self.bcewithlog_loss(cls_preds.view(-1, self.num_classes)[fg_masks], cls_targets # [matched_anchor, 1] )
).sum() / num_fg
在前面精细化筛选中,使用了reg_loss和cls_loss,筛选出和目标框所对应的预测框。
因此这里的iou_loss和cls_loss,只针对目标框和筛选出的正样本预测框进行计算。
而obj_loss,则还是针对29400个预测框。
参考:
深入浅出Yolo系列之Yolox核心基础完整讲解
目标检测: 一文读懂 YOLOX
相关文章:

ByteTrack多目标跟踪——YOLOX详解
文章目录 1 before train1.1 dataset1.2 model 2 train2.1 Backbone2.2 PAFPN2.3 Head2.3.1 Decoupled Head2.3.2 anchor-free2.3.3 标签分配① 初步筛选② simOTA 2.3.4 Loss计算 项目地址: ByteTrack ByteTrack使用的检测器是YOLOX,是一个目前非常流行…...

Linux 常见驱动框架
一、V4L2驱动框架 v4l2驱动框架主要对象: (1)video_device:一个字符设备,为用户空间提供设备节点(/dev/videox),提供系统调用的相关操作(open、ioctl…) (2)v4l2_device:…...
Oracle函数6—递归查询(start with...connect by、sys_connect_by_path、level)
文章目录 一、准备数据二、基本使用三、level函数四、获取完整的全树路径 一、准备数据 创建表 CREATE TABLE TEST_ORG (ID VARCHAR2(64) NOT NULL PRIMARY KEY,NAME VARCHAR2(200),PARTEN_ID VARCHAR2(64) ); comment on column TEST_ORG.ID is 主键; comment on column TES…...

人机交互三原则,网络7层和对应的设备、公钥私钥
人机交互三原则 heo Mandel提出了人机交互的三个黄金原则,它们强调了相似的设计目标,分别是: 简单总结为:控负持面–>空腹吃面 1,用户控制 2,减轻负担 3,保持界面一致 置用户于控制之下&a…...

vue2源码学习01配置rollup打包环境
1.下载rollup相关依赖 npm i rollup rollup-plugin-babel babel/core babel/preset-env --save-dev 2.新建rollup.config.js配置打包选项 //rollup可以导出一个对象,作为打包的配置文件 import babel from rollup-plugin-babel export default {input: ./src/ind…...

DP:斐波那契数列模型
创作不易,感谢三连支持 ! 斐波那契数列用于一维探索的单峰函数之中,用于求解最优值的方法。其主要优势为,在第一次迭代的时候求解两个函数值,之后每次迭代只需求解一次 。 一、第N个泰波那契数 . - 力扣(…...
JavaScript高级(十四)----prmise
异步请求的处理方式 回调函数 所谓的回调函数就是函数作为参数的传递,在一个函数内部调用另一个函数,调用的同时可以把内部函数的数据传递出来,他的使用场景就是异步操作,数据需要等待一段时间才能返回的情况下可以使用回调函数…...

28 OpenCV 轮廓周围绘制图形
文章目录 approxPolyDP 轮廓周围绘制矩形boundingRectminAreaRect绘制圆和椭圆示例 approxPolyDP 轮廓周围绘制矩形 approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)curve:输入点集,二维点向量的集合appro…...

校企合作,助力人才培养——黄冈师范学院-唯众 “实习实训基地”揭牌仪式顺利举行
3月20日上午,黄冈师范学院计算机学院院长何中林、教务处实习科科长雷汝琳以及计算机学院实验室主任肖飞一行三人,莅临唯众进行参观交流。唯众总经理冉柏权、销售总监舒敏以及董事长助理代西凯进行了热情接待。双方就如何更好地结合企业需求与学院教育资源…...
npm audit fix --force
npm audit fix --force是npm的一个命令,用于自动修复包中的安全漏洞。 其中: - npm audit:审查项目中的依赖包,检查是否存在已知的安全漏洞。 - fix:自动安装相关的补丁来修复发现的漏洞。 - --force:强制安装补丁版本,即使出现不兼容也强制更新。 所以npm audit fix --fo…...

递增四元组
解法: 首先都可以想到dp[i]:第i个元素结尾的递增四元组有dp[i]个 然后发现有一组数据:2,3,6,1,5,8。会出现6结尾和5结尾的递增三元组,也就是未来的决策受过去影响,专业的说就是有后效性。需要强化约束条件࿰…...

蓝桥杯每日一题——棋盘
问题描述 小蓝拥有 n xn 大小的棋盘,一开始棋盘上全都是白子。小蓝进行了 m 次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋子变为黑色,黑色棋子变为白色)请输出所有操作做完后棋盘上每个棋子的颜色。输入格式 输入的…...

QT6实现创建与操作sqlite数据库及读取实例(一)
一.Qt为SQL数据库提供支持的基本模块(Qt SQL) Qt SQL的API分为不同层: 驱动层 SQL API层 用户接口层 1.驱动层 对于Qt 是基于C来实现的框架,该层主要包括QSqlDriver,QSqlDriverCreator,QSqlDriverCreatorBase,QSqlPlug…...

第十四届蓝桥杯JavaB组省赛真题 - 阶乘求和
/ 10^9考虑前九位,% 10^9保留后9位 解题思路: 求获取结果的后九位数字,需要对10^9取余,因为202320232023这个数字的阶乘太大,必须要减少计算量,因为当一个整数乘以10^9后对其取余,那么结果都为0。 所以我…...

Java毕业设计 基于springboot医院挂号系统 医院管理系统
Java毕业设计 基于springboot医院挂号系统 医院管理系统 springboot医院挂号系统 医院管理系统 功能介绍 用户:登录 首页 个人资料 修改密码 门诊管理 用户挂号 医生:登录 首页 个人资料 修改密码 门诊管理: 用户挂号 处方划价 项目划价 项目缴费 项目…...

【MySQL】基本查询(1)
【MySQL】基本查询(1) 目录 【MySQL】基本查询(1)表的增删改查Create单行数据 全列插入多行数据 指定列插入插入否则更新替换 RetrieveSELECT 列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件英语不…...

一文讲清!进销存管理系统如何实现锁库及库存冻结?计算月加权平均成本?
进销存管理系统中的锁库及库存冻结如何实现?进销存管理系统如何计算月加权平均成本?进销存管理系统又该如何统计和预测采购需求?这些进销存管理难题困扰着许多企业管理者。本文将结合数年从业经验,深入探讨这些进销存管理难题&…...

将本地项目上传至码云
1.打开git,然后进入到项目目录 2.进入到项目目录,然后进行git的初始化 成功后本地项目目录内会多出一个“.git”文件: 指令介绍: git init -- 建立本地仓库 3.在码云上创建仓库,名为“MyMoney” 创建过程参考&…...

虚拟化技术
前言 大家好我是jiantaoyab,这是我所总结作为学习的笔记第十八篇,在这里分享给大家,这篇文章讲虚拟技术就是大家平时用到的云服务器是什么。 虚拟机技术变迁 虚拟机(Virtual Machine)技术,其实就是指在现…...

鸿蒙一次开发,多端部署(一)简介
背景 随着终端设备形态日益多样化,分布式技术逐渐打破单一硬件边界,一个应用或服务,可以在不同的硬件设备之间随意调用、互助共享,让用户享受无缝的全场景体验。而作为应用开发者,广泛的设备类型也能为应用带来广大的…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...