Innersiou损失函数
设计原理
IoU(Intersection over Union)是用于评估物体检测算法性能的常用指标,它衡量了预测边界框和真实边界框之间的重叠程度。然而,IoU存在一些局限性,例如在处理高度重叠的物体时,IoU难以提供足够的区分度。为了解决这个问题,Inner SIoU(Inner Section over Union)被提出作为一种改进的损失函数,用于训练物体检测模型。
一、IoU的局限性
IoU是通过计算两个边界框的交集面积除以它们的并集面积来衡量它们的重叠程度。但是,当两个边界框高度重叠时,IoU可能无法提供足够的区分度,导致难以准确地评估物体检测算法的性能。
二、Innersiou的引入
Inner SIoU是一种改进的损失函数,它通过考虑边界框内部区域的重叠情况来提高重叠边界框的区分度。Inner SIoU的计算方式如下:
- 首先,计算两个边界框的交集面积。
- 然后,计算第一个边界框的面积。
- 最后,将交集面积除以第一个边界框的面积得到Inner SIoU。
计算步骤
假设有两个边界框A和B,它们的坐标分别为(x1, y1, x2, y2)和(x3, y3, x4, y4)。则Inner SIoU的计算步骤如下:
-
计算两个边界框的交集面积:
- 交集区域的左上角坐标为(max(x1, x3), max(y1, y3))。
- 交集区域的右下角坐标为(min(x2, x4), min(y2, y4))。
- 交集区域的宽度为max(0, right - left),高度为max(0, bottom - top)。
- 交集面积为交集区域的宽度乘以高度。
-
计算第一个边界框的面积:
- 第一个边界框的宽度为x2 - x1,高度为y2 - y1。
- 第一个边界框的面积为宽度乘以高度。
-
计算Inner SIoU:
- Inner SIoU为交集面积除以第一个边界框的面积。
使用PyTorch实现Inner SIoU计算的源代码
import torch
def calculate_inner_siou(box1, box2):
# box1: [x1, y1, x2, y2]
# box2: [x3, y3, x4, y4]
# 计算交集的左上角和右下角坐标
inter_left_top = torch.stack((torch.maximum(box1[0], box2[0]), torch.maximum(box1[1], box2[1])), dim=0)
inter_right_bottom = torch.stack((torch.minimum(box1[2], box2[2]), torch.minimum(box1[3], box2[3])), dim=0)
# 计算交集的宽度和高度
inter_width = torch.maximum(inter_right_bottom[0] - inter_left_top[0], torch.tensor(0.))
inter_height = torch.maximum(inter_right_bottom[1] - inter_left_top[1], torch.tensor(0.))
# 计算交集面积和第一个边界框的面积
inter_area = inter_width * inter_height
box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
# 计算Inner SIoU
inner_siou = inter_area / box1_area
return inner_siou
# 示例使用
box1 = torch.tensor([0., 0., 5., 5.]) # [x1, y1, x2, y2]
box2 = torch.tensor([2., 2., 7., 7.]) # [x3, y3, x4, y4]
inner_siou = calculate_inner_siou(box1, box2)
print(inner_siou.item()) # 打印Inner SIoU值
替换Inner SIoU损失函数(基于MMYOLO)
由于MMYOLO中没有实现Inner SIoU损失函数,所以需要在mmyolo/models/iou_loss.py中添加Inner SIoU的计算和对应的iou_mode,修改完以后在终端运行
python setup.py install
再在配置文件中进行修改即可。修改例子如下:
elif iou_mode == "innersiou":
ratio=1.0
w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
x1 = bbox1_x1 + w1_
y1 = bbox1_y1 + h1_
x2 = bbox2_x1 + w2_
y2 = bbox2_y1 + h2_
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.mi