RT-DETR 详解之查询去噪( DeNoise)

2024-06-11 04:36
文章标签 详解 查询 rt detr denoise

本文主要是介绍RT-DETR 详解之查询去噪( DeNoise),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

前面我们已经讲解了RT-DETR的基本结构与Efficient Hybrid Encoder部分,在这篇博客里,博主将主要记录RT-DETR的第二个创新点:Uncertainty-minimal Query Selection

在这里插入图片描述

查询向量选择为什么重要?

关于 Query Selection(查询向量选择),大家应该并不陌生,这个方法可谓在DETR领域大杀四方,如DAB-DETR对查询向量进行重构理解,将其解释为AnchorDN-DETR通过查询降噪来应对匈牙利匹配的二义性所导致的训练时间长的问题,DINO提出从Encoder中选择Top-k特征进行学习等一系列方法,这都无疑向我们证明,查询向量很重要,选择好的Query能够让我们事半功倍。

RT-DETR改进查询选择的思路

在RT-DETR中,Query selection 的作用是从 Encoder 输出的特征序列中选择固定数量的特征作为 object queries ,其经过 Decoder 后由预测头映射为置信度和边界框。

前面已经说过,现有的 DETR 变体都是利用这些特征的分类分数直接选择 Top-K 特征。然而,由于分类分数和 IOU 分数的分布存在不一致,分类得分高的预测框并不一定是和 GT 最接近的框,这导致髙分类分数低 IOU 的框会被选中,而低分类分数高 IOU 的框会被丢弃,这将会损害检测器的性能。

因此,RT-DETR考虑通过在训练期间约束检测器对高 IOU 的特征产生高分类分数,对低 IOU 的特征产生低分类分数。故而,作者提出了 Iou-aware Query selection。从而使得模型根据分类分数选择的 Top-K 特征对应的预测框同时具有髙分类分数和高 IOU 分数。

那么,RT-DETR到底是怎么做的呢?大家且听我娓娓道来。

RT-DETR预处理特征

进入到Decoder中后,首先是对Encoder输入的特征进行一个特征融合,将原本的三层特征展平拼接,得到扁平特征。

Encoder输入特征:

在这里插入图片描述

扁平融合后的特征:

在这里插入图片描述

随后,便可以进行真正的Decoder中的运算了。
在讲解Uncertainty-minimal Query Selection之前,RT-DETR还做了一个DeNoise的操作,该方法并非是RT-DETR所提出的,但其在这里使用了,这个方法便是查询去噪方法。

查询去噪方法

denoising 方法并非是RT-DETR所提出的,其是由DN-DETR所提出的,用于改善由于匈牙利匹配的二义性所导致的模型训练收敛慢的问题,在这里,RT-DETR使用了,denoising是一个很好的创新点,并且也具有十分大的改进空间,大家在想创新点时可以考虑它。
其实,在博主先前的博客DN-DETR详解中,博主已经讲解过DeNoising的实现过程了,今天就带着大家回顾一遍:

参数讲解

首先关于DeNoising的相关参数,都是在rtdetr_r50中定义好的。

在这里插入图片描述

随后便是判断是否使用DeNoising,该方法只在训练时使用:

在这里插入图片描述

接着便是如何生成噪声查询向量了,该部分代码的实现在denoising.py中。

加噪思路

在讲解这部分代码前,大家可以看一下博主画的这张图,了解一下DeNoising的实现思路

在这里插入图片描述

噪声组设计

我们进入denosing.py文件中,首先看一下传入的参数
label_noise_ratio为类别添加噪声的比例,此处设置为0.5,即有一半的类别要改变

在这里插入图片描述

这块代码是十分具有代表性的

首先是确定每张图像中标注样本的个数,保存在num_gts中,随后选出最大的,这个是方便我们在后面划分组时使用,因为num_denoising的熟练为100,是我们确定好的,每个batch(批次)内划分创建噪声,因此,噪声组的数目num_group=num_denoising//max(num_gts)

在这里插入图片描述

随后,生成对应的输入类别,输入标注框以及真值掩膜,其维度为:

  • input_query_class:(4,11)第一个3代表batch大小,11为该batch内图像中标注样本的最大值
  • input_query_box:(4,11,4)最后一个四代表w,h,x,y
  • input_gt_mask:(4,11)真值掩膜

这里类别初始化值 num_class3,代表背景

在这里插入图片描述

为其赋予对应的值

在这里插入图片描述

其对应位置会被赋值(绿色),比如input_class则会是对应类别,mask则是True
在这里插入图片描述
随后开始创建噪声了,要分正负样本,还要分9组,所以为 2*9,这里用到了一个torch提供的函数:

tile函数(A,reps)

