一、本文介绍
本文给大家带来的改进机制是InnerIoU以及包含其它二次创新的代码InnerCIoU、InnerMPDIoU等一些列利用Inner形成的二次创新损失函数,到此大家可能比较模糊为啥Inner能够和其他损失函数形成二次创新,Inner又是一个什么样的机制,开头这里给大家简单的说一下,假设CIoU的计算需要两个变量分别是A和B,Inner就是一种提取A和B的全新方法 | 替换的是传统的方法(算是比较新颖的方法去年年末提出的一种方法)。(该方法在处理非常小目标的检测任务时表现出良好的性能,但是在其它的尺度检测时也要比普通的损失要好)
专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏
目录
一、本文介绍
二、各种损失函数的基本原理
2.1 交集面积和并集面积
2.2 InnerIoU的思想
2.2.1结合InnerIoU各种损失函数的效果图
2.3 InnerSIoU
2.4 InnerGIoU
2.5 InnerDIoU
2.6 InnerEIoU
2.7 InnerCIoU
三、本文的核心代码
四、添加教程
4.1 步骤一
4.2 步骤二
4.3 步骤三
五、全文总结
二、各种损失函数的基本原理
论文地址:官方Inner-IoU论文地址点击即可跳转
官方代码地址:官方代码地址-官方只放出了两种结合方式CIoU、SIoU
本位改进地址: 文末提供完整代码块-包括InnerEIoU、InnerCIoU、InnerDIoU等七种结合方式和其Focus变种
2.1 交集面积和并集面积
在理解各种损失函数之前我们需要先来理解一下交集面积和并集面积,在数学中我们都学习过集合的概念,这里的交集和并集的概念和数学集合中的含义是一样的。
2.2 InnerIoU的思想
Inner-IoU(内部交并比)的主要思想是:改进目标检测中边界框回归(BBR)的准确性,特别是在处理高度重叠的目标时。传统的IoU(交并比)计算方法考虑了预测边界框和真实边界框的整体重叠区域,而Inner-IoU则专注于边界框内部的重叠部分。它通过引入辅助边界框,这些辅助框是原始边界框的缩小版本,来计算损失函数。
这种方法的优点包括:
- 针对性优化:Inner-IoU通过关注边界框的核心部分而非整体,提供了对重叠区域更加精确的评估。
- 调整尺度:通过控制辅助边界框的大小,Inner-IoU允许对不同的数据集和检测任务进行微调。
- 提高泛化能力:实验证明,Inner-IoU在不同的数据集上显示出比传统IoU更好的泛化性能。
- 处理高低IoU样本:对于高IoU样本,使用较小的辅助框可以加速模型学习;而对于低IoU样本,使用较大的辅助框可以改善回归性能。
总结:Inner-IoU是一种更细致、更专注于目标中心的性能评估指标,它通过辅助框的尺度调整提高了目标检测任务的精确度和效率。
2.2.1结合InnerIoU各种损失函数的效果图
上面的图片展示了CIoU 和 Inner-CIoU 方法。图中从左至右分别表示 CIoU 方法,以及不同比例(0.7、0.75 和 0.8)的 Inner-CIoU 方法的检测结果
这个图片可以看出这个Innner的思想在小目标检测的时候效果能够达到极致(最适用于小范围但是其它的情况也能够有效但是小目标是效果最好的情景)
PS:下面介绍的是融合的各种思想就是将其中的IoU替换为我们上面求出来的InnerIoU即可和其中的参数也替换为InnerIoU的思想,其中各种损失函数的本身思想并没有改变,只是改变了其中的 参数。
2.3 InnerSIoU
论文地址:SIoU: More Powerful Learning for Bounding Box Regression
适用场景:适用于需要高精度边界框对齐的场景,如精细的物体检测和小目标检测。
概念:SIoU损失通过融入角度考虑和规模敏感性,引入了一种更为复杂的边界框回归方法,解决了以往损失函数的局限性,SIoU损失函数包含四个组成部分:角度损失、距离损失、形状损失和第四个未指定的组成部分。通过整合这些方面,从而实现更好的训练速度和预测准确性。
2.4 InnerGIoU
论文地址:GIoU: A Metric and A Loss for Bounding Box Regression
适用场景:适合处理有重叠和非重叠区域的复杂场景,如拥挤场景的目标检测。
概念:在IoU的基础上考虑非重叠区域,以更全面评估边界框
2.5 InnerDIoU
论文地址:DIoU: Faster and Better Learning for Bounding Box Regression
适用场景:适用于需要快速收敛和精确定位的任务,特别是在边界框定位精度至关重要的场景。
概念:结合边界框中心点之间的距离和重叠区域。
2.6 InnerEIoU
论文地址:EIoU:Loss for Accurate Bounding Box Regression
适用场景:可用于需要进一步优化边界框对齐和形状相似性的高级场景。
概念:EIoU损失函数的核心思想在于提高边界框回归的准确性和效率。它通过以下几个方面来优化目标检测:
1. 增加中心点距离损失:通过最小化预测框和真实框中心点之间的距离,提高边界框的定位准确性。
2. 考虑尺寸差异:通过惩罚宽度和高度的差异,EIoU确保预测框在形状上更接近真实框。
3. 结合最小封闭框尺寸:将损失函数与包含预测框和真实框的最小封闭框的尺寸相结合,从而使得损失更加敏感于对象的尺寸和位置。
EIoU损失函数在传统IoU基础上增加了这些考量,以期在各种尺度上都能获得更精确的目标定位,尤其是在物体大小和形状变化较大的场景中。
2.7 InnerCIoU
论文地址:CIoU:Enhancing Geometric Factors in Model Learning
适用场景:适合需要综合考虑重叠区域、形状和中心点位置的场景,如复杂背景或多目标跟踪。
概念:综合考虑重叠区域、中心点距离和长宽比。
三、本文的核心代码
核心代码的使用方式看章节四!
def xyxy2xywh(x):"""Convert bounding box coordinates from (x1, y1, x2, y2) format to (x, y, width, height) format where (x1, y1) is thetop-left corner and (x2, y2) is the bottom-right corner.Args:x (np.ndarray | torch.Tensor): The input bounding box coordinates in (x1, y1, x2, y2) format.Returns:y (np.ndarray | torch.Tensor): The bounding box coordinates in (x, y, width, height) format."""assert x.shape[-1] == 4, f"input shape last dimension expected 4 but input shape is {x.shape}"y = torch.empty_like(x) if isinstance(x, torch.Tensor) else np.empty_like(x) # faster than clone/copyy[..., 0] = (x[..., 0] + x[..., 2]) / 2 # x centery[..., 1] = (x[..., 1] + x[..., 3]) / 2 # y centery[..., 2] = x[..., 2] - x[..., 0] # widthy[..., 3] = x[..., 3] - x[..., 1] # heightreturn ydef bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, MDPIoU=False, Inner=False, ratio=0.7, 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 Inner:if not xywh:box1, box2 = xyxy2xywh(box1), xyxy2xywh(box2)(x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)b1_x1, b1_x2, b1_y1, b1_y2 = x1 - (w1 * ratio) / 2, x1 + (w1 * ratio) / 2, y1 - (h1 * ratio) / 2, y1 + (h1 * ratio) / 2b2_x1, b2_x2, b2_y1, b2_y2 = x2 - (w2 * ratio) / 2, x2 + (w2 * ratio) / 2, y2 - (h2 * ratio) / 2, y2 + (h2 * ratio) / 2# Intersection areainter = (b1_x2.minimum(b2_x2) - b1_x1.maximum(b2_x1)).clamp_(0) * \(b1_y2.minimum(b2_y2) - b1_y1.maximum(b2_y1)).clamp_(0)# Union Areaunion = w1 * h1 * ratio * ratio + w2 * h2 * ratio * ratio - inter + epselse:if 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
四、添加教程
本文代码提到的MPDIoU需要在另一篇文章进行修改一些细节内容,本文的内容以及默认大家修改了我的MPDIoU(不修改会报错)!
另一篇文章的链接:YOLOv9改进策略 | 损失函数篇 | 利用真实边界框损失之MPDIoU助力YOLOv9精度更上一层楼
4.1 步骤一
第一步我们需要先找到如下的文件'utils/metrics.py'(这里以YOLOv9的修改损失函数为例,GELAN的需要修改'utils/loss_tal.py'修改教程一致,本文以YOLOv9的为例)。
我们找到如下图所示的代码!
4.2 步骤二
步骤二我们用章节三中的核心代码完全替换上面4.1红框圈出的整个函数(注意是整个函数红框仅仅是圈出了部分的代码因为代码太多不可能全部圈出来)!
修改完的样子如下图所示!
4.3 步骤三
我们上面相当于以及在项目内添加了Inner等损失函数,下一部我们教的是大家如何开启Inner的损失函数!
我们需要找到如下的文件'utils/loss_tal_dual.py' 按照图示进行修改!
到此我们就修改完成了,上面步骤三以及开启了对应的损失函数机制!
五、全文总结
到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv9改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏(目前免费订阅,后期不迷路),关注后续更多的更新~
专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