RT-DETR改进 | 2023 | InnerEIoU、InnerSIoU、InnerWIoU、InnerDIoU等二十余种损失函数

 

94ccc6bef2b24206b87f3ee12782cbfc.png论文地址:官方Inner-IoU论文地址点击即可跳转

官方代码地址:官方代码地址-官方只放出了两种结合方式CIoU、SIoU

本位改进地址: 文末提供完整代码块-包括InnerEIoU、InnerCIoU、InnerDIoU等七种结合方式和其AlphaIoU变种结合起来可以达到二十余种

76b2b57bfb8e42a48f5d449f49cc6266.png

一、本文介绍

本文给大家带来的是RT-DETR最新改进,为大家带来最近新提出的InnerIoU的内容同时用Inner的思想结合SIoU、WIoU、GIoU、DIoU、EIOU、CIoU等损失函数,形成 InnerIoU、InnerSIoU、InnerWIoU、等新版本损失函数,同时还结合了AIpha思想,形成的新的损失函数,其中Inner的主要思想是:引入了不同尺度的辅助边界框来计算损失,(该方法在处理非常小目标的检测任务时表现出良好的性能(但是在其它的尺度检测时也要比普通的损失要好)。文章会详细探讨这些损失函数如何提高RT-DETR在各种检测任务中的性能,包括提升精度、加快收敛速度和增强模型对复杂场景的适应性。

  RT-DETR改进专栏:RT-DETR专栏——持续复现各种顶会内容——论文收割机 

目录

一、本文介绍

二、各种损失函数的基本原理 

2.1 交集面积和并集面积

2.2 InnerIoU的思想 

2.2.1结合InnerIoU各种损失函数的效果图 

2.3 InnerSIoU

2.4 InnerWioU

2.5 InnerGIoU

2.6 InnerDIoU

2.7 InnerEIoU

2.8 InnerCIoU

三、InnerIoU等损失函数代码块

四、添加InnerIoU等损失函数到模型中

4.1 修改一

7.2 修改二

五、总结


 

二、各种损失函数的基本原理 

2.1 交集面积和并集面积

在理解各种损失函数之前我们需要先来理解一下交集面积和并集面积,在数学中我们都学习过集合的概念,这里的交集和并集的概念和数学集合中的含义是一样的。

2d28de8702034e14955f6834c19c3edb.png

2.2 InnerIoU的思想 

Inner-IoU(内部交并比)的主要思想是:改进目标检测中边界框回归(BBR)的准确性,特别是在处理高度重叠的目标时。传统的IoU(交并比)计算方法考虑了预测边界框和真实边界框的整体重叠区域,而Inner-IoU则专注于边界框内部的重叠部分。它通过引入辅助边界框,这些辅助框是原始边界框的缩小版本,来计算损失函数。

这种方法的优点包括:

  1. 针对性优化:Inner-IoU通过关注边界框的核心部分而非整体,提供了对重叠区域更加精确的评估。
  2. 调整尺度:通过控制辅助边界框的大小,Inner-IoU允许对不同的数据集和检测任务进行微调。
  3. 提高泛化能力:实验证明,Inner-IoU在不同的数据集上显示出比传统IoU更好的泛化性能。
  4. 处理高低IoU样本:对于高IoU样本,使用较小的辅助框可以加速模型学习;而对于低IoU样本,使用较大的辅助框可以改善回归性能。

总结:Inner-IoU是一种更细致、更专注于目标中心的性能评估指标,它通过辅助框的尺度调整提高了目标检测任务的精确度和效率。

2.2.1结合InnerIoU各种损失函数的效果图 

2e6e6efed9b14804a580d5bbac0ae0a4.png

上面的图片展示了CIoU 和 Inner-CIoU 方法。图中从左至右分别表示 CIoU 方法,以及不同比例(0.7、0.75 和 0.8)的 Inner-CIoU 方法的检测结果 

2f36900120fa4e448f733c79361ca299.png

这个图片可以看出这个Innner的思想在小目标检测的时候效果能够达到极致(最适用于小范围但是其它的情况也能够有效但是小目标是效果最好的情景) 

PS:下面介绍的是融合的各种思想就是将其中的IoU替换为我们上面求出来的InnerIoU即可和其中的参数也替换为InnerIoU的思想,其中各种损失函数的本身思想并没有改变,只是改变了其中的 参数。

2.3 InnerSIoU

论文地址:SIoU: More Powerful Learning for Bounding Box Regression

适用场景:适用于需要高精度边界框对齐的场景,如精细的物体检测和小目标检测。

概念:SIoU损失通过融入角度考虑和规模敏感性,引入了一种更为复杂的边界框回归方法,解决了以往损失函数的局限性,SIoU损失函数包含四个组成部分:角度损失、距离损失、形状损失和第四个未指定的组成部分。通过整合这些方面,从而实现更好的训练速度和预测准确性。

9817889f4fe140b7a914acf93773d538.png

 

2.4 InnerWioU

论文地址:WIoU: Bounding Box Regression Loss with Dynamic Focusing Mechanism

适用场景:适用于需要动态调整损失焦点的情况,如不均匀分布的目标或不同尺度的目标检测。

概念:引入动态聚焦机制的IoU变体,旨在改善边界框回归损失。

05b8bd2d7bcb4df7a0fa5c44c9201bf7.png

 

2.5 InnerGIoU

论文地址:GIoU: A Metric and A Loss for Bounding Box Regression

适用场景:适合处理有重叠和非重叠区域的复杂场景,如拥挤场景的目标检测。

概念:在IoU的基础上考虑非重叠区域,以更全面评估边界框

9ca4394b9cd74103b4100129a8eaf26c.png

 

2.6 InnerDIoU

论文地址:DIoU: Faster and Better Learning for Bounding Box Regression

适用场景:适用于需要快速收敛和精确定位的任务,特别是在边界框定位精度至关重要的场景。

概念:结合边界框中心点之间的距离和重叠区域。

48175f62983a4d0aba517180582a7060.png

 

2.7 InnerEIoU

论文地址:EIoU:Loss for Accurate Bounding Box Regression

适用场景:可用于需要进一步优化边界框对齐和形状相似性的高级场景。

概念:EIoU损失函数的核心思想在于提高边界框回归的准确性和效率。它通过以下几个方面来优化目标检测:

1. 增加中心点距离损失:通过最小化预测框和真实框中心点之间的距离,提高边界框的定位准确性。

2. 考虑尺寸差异:通过惩罚宽度和高度的差异,EIoU确保预测框在形状上更接近真实框。

3. 结合最小封闭框尺寸:将损失函数与包含预测框和真实框的最小封闭框的尺寸相结合,从而使得损失更加敏感于对象的尺寸和位置。

EIoU损失函数在传统IoU基础上增加了这些考量,以期在各种尺度上都能获得更精确的目标定位,尤其是在物体大小和形状变化较大的场景中。

0e140b7de1094bab8fc00a6a63ab54f3.png

 

 

2.8 InnerCIoU

论文地址:CIoU:Enhancing Geometric Factors in Model Learning

适用场景:适合需要综合考虑重叠区域、形状和中心点位置的场景,如复杂背景或多目标跟踪。

概念:综合考虑重叠区域、中心点距离和长宽比。

f08d2772845447058b1ede34d0042c38.png

 

三、InnerIoU等损失函数代码块

此代码块块的基础版本来源于Github的开源版本,我在其基础上将Inner的思想加入其中形成了各种Inner的思想同时融合各种改良版本的损失函数形成对应版本的InnerIoU、InnerCIoU等损失函数。

class Inner_WIoU_Scale:
    ''' monotonous: {
            None: origin v1
            True: monotonic FM v2
            False: non-monotonic FM v3
        }
        momentum: The momentum of running mean'''

    iou_mean = 1.
    monotonous = False
    _momentum = 1 - 0.5 ** (1 / 7000)
    _is_train = True

    def __init__(self, iou):
        self.iou = iou
        self._update(self)

    @classmethod
    def _update(cls, self):
        if cls._is_train: cls.iou_mean = (1 - cls._momentum) * cls.iou_mean + \
                                         cls._momentum * self.iou.detach().mean().item()

    @classmethod
    def _scaled_loss(cls, self, gamma=1.9, delta=3):
        if isinstance(self.monotonous, bool):
            if self.monotonous:
                return (self.iou.detach() / self.iou_mean).sqrt()
            else:
                beta = self.iou.detach() / self.iou_mean
                alpha = delta * torch.pow(gamma, beta - delta)
                return beta / alpha
        return 1


def bbox_iou(box1, box2, x1y1x2y2=True, ratio=1, inner_GIoU=False, inner_DIoU=False, inner_CIoU=False, inner_SIoU=False,
             inner_EIoU=False, inner_WIoU=False, alpha=1, gamma=0.5, scale=False, eps=1e-7):
    (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
    w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
    b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
    b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_
    # IoU       #IoU       #IoU       #IoU       #IoU       #IoU       #IoU       #IoU       #IoU       #IoU        #IoU
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)
    union = w1 * h1 + w2 * h2 - inter + eps

    # Inner-IoU      #Inner-IoU        #Inner-IoU        #Inner-IoU        #Inner-IoU        #Inner-IoU        #Inner-IoU
    inner_b1_x1, inner_b1_x2, inner_b1_y1, inner_b1_y2 = x1 - w1_ * ratio, x1 + w1_ * ratio, \
                                                         y1 - h1_ * ratio, y1 + h1_ * ratio
    inner_b2_x1, inner_b2_x2, inner_b2_y1, inner_b2_y2 = x2 - w2_ * ratio, x2 + w2_ * ratio, \
                                                         y2 - h2_ * ratio, y2 + h2_ * ratio
    inner_inter = (torch.min(inner_b1_x2, inner_b2_x2) - torch.max(inner_b1_x1, inner_b2_x1)).clamp(0) * \
                  (torch.min(inner_b1_y2, inner_b2_y2) - torch.max(inner_b1_y1, inner_b2_y1)).clamp(0)
    inner_union = w1 * ratio * h1 * ratio + w2 * ratio * h2 * ratio - inner_inter + eps

    inner_iou = inner_inter / inner_union  # inner_iou

    if scale:
        self = Inner_WIoU_Scale(1 - (inner_inter / inner_union))

    if inner_CIoU or inner_DIoU or inner_GIoU or inner_EIoU or inner_SIoU or inner_WIoU:
        cw = inner_b1_x2.maximum(inner_b2_x2) - inner_b1_x1.minimum(
            inner_b2_x1)  # convex (smallest enclosing box) width
        ch = inner_b1_y2.maximum(inner_b2_y2) - inner_b1_y1.minimum(inner_b2_y1)  # convex height
        if inner_CIoU or inner_DIoU or inner_EIoU or inner_SIoU or inner_WIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
            c2 = (cw ** 2 + ch ** 2) ** alpha + eps  # convex diagonal squared
            rho2 = (((inner_b2_x1 + inner_b2_x2 - inner_b1_x1 - inner_b1_x2) ** 2 + (
                    inner_b2_y1 + inner_b2_y2 - inner_b1_y1 - inner_b1_y2) ** 2) / 4) ** alpha  # center dist ** 2
            if inner_CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
                v = (4 / math.pi ** 2) * (torch.atan(w2 / h2) - torch.atan(w1 / h1)).pow(2)
                with torch.no_grad():
                    alpha_ciou = v / (v - inner_iou + (1 + eps))

                return inner_iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha))  # CIoU
            elif inner_EIoU:
                rho_w2 = ((inner_b2_x2 - inner_b2_x1) - (inner_b1_x2 - inner_b1_x1)) ** 2
                rho_h2 = ((inner_b2_y2 - inner_b2_y1) - (inner_b1_y2 - inner_b1_y1)) ** 2
                cw2 = torch.pow(cw ** 2 + eps, alpha)
                ch2 = torch.pow(ch ** 2 + eps, alpha)
      
                return inner_iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)  # EIou
            elif inner_SIoU:
                # SIoU Loss https://arxiv.org/pdf/2205.12740.pdf
                s_cw = (inner_b2_x1 + inner_b2_x2 - inner_b1_x1 - inner_b1_x2) * 0.5 + eps
                s_ch = (inner_b2_y1 + inner_b2_y2 - inner_b1_y1 - inner_b1_y2) * 0.5 + eps
                sigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)
                sin_alpha_1 = torch.abs(s_cw) / sigma
                sin_alpha_2 = torch.abs(s_ch) / sigma
                threshold = pow(2, 0.5) / 2
                sin_alpha = torch.where(sin_alpha_1 > threshold, sin_alpha_2, sin_alpha_1)
                angle_cost = torch.cos(torch.arcsin(sin_alpha) * 2 - math.pi / 2)
                rho_x = (s_cw / cw) ** 2
                rho_y = (s_ch / ch) ** 2
                gamma = angle_cost - 2
                distance_cost = 2 - torch.exp(gamma * rho_x) - torch.exp(gamma * rho_y)
                omiga_w = torch.abs(w1 - w2) / torch.max(w1, w2)
                omiga_h = torch.abs(h1 - h2) / torch.max(h1, h2)
                shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w), 4) + torch.pow(1 - torch.exp(-1 * omiga_h), 4)
    
                return inner_iou - torch.pow(0.5 * (distance_cost + shape_cost) + eps, alpha)  # SIou
            elif inner_WIoU:
                if scale:
                    return getattr(Inner_WIoU_Scale, '_scaled_loss')(self), (1 - inner_iou) * torch.exp(
                        (rho2 / c2)), inner_iou  # WIoU https://arxiv.org/abs/2301.10051
                else:
                    return inner_iou, torch.exp((rho2 / c2))  # WIoU v1
   
            return inner_iou - rho2 / c2  # DIoU
        c_area = cw * ch + eps  # convex area

        return inner_iou - torch.pow((c_area - inner_union) / c_area + eps,
                                     alpha)  # GIoU https://arxiv.org/pdf/1902.09630.pdf

    return inner_iou  # IoU

 

