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)。

![[yolox网络图.png]]

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,则被选中为候选正样本。

  1. 根据中心点判断

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。
  1. .根据目标框来判断

以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个锚框是正样本锚框。

  1. 初筛正样本信息提取

根据位置,可以将网络预测的候选检测框位置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
  1. 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)
  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)
)
  1. 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

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

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

相关文章

【Review+预测】测试架构演进的曲折之路

文章目录 前言 一、“原始”阶段 二、“小打小闹”阶段 三、“小米加步枪”阶段 四、“摩托化部队”阶段 五、“骑兵连”阶段 六、“海军陆战队”阶段 七、“社区型组织”阶段 前言 近期公司的测试团队需要重新组织安排,本着谦虚谨慎的态度,我从…

视频技术1:使用ABLMediaServer推流rtsp

ABLMediaServer定位是高性能、高稳定、开箱即用、商用级别的流媒体服务器 下边展示了如何把1个mp3作为输入源,转换为rtsp流的过程。 作用:用rtsp模拟摄像头的视频流 1、启动ABLMediaServer ABLMediaServer-2024-03-13\WinX64\ABLMediaServer.exe 配…

Redis中的缓存雪崩

缓存雪崩 🤔现象分析 缓存雪崩是指在同一时段大量的缓存key同时失效或者缓存服务(Redis等)宕机,导致大量请求到达数据库,带来巨大压力。 👊 解决方案 利用Redis集群提高服务的可用性,避免缓存服务宕机给缓存业务添…

流畅的 Python 第二版(GPT 重译)(十)

第十八章:with、match 和 else 块 上下文管理器可能几乎与子例程本身一样重要。我们只是初步了解了它们。[…] Basic 有一个 with 语句,在许多语言中都有 with 语句。但它们的功能不同,它们都只是做一些非常浅显的事情,它们可以避…

打造高效安全的电池管理 | 基于ACM32 MCU的两轮车充电桩方案

随着城市化进程的加快、人们生活水平的提高和节能环保理念的普及,越来越多的人选择了电动车作为代步工具,而两轮电动车的出行半径较短,需要频繁充电,因此在城市中设置两轮车充电桩就非常有必要了。城市中的充电桩不仅能解决两轮车…

数字排列 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 200分 题解: Java / Python / C++ 题目描述 小明负责公司年会,想出一个趣味游戏: 屏幕给出 1−9 中任意 4 个不重复的数字,大家以最快时间给出这几个数字可拼成的数字从小到大排列位于第 n 位置的数字,其中 n 为给出数字中最大的(如果不到这么多数…

diffusion model(十四): prompt-to-prompt 深度剖析

infopaperPrompt-to-Prompt Image Editing with Cross Attention Controlgithubhttps://github.com/google/prompt-to-promptOrg:Google Research个人复现https://github.com/myhz0606/diffusion_learning个人博客主页http://myhz0606.com/article/p2p 1 前言 基于扩散模型&a…

MySQL数据库 - 事务

1. 事务的概念 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中, 要删除一个人员,即需要删除人员的基本资料,又需要删除和该人员相关的信息,如信箱, 文章等等。这样&#x…

移动硬盘故障解析:解决无法访问且位置不可用问题

在我们日常的工作和生活中,移动硬盘已成为存储和传输数据的重要工具。然而,有时我们会遇到移动硬盘无法访问且位置不可用的情况,这无疑给数据的存储和访问带来了极大的困扰。本文将深入探讨这一问题,分析其原因,并给出…

网络工程师练习题6

网络工程师 综合题 计算并填写下表: TP地址191.23.181.13子网掩码255.255.192.0地址类型 (1)网络地址(2)直接广播地址(3)主机号(4)子网内的最后一个可用IP地址&#xf…

mysql的学习笔记

干前端好几年了,只会前端总感觉少了条腿,处处不自在,决定今年学习下后端的东西.以前总想着学node会更快,但是实际工作上却用不上. 出来混,总是要还的,该学的javaWeb这一套体系的东西,总是需要学习的. 那就开始啦. 一,在本地电脑mac上安装mysql 这个参考的这篇文章,照着做一次…

线性顺序表算法库

list.cpp 具体函数实现 #include <stdio.h> #include "list.h" #include <malloc.h>/************************************************** ①函数名: CreateList 功 能: 用数组构建顺序表 参 数: ①SqList *&L:传入的线性表 ②ElemType a[]:使用…

文件上传基础篇

文件上传基础篇 文件上传漏洞原理 ​ 目标网站存在文件上传接口&#xff0c;但是对用户上传的文件没有做仔细甄别&#xff0c;导致黑客可以根据此功能点直接上传木马到网站服务器&#xff0c;造成危害 文件上传存在点 ​ 通常有头像上传&#xff0c;pdf上传 文件上传防护 …

Git浅谈配置文件和免密登录

一、文章内容 简述git三种配置ssh免密登录以及遇见的问题git可忽略文件git remote 相关操作 二、Git三种配置 项目配置文件(局部)&#xff1a;项目路径/.git/config 文件 git config --local user.name name git config --local user.email 123qq.cc全局配置文(所有用户): …

X1 grok-1 开源大语言模型下载

Grok 前言 大型语言模型 Grok-1 的基本模型权重和网络架构。Grok-1 是一个 3140 亿参数的专家混合模型&#xff0c;由 xAI 从头开始训练。 这是 2023 年 10 月结束的 Grok-1 预训练阶段的原始基础模型检查点。这意味着该模型不会针对任何特定应用&#xff08;例如对话&#x…

Linux的学习之路:1、发展史与编译环境的搭建

一、发展史 1991年10月5日&#xff0c;赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组 &#xff08;comp.os.minix&#xff09;中宣布他编制出了一种类似UNIX的小操作系统&#xff0c;叫Linux。新的操作系统是受到另一个UNIX的小操作系统——Minix的启发…

【群晖】Docker Compose部署 Emby Server

【群晖】Docker Compose部署 Emby Server 本来群晖上面的 Emby 是用套件安装的&#xff0c;但是不巧的是前两天脑袋一抽装了两个插件&#xff0c;导致 Emby Server被当肉鸡了&#xff0c;还找不到脚本代码在哪儿&#xff0c;一天时间上传了3T的流量。无奈之下&#xff0c;只能尝…

计算机二级大题

题目来源&#xff1a;计算机二级Python半个月抱佛脚大法&#xff08;内呈上真题版&#xff09; - 知乎 1.大题1 注意csv文件读取的处理 ls[] for line in f: ls.append(line.strip(\n).split(,)) 2. 大题2 第一问&#xff1a; #计算有效票张数 fopen("vote.txt",…

LinuxU盘挂载原理,为什么要用到U盘挂载及实现U盘挂载

目录 一、U盘挂载原理 二、为什么要用到U盘挂载 三、实现U盘挂载 一、准备工作 1、安装gcc 2、下载ntfs-3g 3、解压 4、编译准备 5、编译并安装 二、挂载演示 一、U盘挂载原理 Linux的U盘挂载原理涉及以下几个方面&#xff1a; 设备识别&#xff1a;当您将U盘插入Lin…

leetcode刷题(javaScript)——动态规划相关场景题总结

动态规划在 JavaScript 刷题中有一定的难度&#xff0c;但也是非常常见和重要的算法思想。动态规划通常适用于需要求解最优解、最大值、最小值等问题的场景&#xff0c;可以将复杂问题拆分成子问题&#xff0c;通过存储子问题的解来避免重复计算&#xff0c;从而提高效率。 理解…