本文参考:
https://blog.csdn.net/weixin_46142822/article/details/124074168
该作者写的细节我认为应该是 SimOTA 的细节。
https://zhuanlan.zhihu.com/p/397993315 果然是 SimOTA,其实是抄的这篇的。

OTA 论文回顾: https://www.cnblogs.com/odesey/p/16740854.html

SimOTA 来自于 YOLOX 论文:https://arxiv.org/pdf/2107.08430.pdf ,是 OTA 的简化, OTA 使用 Sinkhorn-Knopp Iteration 来求解 cost 矩阵。 OTA 是直接基于规则,直接用 k 个最小 cost 值的候选框作为正样本。

1. 定义

为了便于理解,我们假设:

  • 一张图片上有 3个目标框,即 3个ground truth
  • 项目有 2个检测类别,比如 cat/dog
  • 网络输出1000个预测框,其中只有少部分是正样本,绝大多数是负样本

bboxes_preds_per_image候选检测框的信息,维度是[1000,4]。预测框的四个坐标。

obj_preds 是目标分数(object score),维度是 [1000,1]。预测框是前景还是背景。

cls_preds 是类别分数,维度是 [1000,2]。预测框的2个检测类别的one-hot。

训练网络需要知道这 1000个预测框的标签,而如何分配标签呢?

使用OTA方法,分为4步,具体做法如下:

step1:生成cost矩阵

OTA 方法分配标签是基于 cost 的,因为有 3个目标框和1000个预测框,所以需要生成 3 × 1000 的 cost matrix(也就是每个真实框都要和1000个预测框计算下 cost)。

那么 cost 怎么计算?

对于目标检测任务,cost 由定位损失和分类损失组成,计算方法如下:

(1) 定位损失

计算 3个目标框,和 1000个候选框,得到每个目标框和 1000 个预测框之间的 iou(pair_wise_ious)。

再通过 -torch.log 计算得到定位损失,即 pair_wise_iou_loss,向量维度为[3, 1000]。3 是 3个真实框,每个都计算1000个值。

pair_wise_ious=bboxes_iou(gt_bboxes_per_image,bboxes_perds_per_image,False)
pair_wise_ious_loss=-torch.log(pair_wise_ious+1e-8)
(2) 分类损失

通过第一行代码,将类别的条件概率(cls_preds:表示分类的概率)和目标的先验概率(obj_preds:是前景的概率)做乘积,得到目标的类别分数(两个乘积得到的)。

再通过第二行代码,F.binary_cross_entroy 的处理,得到 3个目标框和1000个预测框 的综合loss值,得到类别损失,即 pair_wise_cls_loss,向量维度为 [3,1000]。3也是 3个真实框。其实这里就是算一个2分类交叉熵,cls_preds 和 真实框的 1 算下。每个真实框算1000次。

cls_preds=(cls_preds_.float().unsqueeze(0).repeat(num_gt,1,1).sigmoid_()
*obj_preds_.unsqueeze(0).repeat(num_gt,1,1).sigmoid_())pair_wise_cls_losss=F.binary_cross_entropy(cls_pres_.sqrt_(),gt_cls_per_image,reduction='none').sum(-1)

有了reg_loss和 cls_loss,将两个损失函数加权相加,就可以得到cost成本函数了。

cost 计算公式如下:

Cij=Lijcls+λLijregC_{ij} = L_{ij}^{cls} + \lambda L_{ij}^{reg}Cij​=Lijcls​+λLijreg​

加权系数λ=3\lambda=3λ=3,计算代码如下:

cost=pair_wise_cls_loss+3.0*pair_wise_ious_loss+100000.0*(~is_in_boxes_and_center)

step2:dynamic_k_estimation

每个 gt 提供多少正样本,可以理解为“ 这个 gt 需要多少个正样本才能让网络更好的训练收敛 ”。