四、添加InnerIoU等损失函数到模型中

4.1 修改一

第一步我们需要找到如下的文件ultralytics/utils/metrics.py,找到如下的代码,下面的图片是原先的代码部分截图的正常样子,然后我们将上面的整个代码块将下面的整个方法(这里这是部分截图)内容全部替换。

e7a59a4795ac45e29c2ee02d373394e9.png

7.2 修改二

第二步我们找到另一个文件如下->"ultralytics/models/utils/loss.py",(注意这个文件和YOLOv8的修改内容不是一个!!!!)我们找到如下的代码块,我们就可以进行设置了,看到我这里以及将EIoU都设置成True了,并且引入了alpha的思想进行改进大家可以多进行尝试,同时我们使用Inner思想将其设置为True即可,此时使用的就是InnerEIoU。

87c091cd2c554bcdb9fa62effe0741c0.png

(这里暂时还不能使用Focus的思想!!!)

 

五、总结

 到此本文的正式分享内容就结束了,在这里给大家推荐我的RT-DETR改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,目前本专栏免费阅读(暂时,大家尽早关注不迷路~),如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

本专栏其它内容(持续更新) 

 RT-DETR改进专栏:RT-DETR专栏——持续复现各种顶会内容——论文收割机

3d51a0611af1442f833362eaf18fbae2.gif

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JAVA进阶之路JVM-1:jvm基本组成、java程序执行过程、java程序的跨平台、静态编译器、jvm执行方式

