YOLOv9改进策略【损失函数篇】| 利用MPDIoU,加强边界框回归的准确性

本文主要是介绍YOLOv9改进策略【损失函数篇】| 利用MPDIoU,加强边界框回归的准确性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、背景

  1. 目标检测和实例分割中的关键问题
    • 现有的大多数边界框回归损失函数在不同的预测结果下可能具有相同的值,这降低了边界框回归的收敛速度和准确性。
  2. 现有损失函数的不足
    • 现有的基于 ℓ n \ell_n n范数的损失函数简单但对各种尺度敏感。
    • 当预测框与真实框具有相同的宽高比但不同的宽度和高度值时,现有损失函数可能会存在问题,限制了收敛速度和准确性。

文章目录

  • 一、背景
  • 二、原理
    • 2.1 IoU计算原理
    • 2.2. 基于最小点距离的IoU度量
    • 2.3. 作为边界框回归损失函数
    • 2.4 MPDIoU的计算公式
  • 三、添加步骤
    • 3.1 utils\metrics.py
    • 3.2 修改utils\loss_tal_dual.py
  • 四、总结


MPDIoU(Intersection over Union with Minimum Points Distance)是一种用于高效且准确的边界框回归的损失函数。

二、原理

2.1 IoU计算原理

IoU(Intersection over Union)即交并比,用于衡量预测边界框和真实边界框的重合程度。

1. 交集计算:
- 首先确定预测边界框和真实边界框的交集区域。
- 对于两个以左上角和右下角坐标表示的矩形框,分别找出它们在横坐标和纵坐标方向上的重叠区间。
- 如果两个矩形框在横坐标和纵坐标方向上都有重叠部分,那么这个重叠区域就是一个矩形,其面积就是交集的大小。
2. 并集计算:
- 计算预测边界框和真实边界框的并集区域。
- 并集的大小等于两个矩形框各自的面积之和减去它们的交集面积。
3. 比值计算:
- 最后,IoU的值就是交集面积与并集面积的比值。

2.2. 基于最小点距离的IoU度量

  • 原论文中受水平矩形的几何特性启发,设计了一种基于最小点距离的新型IoU度量MPDIoU,直接最小化预测边界框和真实边界框的左上角和右下角点之间的距离。
  • MPDIoU的计算通过两个任意凸形状 A A A B B B,用其左上角和右下角点的坐标来表示,通过计算两个框的交集与并集之比,再减去左上角和右下角两点距离的归一化值来得到MPDIoU

2.3. 作为边界框回归损失函数

  • 在训练阶段,通过最小化基于MPDIoU的损失函数 L M P D I o U = 1 − M P D I o U L_{MPDIoU}=1-MPDIoU LMPDIoU=1MPDIoU,使模型预测的每个边界框 B p r d B_{prd} Bprd接近其真实框 B g t B_{gt} Bgt
  • 现有损失函数中的所有因素(如非重叠区域、中心点距离、宽高偏差等)都可以通过左上角和右下角两点的坐标确定,这意味着提出的 L M P D I o U L_{MPDIoU} LMPDIoU不仅考虑了这些因素,还简化了计算过程。

在这里插入图片描述

2.4 MPDIoU的计算公式

  1. MPDIoU的计算公式:

    • M P D I o U = A ∩ B A ∪ B − d 1 2 w 2 + h 2 − d 2 2 w 2 + h 2 MPDIoU=\frac{A\cap B}{A\cup B}-\frac{d_{1}^{2}}{w^{2}+h^{2}}-\frac{d_{2}^{2}}{w^{2}+h^{2}} MPDIoU=ABABw2+h2d12w2+h2d22
    • 其中 A A A B B B是两个任意凸形状, ( x A 1 , y A 1 ) (x_{A1}, y_{A1}) (xA1,yA1) ( x A 2 , y A 2 ) (x_{A2}, y_{A2}) (xA2,yA2)表示(A)的左上角和右下角点坐标, ( x B 1 , y B 1 ) (x_{B1}, y_{B1}) (xB1,yB1) ( x B 2 , y B 2 ) (x_{B2}, y_{B2}) (xB2,yB2)表示 B B B的左上角和右下角点坐标。
    • d 1 2 = ( x 1 B − x 1 A ) 2 + ( y 1 B − y 1 A ) 2 d_{1}^{2}=(x_{1}^{B}-x_{1}^{A})^{2}+(y_{1}^{B}-y_{1}^{A})^{2} d12=(x1Bx1A)2+(y1By1A)2 d 2 2 = ( x 2 B − x 2 A ) 2 + ( y 2 B − y 2 A ) 2 d_{2}^{2}=(x_{2}^{B}-x_{2}^{A})^{2}+(y_{2}^{B}-y_{2}^{A})^{2} d22=(x2Bx2A)2+(y2By2A)2
  2. 基于MPDIoU的损失函数计算公式:

    • L M P D I o U = 1 − M P D I o U L_{MPDIoU}=1-MPDIoU LMPDIoU=1MPDIoU