直觉上,每个 gt 的大小、尺度和遮挡条件不同,所以其提供的 positive albel 数量也应该是不同的,如何确定每个 gt 的正样本数 k 值呢?论文提供了一个简单的方案,该方法称之为:Dynamic k Estimation,具体做法如下:

从前面的 pair_wise_ious 中,给每个真实框,挑选 10个iou 最大的预测框。因为前面假定有3个目标,因此这里topk_ious的维度为[3,10]。 其实这里就是对于每个真实框选出来的 1000 个 IOU 值中选出来十个。

topk_ious 计算代码如下:

ious_in_boxes_matrix = pair_wise_ious
n_candidate_k = min(10, ious_in_boxes_matrix.size(1))
topk_ious, _ = torch.topk(ious_in_boxes_matrix, n_candidate_k, dim=1)

下面通过topk_ious的信息,动态选择预测框。**dynamic_k_matching 代码如下:

dynamic_ks = torch.clamp(topk_ious.sum(1).int(), min=1)

针对每个目标框,计算所有 anchor 的 iou 值之和,再经过 torch.clamp 函数,得到最终左边的dynamic_ks值,给目标框 1 和 3 各分配 3 个候选框,给目标框 2 分配 4个候选框。

torch.clamp 就是把每个真实框最少分配一个目标(min=1),参考:

https://blog.csdn.net/hb_learing/article/details/115696206


step3: Sinkhorn-Knopp Iteration 求解 cost 矩阵获得 标签分配方案

有了cost 矩阵 c,supplying vector s∈Rm+1s∈R^{m+1}s∈Rm+1, demanding vector d∈Rnd∈R^nd∈Rn,因此可以通过现有的 Sinkhorn-Knopp Iteration [5]来求解该 OT 问题,从而得到最优运输方案 π∗∈R(m+1)×nπ^∗∈R^{(m+1)×n}π∗∈R(m+1)×n。

在得到 π∗π^∗π∗ 之后,将每个 anchor 分配给运送 labels 量最大的 supplier(真实框) ,从而解码出相应的标签分配方案。


step3:得到 matching_matrix(SimOTA 使用的)

for gt_idx in range(num_gt):_, pos_idx = torch.topk(cost[gt_idx], k=dynamic_ks[gt_idx], largest=False)matching_matrix[gt_idx][pos_idx] = 1

针对每个目标框挑选相应的 cost 值最低的一些候选框。比如右面的matching_matrix 中,cost值最低(largest=False)的一些位置,数值为1,其余位置都为0。

因为目标框1和3,dynamic_ks 值都为3,因此matching_matrix的第一行和第三行,有3个1。而目标框2,dynamic_ks值为4,因此matching_matrix的第二行,有4个1。

step4:过滤共用的候选框

这一步就是论文中所谓的考虑了全局信息的意思吧。

anchor_matching_gt = matching_matrix.sum(0)
if (anchor_matching_gt > 1).sum() > 0:_, cost_argmin = torch.min(cost[:, anchor_matching_gt > 1], dim=0)matching_matrix[:, anchor_matching_gt > 1] *= 0matching_matrix[cost_argmin, anchor_matching_gt > 1] = 1

matching_matrix 中第5列有两个1,这说明第5列所对应的候选框,被目标检测框1和2 都进行关联

因此对这两个位置,还要使用 cost值 进行对比,选择较小的值,再进一步筛选。假设第5列两个位置的值分别为0.4和0.3。

经过第三行代码,可以找到最小的值是0.3,即cost_min为0.3,所对应的行数,cost_argmin为2。

经过第四行代码,将matching_matrix第5列都置0。

再利用第五行代码,将matching_matrix第2行,第5列的位置变为1。

最终我们可以得到3个目标框,最合适的一些候选框,即matching_matrix中,所有1所对应的位置。

看来 cost 最低是这个算法的核心。并且也解决了冲突问题。太强了


OTA 和 SimOTA 区别:

