YOLOv5基础知识入门(5)— 损失函数(IoU、GIoU、DIoU、CIoU和EIoU)

news2025/1/16 2:37:03

前言:Hello大家好,我是小哥谈。使用YOLOv5训练模型阶段,需要用到损失函数。损失函数是用来衡量模型预测值和真实值不一样的程度,极大程度上决定了模型的性能。本节就给大家介绍IoU系列损失函数,希望大家学习之后能够有所收获!🌈

前期回顾:

           YOLOv5基础知识入门(1)— YOLO算法的发展历程

           YOLOv5基础知识入门(2)— YOLOv5核心基础知识讲解

           YOLOv5基础知识入门(3)— 目标检测相关知识点

           YOLOv5基础知识入门(4)— 神经网络的基本概念与原理

           目录

🚀1.损失函数简介

🚀2.IoU

🚀3.GIoU

🚀4.DIoU

🚀5.CIoU

🚀6.EIoU

🚀7.总结

🚀1.损失函数简介

损失函数(loss function)是用于衡量模型预测结果真实结果之间的差距。损失函数通常是一标量函数,其值越小表示模型的预测结果越接近真实结果,反之则表示预测结果与真实结果之间的差距越大。🎈

使用YOLOv5训练模型的时候,我们需要不断地调整模型的参数,使得模型的预测结果和真实结果之间的差距最小化,损失函数在这个过程中起到了关键的作用。它可以帮助我们衡量模型的预测结果与真实结果之间的差距,并将这个差距转化为一个标量值。我们可以使用这个标量值来评估模型的性能,并根据这个标量值来调整模型的参数。🍓

YOLOv5损失函数包括:

  • classification loss,分类损失
  • localization loss,定位损失(预测边界框与GT之间的误差)
  • confidence loss,置信度损失(框的目标性;objectness of the box)

总体损失函数:Loss = a*classification loss + b*localization loss + c*confidence los 

也即总体损失函数为三个损失函数的加权和,通常置信度损失函数取最大权重,矩形框损失函数和分类损失的权重次之。🌷


🚀2.IoU

IoU(Intersection over Union),为两个方框相交区域面积相并区域面积的比值,所以也称为交并比。❤️

🍀计算公式:

🍀不足之处:

具体如下图所示:👇

(1)即状态1的情况,当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近,此时损失函数不可导,IOU_Loss无法优化两个框不相交的情况。 🍬

(2)即状态2状态3的情况,当两个预测框大小相同,两个IOU也相同,IOU_Loss无法区分两者相交情况的不同。因此2019年出现了GIOU_Loss来进行改进。 🍬

 🍀Pytorch代码:

def IoU(box1, box2):
    b1_x1, b1_y1, b1_x2, b1_y2 = box1
    b2_x1, b2_y1, b2_x2, b2_y2 = box2
    
    xx1 = np.maximum(b1_x1, b2_x1)
    yy1 = np.maximum(b1_y1, b2_y1)
    xx2 = np.minimum(b1_x2, b2_x2)
    yy2 = np.minimum(b1_y2, b2_y2)
    
    w = np.maximum(0.0, yy2 - yy1)
    h = np.maximum(0.0, xx2 - xx1)
 
    inter = w * h
    IoU = inter/((b1_x2-b1_x1)*(b1_y2-b1_y1) + (b2_x2-b2_x1)*(b2_y2-b2_y1) - inter)
    print("IoU: ", IoU)
 
 
if __name__ == "__main__":
    box1 = np.array([100, 100, 210, 210])
    box2 = np.array([150, 150, 230, 220])
    IoU(box1, box2)

🚀3.GIoU

GIOU(Generalized-IoU),GIoU比IoU多了一个“Generalized”,能在更广义的层面上计算IoU。当检测框和真实框没有出现重叠的时候IoU的loss都是一样的,因此GIoU就引入了最小封闭形状C(C可以把A,B包含在内),在不重叠情况下能让预测框尽可能朝着真实框前进,这样就可以解决检测框和真实框没有重叠的问题 。🍁

🍀计算公式:

如上图所示,GIOU在IOU的基础上,把包围矩形框A和矩形框B的最小矩形框(图中的虚线框)的面积也加入到计算中。🔖

GIOU可按下式计算,其中S1为A、B相交部分的面积(红色区域)。其中S3为包围A、B的最小矩形框的面积,S2为A、B相并区域的面积(蓝色+红色+灰色区域)。🗼