A:输入的数组(array
reps:数组A重复的次数;可以有两种形式(数字和二维元组)
tile的本意有“铺以瓷砖,铺以瓦”的意思,即将数组视为瓷砖,在一个平面上将此数组平铺开来(数字对应一维,元组对应二维 tuple(纵铺个数,横铺个数)
这里使用的是元组,即纵铺为1,横铺为2*9,这很好理解,其要生成的是很多batch

在这里插入图片描述
得到的变量对应维度为:

在这里插入图片描述

可以看到,此时input_query_class的值如下,其是按照图像来划分的,第一张图像中只有两个样本,因此每11个数中只有2个不为3,而第二张图像中有11个样本,则没有出现3

在这里插入图片描述

如下图所示(注意,这里我为方便显示,将设置num_group=3,则生成的样本组数为2*3=6)绿色代表有样本,白色代表无样本。

在这里插入图片描述

生成对应的正负样本掩膜,划分正负样本,隔一组切换一次正负样本。

在这里插入图片描述

生成的掩膜如下,黄色为正样本,红色为负样本,这意味着红色样本的标注框偏移,大小变化会更大,即噪声更大

在这里插入图片描述

将正负样本掩膜与标注位置掩膜结合,并获取每个正样本的坐标

在这里插入图片描述

dn_positive_idx的值如下:,我们以第一张图片为例,其内有2个标注,则在第一组正样本的坐标为0,1,第二组正样本为22,23,(中间隔了一个负样本组)

生成

添加类别噪声

接下来便是生成类别噪声了,首先是生成噪声比例的掩膜mask,随后根据掩膜生成随机类别new_label,最后判断判断input_query_class对应位置是不是应该添加噪声,最终生成噪声input_query_class

在这里插入图片描述

在这里插入图片描述

添加标注框噪声

添加标注框噪声,完整代码如下:

在这里插入图片描述

首先进行一个转换,因为原本的标注文件中给出的是中心点坐标与宽高的标注个数,我们先将其转变为左上和右下坐标,方便添加噪声。

在这里插入图片描述

diff是根据目标框的宽高获取一个缩放的比例,其维度为torch.Size([4, 198, 4]),其中使用宽高乘以0.5,能够保证将来中心点偏移不会超出原本的标注框。

 diff = torch.tile(input_query_bbox[..., 2:] * 0.5, [1, 1, 2]) * box_noise_scale

rand_sign是目标框位移的方向,torch.randint_like(input_query_bbox, 0, 2) * 2.0 - 1.0生成的值在-1到1之间,将其作用在坐标上,即可实现上下作用的平移
随后对正样本以及负样本添加不同程度的噪声区别:

 rand_part = (rand_part + 1.0) * negative_gt_mask + rand_part * (1 - negative_gt_mask)

将偏移方向(rand_sign)与缩放程度(diff)相乘可以得到两个坐标点偏移后的位置:

rand_part *= rand_sign
known_bbox += rand_part * diff

最终将偏移后的坐标转换为中心点宽高的形式,并构造查询向量:

 input_query_bbox = box_xyxy_to_cxcywh(known_bbox)input_query_bbox = inverse_sigmoid(input_query_bbox)

遮蔽掩膜设计

这是DN-DETR中最精巧的设计了,这个屏蔽掩膜是什么东西呢,其实是为了让真值加噪生成的查询向量与Encoder输入的查询向量有所区分,因为如果Decoder对上述两者不区分的话,虽然加噪组添加了噪声,但相比于Encoder输出的查询向量也是十分强的,这就会导致作弊,因此,加噪组查询向量与原始查询向量需要加以区分,而这个做法便是遮蔽掩膜,其实这个掩膜与前面噪声构造时的很相似。

同时,不同的噪声组之间也是需要相互屏蔽的。

在这里插入图片描述

如下图所示,绿色即为True,即为可见的,白色即为不可互相见的。
在这里插入图片描述

最终,加噪完成后得到的数据为:

在这里插入图片描述

在这里插入图片描述

至此,便完成了查询加噪的过程,随后这些查询向量会与Encoder输出的特征向量进行Uncertainty-minimal Query Selection操作,这个我们下一章再讲。

码字不易,给个赞呗。

这篇关于RT-DETR 详解之查询去噪( DeNoise)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1050211

相关文章

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

Python Faker库基本用法详解

《PythonFaker库基本用法详解》Faker是一个非常强大的库,适用于生成各种类型的伪随机数据,可以帮助开发者在测试、数据生成、或其他需要随机数据的场景中提高效率,本文给大家介绍PythonF... 目录安装基本用法主要功能示例代码语言和地区生成多条假数据自定义字段小结Faker 是一个 python

Java Predicate接口定义详解

《JavaPredicate接口定义详解》Predicate是Java中的一个函数式接口,它代表一个判断逻辑,接收一个输入参数,返回一个布尔值,:本文主要介绍JavaPredicate接口的定义... 目录Java Predicate接口Java lamda表达式 Predicate<T>、BiFuncti

详解如何通过Python批量转换图片为PDF

《详解如何通过Python批量转换图片为PDF》:本文主要介绍如何基于Python+Tkinter开发的图片批量转PDF工具,可以支持批量添加图片,拖拽等操作,感兴趣的小伙伴可以参考一下... 目录1. 概述2. 功能亮点2.1 主要功能2.2 界面设计3. 使用指南3.1 运行环境3.2 使用步骤4. 核

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的