从上面描述可知,OTA 和 SimOTA 都是在经过 step2:dynamic_k_estimation 后,OTA 使用的是 Sinkhorn-Knopp Iteration 求解 cost 矩阵来获得最优的标签分配结果。SimOTA 是采用定义的规则使用 torch.topk 根据 dynamic_k_estimation 得到的 k ,选择 k 个 cost 最小的值,作为分配给真实框的 候选框。

因此,SimOTA 有两个 topk :1. step2:dynamic_k_estimation 中的选择比如 10 个 topk_ious。 2. 根据动态获得的 k 选择 k 个候选框。

OTA 只有 step2:dynamic_k_estimation 中的选择比如 10 个 topk_ious。

据我目前的认识,第 4 步两者都是需要的。目前的疑问:OTA 是否需要第 5 步 去掉歧义的候选框还不太清楚。需要调试源码,但是我也不想调。

参考:

OTA的topk用来筛选candidates,是用来求dynamic k过程中使用的,最终的正样本划分有sinkhorn-knopp iter求解得到。SimOTA拿到dynamic k之后,最终正负样本划分依然是greedy的topk
https://github.com/Megvii-BaseDetection/YOLOX/issues/859

代码细节:https://blog.csdn.net/jiaoyangwm/article/details/126638775

2. OTA效果性能

(2)r 的影响

OTA方法通常用于精筛选正样本,在精筛选正样本前,可以增加一步粗筛选,有2种方式:

  • 筛选中心点落在 ground truth bbox 范围内的 anchor 作为正样本;
  • 筛选中心点落在以 ground truth bbox 中心点为中心,r为半径的区域内的anchor 作为正样本;(论文中提到的 Center Prior.中心先验)

在粗筛选的结果基础上,再使用OTA方法,可以减少运算量和提高精度。

将 r 设置成 3, 5, 7 后,得到粗筛选候选框数量分别为 45,125 和 245。将 OTAATSSPAA 方法作比较,得到2个结论:

  • 歧义 anchors 样本 ambiguous anchors(一个 anchor 可能对应多个gt)数量 NambN_{amb}Namb​ 越多,相应的 AP 会下降,说明 歧义样本 会对网络训练产生负面影响;
  • 分配到 歧义样本 的数量:ATSS > PAA > OTA;
  • 对 r 的敏感性:ATSS > PAA > OTA

上面说明 OTA 比 ATSS 和 PAA 要好!

(3)k 的影响

在使用 Sinkhorn-Knopp 算法前,需要知道每个 gt 需要提供多少 positive label,posivtive label 的数量就是 k ,如下比较了将 k 设置成固定值和动态值的情形,论文提出的 dynamic k 方法可有效提高 AP值。

3. 总结

OTA 论文的主要贡献包括以下几点:

  • 提出解决目标检测中的标签分配问题的新思路:当作 OT (Optimal Transport problem) 问题来处理;
  • 提出计算每个gt需要提供多少 positive label 的方法,该方法简单有效;dynamic k
  • 分析了歧义样本的影响,ambiguous anchors 会对网络训练产生负面影响,OTA方法可以有效的减少歧义样本的数量。

