新的损失函数SIoU:结合图片和详细代码分块深入理解原理

一、前言

        原文地址https://arxiv.org/abs/2205.12740

        SIoU进一步考虑了真实框和预测框之间的向量角度,重新定义相关损失函数,具体包含四个部分:角度损失(Angle cost)、距离损失(Distance cost)、形状损失(Shape cost)、IoU损失(IoU cost)。

二、分块分析

        1、角度损失(Angle cost)

        sin(\alpha)看公示可以知道,就是直角三角形中的对边比斜边。

        \sigma为真实框和预测框中心点的距离。

       c_{h}为真实框和预测框中心点的高度差,代码中直接使用勾股定理求得。

        b_{c_{x}}^{gt}  , b_{c_{y}}^{gt} 为真实框中心坐标,b_{c_{x}}b_{c_{y}}为预测框中心坐标

import torch
import math
# [[x, y, w, h]]
# [[x, y, w, h]] : 中心点坐标和宽高
pred = torch.tensor([[1, 2, 3, 4]])
gt = torch.tensor([[5, 6, 7, 8]])
iou = 0.5  # 这里设置iou为0.5
def siou1():
    # --------------------角度损失(Angle cost)------------------------------
    gt_p_center_D_value_w = torch.abs((gt[:, 0] - pred[:, 0]))  # 真实框和预测框中心点的宽度差
    gt_p_center_D_value_h = torch.abs((gt[:, 1] - pred[:, 1]))  # 真实框和预测框中心点的高度差
    sigma = torch.pow(gt_p_center_D_value_w ** 2 + gt_p_center_D_value_h ** 2, 0.5)  # 真实框和预测框中心点的距离
    sin_alpha = torch.abs(gt_p_center_D_value_h) / sigma  # 真实框和预测框中心点的夹角α
    sin_beta = torch.abs(gt_p_center_D_value_w) / sigma  # 真实框和预测框中心点的夹角β
    threshold = torch.pow(torch.tensor(2.), 0.5) / 2  # 夹角阈值 0.7071068 = sin45° = 二分之根二
    # torch.where(condition,a,b)其中
    # 输入参数condition:条件限制,如果满足条件,则选择a,否则选择b作为输出。
    sin_alpha = torch.where(sin_alpha < threshold, sin_beta, sin_alpha)  # α小于45°则考虑优化β,否则优化α
    angle_cost = torch.cos(2 * (torch.arcsin(sin_alpha) - math.pi / 4))

        2、距离损失(Distance cost)

                    与真实框和预测框的最小外接矩形有关

                      c_{w}c_{h}为真实框和预测框最小外接矩形的宽和高

 # -----------------距离损失(Distance cost)-----------------------------
    # min_enclosing_rec_tl:最小外接矩形左上坐标
    # min_enclosing_rec_br:最小外接矩形右下坐标
    min_enclosing_rec_tl = torch.min(
                (pred[:, :2] - pred[:, 2:] / 2), (gt[:, :2] - gt[:, 2:] / 2))
    min_enclosing_rec_br = torch.max(
                (pred[:, :2] + pred[:, 2:] / 2), (gt[:, :2] + gt[:, 2:] / 2))

    # 最小外接矩形的宽高
    min_enclosing_rec_br_w = (min_enclosing_rec_br - min_enclosing_rec_tl)[:, 0]
    min_enclosing_rec_br_h = (min_enclosing_rec_br - min_enclosing_rec_tl)[:, 1]

    # 真实框和预测框中心点的宽度(高度)差 / 以最小外接矩形的宽(高) 的平方
    rho_x = (gt_p_center_D_value_w / min_enclosing_rec_br_w) ** 2
    rho_y = (gt_p_center_D_value_h / min_enclosing_rec_br_h) ** 2

    gamma = 2 - angle_cost
    # 距离损失
    distance_cost = 2 - torch.exp(-gamma * rho_x) - torch.exp(-gamma * rho_y)

        3、形状损失(Shape cost)

                w,h,w^{gt},h^{gt}分别为预测框和真实框的宽和高,\theta控制对形状损失的关注程度,为了避免过于关注形状损失而降低对预测框的移动,作者使用遗传算法计算出接近4,因此作者定于参数范围为[2, 6]

# ----------------形状损失(Shape cost)----------------------
    w_pred = pred[:, 2]  # 预测框的宽
    w_gt = gt[:, 2]  # 真实框的宽
    h_pred = pred[:, -1]  # 预测框的高
    h_gt = gt[:, -1]  # 真实框的高
    # 预测框的宽 - 真实框的宽的绝对值 / 预测框的宽和真实框的宽中的最大值
    omiga_w = torch.abs(w_pred - w_gt) / torch.max(w_pred, w_gt)
    omiga_h = torch.abs(h_pred - h_gt) / torch.max(h_pred, h_gt)

    # 作者使用遗传算法计算出θ接近4,因此作者定于θ参数范围为[2, 6]
    theta = 4
    # 形状损失
    shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w), theta) + torch.pow(1 - torch.exp(-1 * omiga_h), theta)

4、IoU损失(IoU cost)

        可以看看之前的学习随笔

通过PYTHON画图来理解IOU的计算(学习随笔)

5、最终SIoU损失函数定义如下:

三、完整代码(可直接运行)