JVM基本组成 当线上系统突然宕机,系统无法访问,甚至直接OOM; 线上系统响应速度太慢,优化系统性能过程中发现CPU占用过高,原因也许是因为JVM的GC次数过于频繁 因此,新项目上线,需要设置JVM的各…

算法-技巧-中等-寻找重复数,环形链表|,||

记录一下算法题的学习13 这次代码中运用到的技巧是「Floyd 判圈算法」(又称龟兔赛跑算法),它是一个检测链表是否有环的算法 我们想象乌龟tortoise和兔子rabbit在链表上移动,乌龟爬的慢,兔子爬的快,当乌龟和…

Unity EventSystem的一些理解和使用

Unity的EventSystem是用于处理用户输入和交互的系统。它是Unity UI系统的核心组件之一,可以用于捕捉和分发各种事件,例如点击、拖拽、按键、射线等。 常用的属性和方法有以下这些: 属性: current: 获取当前的EventSystem实例。…

数据结构--->单链表

文章目录 链表链表的分类 单链表单链表的存储结构单链表主要实现的接口函数单链表尾插动态申请新节点单链表头插单链表的尾删单链表的头删在指定位置之前插入单链表查找插入 在指定位置之后插删除指定位置元素删除指定位置之后的元素顺序输出链表销毁单链表 顺序表和单链表的区…