目标检测标签分配之 OTA 和 SimOTA 细节学习相关推荐

  1. ECCV 2022 | RFLA:基于高斯感受野的微小目标检测标签分配

    前言 在本文中,作者提出了一种基于高斯感受野的标签分配(RFLA)策略用于微小目标检测.并提出了一种新的感受野距离(RFD)来直接测量高斯感受野和地面真值之间的相似性,而不是使用IoU或中心采样策略分 ...

  2. 基于语义分割Ground Truth(GT)转换yolov5目标检测标签(路面积水检测例子)

    基于语义分割Ground Truth(GT)转换yolov5目标检测标签(路面积水检测例子) 概述 许多目标检测的数据是通过直接标注或者公开平台获得,如果存在语义分割Ground Truth的标签文件 ...

  3. 【目标检测】36、OTA: Optimal Transport Assignment for Object Detection

    文章目录 一.背景 二.方法 2.1 Optimal Transport 2.2 OT for label assignment 2.3 Center prior 2.4 Dynamic k Esti ...

  4. VPGNet数据集解析且将分割标签转化为目标检测标签

    VPGNet交通标志数据集 VPGNet是一个包含了四个场景(晴天,夜间,阴雨等)下的交通路况数据集,其主要是针对地面标志(箭头线,人行道)的任务,该数据集一共包括以下17类地面标注 {0:'back ...

  5. 【我的第一个目标检测课题】3、Retinanet网络的学习与实现+扩展

    2021.1.7下午记 大家新年好~ 距离上次写这个课题的博客已经是去年12.30的时候了,是想趁热打铁赶快写的,无奈1.5/1.6有两门考试,便只好赶去复习暂时搁置了.现在终于考完试,而且也马上到了 ...

  6. 基于PyTorch深度学习遥感影像地物分类与目标检测、分割及遥感影像问题深度学习优化

    我国高分辨率对地观测系统重大专项已全面启动,高空间.高光谱.高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源.未来10年全球每天获取的观测 ...

  7. PyTorch深度学习遥感影像地物分类与目标检测、分割及遥感影像问题深度学习优化

    我国高分辨率对地观测系统重大专项已全面启动,高空间.高光谱.高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源.未来10年全球每天获取的观测 ...

  8. 目标检测的二十年发展史—从传统方法到深度学习

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要15分钟 Follow小博主,每天更新前沿干货 本文转载自DeepBlue深兰科技 本文主要参考自文献[1]:Zhengxia Zou, Zh ...

  9. 目标检测,FFmpeg中第一个基于深度学习模型的视频分析功能

    2021年4月,终于把目标检测(object detection)加到FFmpeg upstream了,有maintainer身份加持,还是交互了将近100封邮件,花了两个多月才完成upstream, ...

  10. 目标检测标签文件txt转成xml

    最近在用ppyolo训练好的模型对新采集的数据进行标记,再人工微调,减少从头打标签的时间,但是推理保存的结果都是txt格式的,想要在labelimg中可视化,那就需要将txt转换成xml. 以下代码即 ...

最新文章

  1. 语义分割:最简单的代码实现!
  2. 《Redis入门指南(第2版)》一3.2 字符串类型
  3. Xcode代码文件模板
  4. 一篇文章带你了解APP PUSH推送机制
  5. 浅谈Base64编码[转]
  6. 使用Github Actions构建、发布和部署NuGet软件包
  7. pandas python groupby_python – pandas groupby方法实际上是如何工作的?
  8. 自定义autograd function
  9. 基于阿里云上实现全站https
  10. thinkphp 表单令牌
  11. c语言CRC16校验(8005)
  12. iOS蓝牙开发(三)实现外设功能
  13. 深入浅出Embedding
  14. 什么是搜索引擎???搜索引擎的介绍
  15. 如何批量重命名文件夹,自定义修改文件夹的名称
  16. C语言的文件打开(多种方式),读写,关闭,文件指针偏移等操作,理解读写原理
  17. MAC 键盘快捷键符号图例
  18. jmeter线程说明_Jmeter-常用线程组设置及场景运行时间计算
  19. Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)
  20. html5 3d柱形,Highcharts 3D柱形图

热门文章

  1. js系列七:生命周期
  2. net_device_ops的ndo_open和ndo_start_xmit函数
  3. php做支付宝接口测试,支付宝接口调试经验总结
  4. Beautiful Soup
  5. 动画效果--漫天飞雪
  6. 深度剖析 string —— memset memcmp
  7. 32位 shell.efi x86_EFI Shell 命令参考
  8. win10系统联想电脑亮度自动调节怎么办?
  9. html中fixed属性,CSSposition属性中:fixed使用详解
  10. odoo使用word中的MERGEFIELD合并域和python包mailmerge来生成word文档