import torch
import math
# [[x, y, w, h]]
# [[x, y, w, h]] : 中心点坐标和宽高
pred = torch.tensor([[1, 2, 3, 4]])
gt = torch.tensor([[5, 6, 7, 8]])
iou = 0.5  # 这里设置iou为0.5
def siou1():
    # --------------------角度损失(Angle cost)------------------------------
    import torch
import math
# [[x, y, w, h]]
# [[x, y, w, h]] : 中心点坐标和宽高
pred = torch.tensor([[1, 2, 3, 4]])
gt = torch.tensor([[5, 6, 7, 8]])
iou = 0.5  # 这里设置iou为0.5
def siou1():
    # --------------------角度损失(Angle cost)------------------------------
    gt_p_center_D_value_w = torch.abs((gt[:, 0] - pred[:, 0]))  # 真实框和预测框中心点的宽度差
    gt_p_center_D_value_h = torch.abs((gt[:, 1] - pred[:, 1]))  # 真实框和预测框中心点的高度差
    sigma = torch.pow(gt_p_center_D_value_w ** 2 + gt_p_center_D_value_h ** 2, 0.5)  # 真实框和预测框中心点的距离
    sin_alpha = torch.abs(gt_p_center_D_value_h) / sigma  # 真实框和预测框中心点的夹角α
    sin_beta = torch.abs(gt_p_center_D_value_w) / sigma  # 真实框和预测框中心点的夹角β
    threshold = torch.pow(torch.tensor(2.), 0.5) / 2  # 夹角阈值 0.7071068 = sin45° = 二分之根二
    # torch.where(condition,a,b)其中
    # 输入参数condition:条件限制,如果满足条件,则选择a,否则选择b作为输出。
    sin_alpha = torch.where(sin_alpha < threshold, sin_beta, sin_alpha)  # α小于45°则考虑优化β,否则优化α
    angle_cost = torch.cos(2 * (torch.arcsin(sin_alpha) - math.pi / 4))

    # -----------------距离损失(Distance cost)-----------------------------
    # min_enclosing_rec_tl:最小外接矩形左上坐标
    # min_enclosing_rec_br:最小外接矩形右下坐标
    min_enclosing_rec_tl = torch.min(
                (pred[:, :2] - pred[:, 2:] / 2), (gt[:, :2] - gt[:, 2:] / 2))
    min_enclosing_rec_br = torch.max(
                (pred[:, :2] + pred[:, 2:] / 2), (gt[:, :2] + gt[:, 2:] / 2))

    # 最小外接矩形的宽高
    min_enclosing_rec_br_w = (min_enclosing_rec_br - min_enclosing_rec_tl)[:, 0]
    min_enclosing_rec_br_h = (min_enclosing_rec_br - min_enclosing_rec_tl)[:, 1]

    # 真实框和预测框中心点的宽度(高度)差 / 以最小外接矩形的宽(高) 的平方
    rho_x = (gt_p_center_D_value_w / min_enclosing_rec_br_w) ** 2
    rho_y = (gt_p_center_D_value_h / min_enclosing_rec_br_h) ** 2

    gamma = 2 - angle_cost
    # 距离损失
    distance_cost = 2 - torch.exp(-gamma * rho_x) - torch.exp(-gamma * rho_y)

    # ----------------形状损失(Shape cost)----------------------
    w_pred = pred[:, 2]  # 预测框的宽
    w_gt = gt[:, 2]  # 真实框的宽
    h_pred = pred[:, -1]  # 预测框的高
    h_gt = gt[:, -1]  # 真实框的高
    # 预测框的宽 - 真实框的宽的绝对值 / 预测框的宽和真实框的宽中的最大值
    omiga_w = torch.abs(w_pred - w_gt) / torch.max(w_pred, w_gt)
    omiga_h = torch.abs(h_pred - h_gt) / torch.max(h_pred, h_gt)

    # 作者使用遗传算法计算出θ接近4,因此作者定于θ参数范围为[2, 6]
    theta = 4
    # 形状损失
    shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w), theta) + torch.pow(1 - torch.exp(-1 * omiga_h), theta)

    #------------------loss_siou----------------------------
    siou = 1.0 - iou + 0.5 * (distance_cost + shape_cost)

    print(siou)

siou1()

  • 15
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
YOLO损失函数SIOU是指采用SIoU损失函数来替换原始的边界框回归指标的聚合方法。传统的目标检测损失函数依赖于预测框和真实框之间的距离、重叠区域和纵横比等指标来衡量匹配程度。然而,这些方法没有考虑到真实框与预测框之间的不匹配方向。这导致了模型的收敛速度较慢和效率较低,因为预测框可能会在训练过程中“四处游荡”并产生较差的结果。 为了解决这个问题,采用SIOU损失函数来替代原始损失函数SIOU损失函数考虑了真实框与预测框之间不匹配的方向,通过引入方向偏差来改进匹配过程。这样可以更准确地衡量真实框与预测框的匹配程度,从而提升模型的性能。 这种改进的损失函数不仅适用于改进YOLOv5,还可以应用于其他版本的YOLO网络,如YOLOv4、v3等。通过采用SIOU损失函数,可以提高目标检测的准确性和效率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [[YOLOv7/YOLOv5系列算法改进NO.10]损失函数改进为SIOU](https://blog.csdn.net/m0_70388905/article/details/125569509)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值