随手写了个博客多平台发布脚本:Python自动发布文章到Wordpress

​ 引言 作为一名技术博主,提高博客发布效率是我们始终追求的目标。在这篇文章中,我将分享一个基于Python的脚本,能够实现博客多平台发布,具体来说,是自动发布文章到WordPress。通过这个简单而高效的脚本&#xff0c…

Android 单元测试初体验(二)-断言

[TOC](Android 单元测试初体验(二)-断言) 前言 当初在学校学安卓的时候,老师敢教学进度,翻到单元测试这一章节的时候提了两句,没有把单元测试当重点讲,只是说我们工作中几乎不会用到,果真在之前的几年工作当中我真的没…

人工智能与供应链行业融合:预测算法的通用化与实战化

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 让我们一起深入探索人工智能与供应链的融合,以及预测算法在实际应用中的价值!🔍🚀 文章目录 前言供应链预测算法的基本流程统计学习模型与机…

Gitea和Jenkins安装

Gitea Gitea:https://dl.gitea.com/gitea/1.21.0/ Jenkins:https://www.jenkins.io/download/ 数据库配置 可以参考官方文档-https://docs.gitea.cn/1.20/installation/database-prep,这里以MySQL作为讲解 MySQL 在数据库实例上&#xf…

LeetCode-面试题08.01 三步问题 C/C++实现 超详细思路及过程[E]