由上式可知GIOU相比IOU,新增了(S3-S2)/S3这一项。新增项表示什么意义呢?❓❓❓

由上述可知S3-S2为虚线框中白色区域的面积,也即虚线框中不属于A也不属于B的空白区域,那么(S3-S2)/S3就是空白区域面积占虚线框面积的比例,这个比例越大说明A、B距离越远、重叠度越小,反之则A、B距离越近、重叠度越大。📬

GIOU的取值范围是-1~1,当A、B完全没有重叠区域时IOU为0,那么GIOU取负值,极端情况,当A、B无重叠区域且距离无限远时,此时(S3-S2)/S3等于1,那么GIOU取-1;另一个极端情况,当A、B完全重叠时(S3-S2)/S3等于0,IOU为1,那么GIOU取1。🌻

因此,GIOU解决了当A、B完全没有重叠区域时IOU恒为0的问题。

最后得到GIOU loss的计算公式:

🍀不足之处:

状态1、2、3都是预测框在目标框内部且预测框大小一致的情况,这时预测框和目标框的差集都是相同的,因此这三种状态的GIOU值也都是相同的,这时GIOU退化成了IOU,无法区分相对位置关系。 基于这个问题,2020年的AAAI又提出了DIOU_Loss。

🍀Pytorch代码:

def GIoU(box1, box2):
    b1_x1, b1_y1, b1_x2, b1_y2 = box1
    b2_x1, b2_y1, b2_x2, b2_y2 = box2
    
    # IOU
    xx1 = np.maximum(b1_x1, b2_x1)
    yy1 = np.maximum(b1_y1, b2_y1)
    xx2 = np.minimum(b1_x2, b2_x2)
    yy2 = np.minimum(b1_y2, b2_y2)
    inter_w = np.maximum(0.0, yy2 - yy1)
    inter_h = np.maximum(0.0, xx2 - xx1)
    inter = inter_w * inter_h
    Union = (b1_x2-b1_x1)*(b1_y2-b1_y1) + (b2_x2-b2_x1)*(b2_y2-b2_y1) - inter
 
    # GIOU
    C_xx1 = np.minimum(b1_x1, b2_x1)
    C_yy1 = np.minimum(b1_y1, b2_y1)
    C_xx2 = np.maximum(b1_x2, b2_x2)
    C_yy2 = np.maximum(b1_y2, b2_y2)
    C_area = (C_xx2 - C_xx1) * (C_yy2 - C_yy1)
 
    IOU = inter / Union
    GIOU = IOU - abs((C_area-Union)/C_area)
    print("GIOU:", GIOU)
 
if __name__ == "__main__":
    box1 = np.array([100, 100, 210, 210])
    box2 = np.array([150, 150, 230, 220])
    GIoU(box1, box2)

🚀4.DIoU

DIoU(Distance-IoU),考虑到GIoU的缺点,也是增加了C检测框,将真实框和预测框都包含了进来,但是DIoU计算的不是框之间的交并,而是计算的每个检测框之间的欧氏距离。DIoU要比GIou更加符合目标框回归的机制,将目标与anchor之间的距离,重叠率以及尺度都考虑进去,使得目标框回归变得更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题。🌳

 🍀计算公式:

DIOU把矩形框A、B的中心点距离ρ、外接矩形框(虚线框)的对角线长度c都直接考虑进去,如下图所示:👇

DIOU可按下式计算:

由上式可知DIOU的取值范围也为-1~1,当两个框A、B完全重合时DIOU取1,当A、B距离无限远时,DIOU取-1。

从而得到DIOU loss的计算公式:

 🍀不足之处:

DIoU考虑了重叠面积和中心点距离,当目标框包裹预测框的时候,直接度量2个框的距离,因此DIoU收敛的更快,但并没有考虑到长宽比。💞

 🍀Pytorch代码:

