YOLOv5 源码地址(使用的是6.1版本):GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
参考笔记:
YOLOv5改进实战 | 更换损失函数(三)之MPDIOU(2023最新IOU)篇-CSDN博客
MPDIoU: A Loss for Efficient and Accurate Bounding BoxRegression--论文学习笔记_mpdiou论文-CSDN博客
YOLOv5改进系列(七) 更换损失函数GIoU,DIoU,CIoU,EIoU,AlphaIoU,SIoU,WIoU_yolov5s eiou-CSDN博客
损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU超详细精讲及Pytorch实现-CSDN博客
YOLO 系列源码中默认使用的是 CIoU Loss
目录
1.EIoU(Efficient-IoU)
论文原文:《Focal and Efficient IOU Loss for Accurate Bounding Box Regression》
1.1 简介
EIOU 是在 CIOU 的惩罚项基础上将预测框和真实框的纵横比的影响因子拆开,分别计算预测框和真实框的长和宽,来解决 CIOU 存在的问题。这里我们先看一下 CIoU 的计算公式:
CIoU计算公式
说明:
(1)
:真实框的宽
:真实框的高
(2)
:预测框的宽
:预测框的高
(3)
:可以理解为对于预测框的高和宽的惩罚系数;
(4)
:用来衡量高宽比的一致性,当预测框与真实框的高和宽越接近时,
越接近于0
(5)
:预测框的中心点
:真实框的中心点
:两点之间的欧式距离
(6)
:预测框和真实框的最小外接矩形框的对角线长度
EIoU 包括三个部分:IoU损失、距离损失、高宽损失(重叠面积、中心点距离、高宽比)。高宽损失直接最小化了预测目标边界框和真实边界框的高度和宽度的差异,使其有更快的收敛速度和更好的定位结果
1.2 公式
其中 是预测框与真实框最小外接矩形框的宽度和高度,其他值与 1.1 中一致
1.3 Pytorch实现
#计算box1与box2的IoU
def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, EIoU=False, eps=1e-7):
box2 = box2.T
#获取边界框的坐标
if x1y1x2y2: # x1, y1, x2, y2 = box1
b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]
b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]
else:#将坐标值形式从xywh转换为xyxy
b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2
b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2
b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2
b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2
#交集面积
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)
#并集面积
w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps
w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps
union = w1 * h1 + w2 * h2 - inter + eps
#box1与box2的IoU值
iou = inter / union
if GIoU or DIoU or CIoU or EIoU:
cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) #最小外接矩形框的宽度
ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1) #最小外接矩形框的高度
if CIoU or DIoU or EIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
c2 = cw ** 2 + ch ** 2 + eps #最小外接矩形框的对角线长度的平方
rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 +
(b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 #中心点距离的平方
if DIoU:
return iou - rho2 / c2 # DIoU
elif CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
v = (4 / math.pi ** 2) * torch.pow(torc