🎈归属专栏:深夜咖啡配算法 🚗个人主页:Jammingpro 🐟记录一句:摆了一个周末了,不能摆了,努力起来!! 文章目录 LeetCode-面试题08.01 三步问题🚗题…

SpringBoot : ch08 自动配置原理

前言 在现代的Java开发中,Spring Boot已经成为了一个备受欢迎的框架。它以其简化开发流程、提高效率和强大的功能而闻名,使得开发人员能够更加专注于业务逻辑的实现而不必过多地关注配置问题。 然而,你是否曾经好奇过Spring Boot是如何做到…

C++11线程以及线程同步

C11中提供的线程类std::thread,基于此类创建一个新的线程相对简单,只需要提供线程函数和线程对象即可 一.命名空间 this_thread C11 添加一个关于线程的命名空间std::this_pthread ,此命名空间中提供四个公共的成员函数; 1.1 get_id() 调用命名空间s…

识别验证码

背景 需求是要爬取某网站的数据, 已有账号密码, 但这个网站需要登录, 登录需要输入验证码 验证码样式如下 调研了Tesseract框架, 识别效果不佳. 后来使用ddddocr, 能正确识别. https://github.com/sml2h3/ddddocr 代码如下 def ocr():response requests.get(http://xxx/get…

【JavaScript】封装自己的JavaScript公共工具函数,并上传到npm中 进行下载

js公共方法封装方式都有哪些 全局函数 function greet(name) {console.log("Hello, " name "!"); }greet("Alice"); // 调用全局函数对象字面量 var utils {add: function(a, b) {return a b;},subtract: function(a, b) {return a - b;}…

使用opencv实现图片相似度检测

1.为什么学这个,我对图像处理非常感兴趣,我联想到海尔的指纹识别门锁是如何进行检测的,我在想不应该呀,单片机性能这么差,应该是使用了训练后的数据去检测图片的,如果我要实现草莓检测,知道它是不是草莓,我觉得单纯使用图片处理是不够的,我考虑过使用指纹模块来接触草莓从而实现…

芯片制程中温度的几种表示方法

在众多影响芯片制程的因素中,温度控制被视为一项至关重要的技术。温度是比较一种物质相对于另一种物质是冷还是热的衡量标准,它会影响到芯片的性能、可靠性以及最终产量。在不同的制程步骤中,温度扮演着各种各样的角色。但是在评价制程温度高…

振弦式轴力计和振弦采集仪组成的安全监测解决方案

振弦式轴力计和振弦采集仪组成的安全监测解决方案 振弦式轴力计和振弦采集仪是一种常用的结构安全监测工具,可以用于评估建筑物、桥梁、隧道或其他结构的结构健康状态和安全性能。这种监测方案较为先进、精确,并且能够监测长期的结构反应,因此…

Git指定分支或文件回退到指定版本

文章目录 一、分支回滚1.1、使用 git reset 命令1.2、使用 git revert 命令1.3、使用 git checkout 命令 二、文件回滚2.1、回滚未提交文件2.2、回滚已提交文件2.2.1、首先查看文件的历史版本2.2.2、找到你想要还原的版本2.2.3、将文件还原到你想要还原的版本2.2.4、提交代码 三…

便利高效双赢:无人机油气管道巡检全面升级

我国庞大的油气管道网络,包括原油、成品和天然气管道,因为地理区域广泛、建设年代久远、安全事故频发等现实因素,对管道的安全巡护与管理提出了更高的需求。在这一背景下,传统的人工巡护方式显然已经难以满足对高、精、准的要求。…

s_v_web_id或fp协议过签名,dy滑块

某音s_web_id或fp协议过签名 ‘h5_sdk_version’, ‘2.36.0’ "search_impr":{"entity_id":"1135137973613200"},"link_item_list":null,"user_permissions":null,"offline_info_list":null,"is_cf":…

计算机组成原理-页式存储器

文章目录 页式存储虚拟地址vs实地址页表:逻辑页->主存块号地址交换过程地址交换过程(增加TLB)总结 页式存储 把程序分散式地放到主存的不同块的地方 虚拟地址vs实地址 操作系统将逻辑地址映射到主存块中的物理地址,对应的物…