def DIoU(box1, box2):
    b1_x1, b1_y1, b1_x2, b1_y2 = box1
    b2_x1, b2_y1, b2_x2, b2_y2 = box2
    
    # IOU
    xx1 = np.maximum(b1_x1, b2_x1)
    yy1 = np.maximum(b1_y1, b2_y1)
    xx2 = np.minimum(b1_x2, b2_x2)
    yy2 = np.minimum(b1_y2, b2_y2)
    inter_w = np.maximum(0.0, xx2 - xx1)
    inter_h = np.maximum(0.0, yy2 - yy1)
    inter = inter_w * inter_h
    Union = (b1_x2 - b1_x1)*(b1_y2 - b1_y1) + (b2_x2 - b2_x1)*(b2_y2 - b2_y1) - inter
 
    # DISTANCE
    C_xx1 = np.minimum(b1_x1, b2_x1)
    C_yy1 = np.minimum(b1_y1, b2_y1)
    C_xx2 = np.maximum(b1_x2, b2_x2)
    C_yy2 = np.maximum(b1_y2, b2_y2)
    C_area = (C_xx2 - C_xx1) * (C_yy2 - C_yy1)
 
    center_b_x = (b1_x1+b1_x2)/2
    center_b_y = (b1_y1+b1_y2)/2
    center_gtb_x = (b2_x1+b2_x2)/2
    center_gtb_y = (b2_y1+b2_y2)/2
 
    center_distance = (center_gtb_x-center_b_x)**2 + (center_gtb_y-center_b_y)**2
	c_distance = (C_xx2 - C_xx1)**2 + (C_yy2 - C_yy1)**2
	
    IOU = inter/Union
    DIOU = IOU - center_distance /c_distance
    print("DIOU:", DIOU)
 
if __name__ == "__main__":
    box1 = np.array([100, 100, 210, 210])
    box2 = np.array([150, 150, 230, 220])
    DIoU(box1, box2)

🚀5.CIoU

CIoU(Complete-IoU),就是在DIoU的基础上增加了检测框尺度的loss增加了长和宽的loss,使得目标框回归更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题。💞

🍀计算公式:

CIOU Loss 和 DIOU Loss 前面的公式都是一样的,不过在此基础上还增加了一个影响因子,这样CIOU_Loss就将目标框回归函数应该考虑三个重要几何因素重叠面积中心点距离长宽比全都考虑进去了。🐳

由以上可得CIOU loss的计算公式为:

 🍀不足之处:

(1)如果预测框和ground truth框的长宽比是相同的,那么长宽比的惩罚项恒为0,不合理。

(2)观察CIoU中w, h相对于v的梯度,发现这两个梯度是一对相反数,也就是说,w和h不能同时增大或减小,这显然也不够合理的。

 🍀Pytorch代码:

def CIoU(box1, box2):
    b1_x1, b1_y1, b1_x2, b1_y2 = box1
    b2_x1, b2_y1, b2_x2, b2_y2 = box2
 
    # IOU
    xx1 = np.maximum(b1_x1, b2_x1)
    yy1 = np.maximum(b1_y1, b2_y1)
    xx2 = np.minimum(b1_x2, b2_x2)
    yy2 = np.minimum(b1_y2, b2_y2)
    inter_w = np.maximum(0.0, xx2 - xx1)
    inter_h = np.maximum(0.0, yy2 - yy1)
    inter = inter_w*inter_h
    Union = (b1_x2-b1_x1)*(b1_y2-b1_y1) + (b2_x2-b2_x1)*(b2_y2-b2_y1) - inter
    IOU = inter/Union
 
    C_xx1 = np.minimum(b1_x1, b2_x1)
    C_yy1 = np.minimum(b1_y1, b2_y1)
    C_xx2 = np.maximum(b1_x2, b2_x2)
    C_yy2 = np.maximum(b1_y2, b2_y2)
 
    # DISTANCE
    center_b_x = (b1_x1 + b1_x2)/2
    center_b_y = (b1_y1 + b1_y2)/2
    center_gtb_x = (b2_x1 + b2_x2)/2
    center_gtb_y = (b2_y1 + b2_y2)/2
    C_area = (C_xx2-C_xx1)*(C_yy2-C_yy1)
    Distance = (center_gtb_x-center_b_x)**2 + (center_gtb_y-center_b_y)**2
    Distance_area = Distance/C_area**2
 
    # aspect ratio
    pred_w = b1_y2 - b1_y1
    pred_h = b1_x2 - b1_x1
    gt_w = b2_y2 - b2_y1
    gt_h = b2_x2 - b2_x1
    v = (4/(np.pi)**2)*(np.arctan(gt_w/gt_h) - np.arctan(pred_w/pred_h))**2
    alpha = v/((1-IOU) + v)
 
    CIOU = IOU - Distance_area - alpha*v
    print("CIOU:", CIOU)
 
if __name__ == "__main__":
    box1 = np.array([100, 100, 210, 210])
    box2 = np.array([150, 150, 230, 220])
    CIoU(box1, box2)

🚀6.EIoU

EIOU 是在 CIOU 的惩罚项基础上将预测框和真实框的纵横比的影响因子拆开,分别计算预测框和真实框的长和宽,来解决 CIOU 存在的问题。🌾