三、添加步骤

3.1 utils\metrics.py

此处需要查看的文件是utils\metrics.py

metrics.py中定义了模型的损失函数和计算方法,我们想要加入新的损失函数就只需要将代码放到这个文件内即可。YOLOv9原模型中使用的是CIoU,并且在原YOLOv9的代码中已经实现了MPDIoU的代码,

MPDIoU的代码在utils\metrics.py的第254行,如下:

def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, MDPIoU=False, feat_h=640, feat_w=640, eps=1e-7):# Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4)# Get the coordinates of bounding boxesif xywh:  # transform from xywh to xyxy(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 / 2b1_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_else:  # x1, y1, x2, y2 = box1b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, -1)b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, -1)w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + epsw2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps# Intersection areainter = (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 Areaunion = w1 * h1 + w2 * h2 - inter + eps# IoUiou = inter / unionif CIoU or DIoU or GIoU:cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # convex (smallest enclosing box) widthch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # convex heightif CIoU or DIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = cw ** 2 + ch ** 2 + eps  # convex diagonal squaredrho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4  # center dist ** 2if CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)with torch.no_grad():alpha = v / (v - iou + (1 + eps))return iou - (rho2 / c2 + v * alpha)  # CIoUreturn iou - rho2 / c2  # DIoUc_area = cw * ch + eps  # convex areareturn iou - (c_area - union) / c_area  # GIoU https://arxiv.org/pdf/1902.09630.pdfelif MDPIoU:d1 = (b2_x1 - b1_x1) ** 2 + (b2_y1 - b1_y1) ** 2d2 = (b2_x2 - b1_x2) ** 2 + (b2_y2 - b1_y2) ** 2mpdiou_hw_pow = feat_h ** 2 + feat_w ** 2return iou - d1 / mpdiou_hw_pow - d2 / mpdiou_hw_pow  # MPDIoUreturn iou  # IoU

在这里插入图片描述

3.2 修改utils\loss_tal_dual.py

utils\loss_tal_dual.py是损失函数的辅助分支+主分支损失计算文件。

utils\loss_tal_dual.py的75行处修改成如下代码,使模型调用此MPDIoU损失函数。


iou = bbox_iou(pred_bboxes_pos, target_bboxes_pos, xywh=False, MPDIoU=True)

在这里插入图片描述

四、总结

当发现预测边界框和真实边界框具有相同的宽高比但不同的宽度和高度值时,MPDIoU损失函数比现有损失函数更有效,此时可以尝试将损失函数修改成MPDIoU查看效果。

这篇关于YOLOv9改进策略【损失函数篇】| 利用MPDIoU,加强边界框回归的准确性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to

SigLIP——采用sigmoid损失的图文预训练方式

SigLIP——采用sigmoid损失的图文预训练方式 FesianXu 20240825 at Wechat Search Team 前言 CLIP中的infoNCE损失是一种对比性损失,在SigLIP这个工作中,作者提出采用非对比性的sigmoid损失,能够更高效地进行图文预训练,本文进行介绍。如有谬误请见谅并联系指出,本文遵守CC 4.0 BY-SA版权协议,转载请联系作者并注

一种改进的red5集群方案的应用、基于Red5服务器集群负载均衡调度算法研究

转自: 一种改进的red5集群方案的应用: http://wenku.baidu.com/link?url=jYQ1wNwHVBqJ-5XCYq0PRligp6Y5q6BYXyISUsF56My8DP8dc9CZ4pZvpPz1abxJn8fojMrL0IyfmMHStpvkotqC1RWlRMGnzVL1X4IPOa_  基于Red5服务器集群负载均衡调度算法研究 http://ww