EIoU包括三个部分IoU损失、距离损失、高宽损失(重叠面积、中心点举例、高宽比)。高宽损失直接最小化了预测目标边界框和真实边界框的高度和宽度的差异,使其有更快的收敛速度和更好的定位结果。🌾

🍀计算公式:

其中,wchc是预测边界框与真实边界框的最小外接矩形的宽度和高度。p是两点之间的欧氏距离。 🌴

🍀Pytorch代码:

def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False,  EIoU=False, eps=1e-7):
    # Returns the IoU of box1 to box2. box1 is 4, box2 is nx4
    box2 = box2.T
 
    # Get the coordinates of bounding boxes
    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:  # transform from xywh to 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
 
    # Intersection area
    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 Area
    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
 
    iou = inter / union
    if GIoU or DIoU or CIoU or EIoU:
        cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # convex (smallest enclosing box) width
        ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # convex height
        if CIoU or DIoU or EIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
            c2 = cw ** 2 + ch ** 2 + eps  # convex diagonal squared
            rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 +
                    (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4  # center distance squared
            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(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)  # CIoU
            elif EIoU:
                rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** 2
                rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** 2
                cw2 = cw ** 2 + eps
                ch2 = ch ** 2 + eps
                return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)
        else:  # GIoU https://arxiv.org/pdf/1902.09630.pdf
            c_area = cw * ch + eps  # convex area
            return iou - (c_area - union) / c_area  # GIoU
    else:
        return iou  # IoU

🚀7.总结

边界框回归的三大几何因素:重叠面积中心点距离纵横比🍒🍒🍒

IOU Loss:主要考虑检测框和目标框重叠面积
GIOU Loss:在IOU的基础上,解决边界框不相交时loss等于0的问题
DIOU Loss:在IOU和GIOU的基础上,考虑边界框中心点距离的信息
CIOU Loss:在DIOU的基础上,考虑边界框宽高比的尺度信息。
EIOU Loss:在CIOU的基础上,解决了纵横比的模糊定义,并添加Focal Loss解决BBox回归中的样本不平衡问题。


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式 - 消息队列Kafka:Kafka消费者的分区分配策略

文章目录 1. 环境准备2. range 范围分区策略介绍3. round-robin 轮询分区策略4. sticky 粘性分区策略5. 自定义分区分配策略 1. 环境准备 创建主题 test 有5个分区,准备 3 个消费者并进行消费,观察消费分配情况。然后再停止其中一个消费者,再…

opencv实战项目 手势识别-手势控制键盘

手势识别是一种人机交互技术,通过识别人的手势动作,从而实现对计算机、智能手机、智能电视等设备的操作和控制。 1. opencv实现手部追踪(定位手部关键点) 2.opencv实战项目 实现手势跟踪并返回位置信息(封装调用&am…

Java医院信息化HIS管理系统源码

HIS模板分为两种:病历模板和报表模板。模板管理是运营管理的核心组成部分,是基层卫生健康云中各医疗机构定制电子病历和报表的地方,各医疗机构可根据自身特点特色定制电子病历和报表,制作的电子病历及报表可直接在业务系统中使用。…

全国各城市-货物进出口总额和利用外资-外商直接投资额实际使用额(1999-2020年)

最新数据显示,全国各城市外商直接投资额实际使用额在过去一年中呈现了稳步增长的趋势。这一数据为研究者提供了对中国外商投资活动的全面了解,并对未来投资趋势和政策制定提供了重要参考。 首先,这一数据反映了中国各城市作为外商投资的热门目…

SSL握手协议相关概念

下图为握手协议的流程图,具体的解释参考博客: 【下】安全HTTPS-全面详解对称加密,非对称加密,数字签名,数字证书和HTTPS_tenfyguo的博客-CSDN博客 下面梳理一下SSL协议中的一些细节。首先是相关名词:证书、…

【jvm】类加载子系统

目录 一、图二、类加载器作用三、类加载器角色四、类的加载过程4.1 加载4.1.1 说明4.1.2 加载.class文件的方式 4.2 链接4.2.1 验证(verify [ˈverɪfaɪ])4.2.2 准备(prepare)4.2.3 解析(resolve) 4.3 初始化4.3.1 说明4.3.2 图示14.3.3 图示24.3.3 图示3 一、图 二、类加载器…

预测知识 | 神经网络、机器学习、深度学习

预测知识 | 预测技术流程及模型评价 目录 预测知识 | 预测技术流程及模型评价神经网络机器学习深度学习参考资料 神经网络 神经网络(neural network)是机器学习的一个重要分支,也是深度学习的核心算法。神经网络的名字和结构,源自…

整理mongodb文档:find方法查询数据

个人博客 整理mongodb文档:find方法查询数据 求关注,求批评,求指出,如果哪儿不清晰,请指出来,谢谢 文章概叙 如题,本文讲的是如何用find查询数据,如何在数组、字段、对象中查询,以…

redis学习笔记(八)

文章目录 redis的配置redis的核心配置选项Redis的使用 redis的配置 cat /etc/redis/redis.confredis 安装成功以后,window下的配置文件保存在软件 安装目录下,如果是mac或者linux,则默认安装/etc/redis/redis.conf redis的核心配置选项 绑定ip:访问白名单&#x…

关系型数据库MySQL及其优化

写在前面 本文看下MySQL的基础内容以及常见的优化方式。 1:MySQL基础内容 1.1:什么是关系型数据库 以二维的数据格式来存储数据的数据库叫做关系型数据库,其中关系包括一对一,一对多,多对多,都通过二位…

qt QPalette的原理与使用

QPalette类用于控制控件的风格,即任意一个地方的绘制方式。每个控件或者说qwidget对象内部都有一个QPalette对象。 在paintEvent(QPaintEvent *event)函数中,其实就是调用该控件的QPalette内容来进行绘制的了。 例如: QStyleOptionTab opt…

强化学习算法

强化学习算法 游戏模型如下: 策略网络输入状态s,输出动作a的概率分布如下: π ( a ∣ s ) \pi(a|s) π(a∣s) 多次训练轨迹如下 r表示回报横轴为T, 1个回合的步骤数纵轴为N, 回合数,1行代表1条轨迹,符合概率分布…

DatawhaleAI夏令营第三期机器学习用户新增预测挑战赛baseline新手教程

本教程会带领大家项目制学习,由浅入深,逐渐进阶。从竞赛通用流程与跑通最简的Baseline,到深入各个竞赛环节,精读Baseline与进阶实践技巧的学习。 千里之行,始于足下,从这里,开启你的 AI 学习之旅…

wifi列表消失 后总结

故障现象: 管理源身份打开cmd ,然后重启网络服务 Fn 加信号塔 开启二者为自动: 刷新网络: Fn 加信号塔 重启的时间可以放长一些 半个小时左右

【数据结构与算法】十大经典排序算法-选择排序

🌟个人博客:www.hellocode.top 🏰Java知识导航:Java-Navigate 🔥CSDN:HelloCode. 🌞知乎:HelloCode 🌴掘金:HelloCode ⚡如有问题,欢迎指正&#…

ping是什么

一.什么是ping 命令 在网络中 ping 是一个十分强大的 TCP/IP 工具,ping是定位网络通不通的一个重要手段。 ping 命令是基于 ICMP 协议来工作的,「 ICMP 」全称为 Internet 控制报文协议(Internet Control Message Protocol)。ping 命令会发…

恒温碗语音芯片,具备数码管驱动与温度传感算法,WT2003H-B012

近年来,随着科技的飞速发展,智能家居产品已然成为了现代生活的一部分,为人们的生活带来了更多的便利和舒适。在这个不断演进的领域中,恒温碗多功能语音芯片——WT2003H-B012成为众多厂商的首选,为智能家居领域注入了全…

数据库中的连表更新和连表删除

1.连表更新 准备两张表,id一样,但是姓名不一样, 需求根据id让姓名保持一致 执行的sql UPDATE teacher_copy1 AS b INNER JOIN teacher c ON b.TId c.TId set b.tnamec.tname 执行结果 2.连接删除 DELETE a FROMteacher_copy1 AS aINNER JOIN teacher b ON a.TId b.TId

【从零开始学习JAVA | 第四十五篇】动态代理

目录 前言: 动态代理: 动态代理实现步骤: 动态代理的应用场景: 总结: 前言: 动态代理作为一种强大的编程技术,不仅为我们提供了灵活性和可扩展性,还为软件开发和系统设计带来了…

在Linux虚拟机内配置nginx以及docker

目录 1、nginx源码包编译以及安装依赖 1、配置安装所需的编译环境 2、安装函数库(pcre、zlib、openssl) 2、安装nginx 1、获取源码包 2、解压编译 3、启动nginx服务 1、关闭防火墙 2、运行nginx 3、使用本地浏览器进行验证 3、安装docker 1、…