目标检测之损失函数

news2024/12/28 9:54:41

损失函数的作用为度量神经网络预测信息与期望信息(标签)的距离,预测信息越接近期望信息,损失函数值越小。
在目标检测领域,常见的损失分为分类损失和回归损失。

L1损失

L1 Loss也称为平均绝对值误差(MAE),是指模型预测值f(x)和真实值y之间绝对差值的平均值,公式如下:
在这里插入图片描述
优点:
L1损失函数的导数是常量,有着稳定的梯度,所以不会有梯度爆炸的问题。
缺点:
在-1到1之间时,由于其梯度仍为1或-1,即梯度没有任何变换,而在该区间时,误差以及很小了,那么我们希望在该部分的梯度应该小一些,来慢慢逼近。

L2损失

L2 Loss也称为均方误差(MSE),是指模型预测值f(x)和真实值y之间差值平方的平均值,公式如下:

在这里插入图片描述
优点:
函数曲线连续,处处可导,随着误差值的减小,梯度也减小,有利于收敛到最小值。
缺点:
当误差较大时,由于其导数为2x,故此时期梯度较大,且对异常值十分敏感,即遇到异常值不够稳定(鲁棒性不强),如下图对异常值表现过于敏感。

在这里插入图片描述
综合考量,我们希望损失函数在误差较小时能够较为平滑的,缓慢的逼近,即梯度应该减小,而在误差较大时,希望其能够平稳,鲁棒性好,故提出了L1损失与L2损失的变种,Smooth L1。

Smooth L1损失

简单的说Smooth L1就是一个平滑版的L1 Loss,其公式如下:

在这里插入图片描述

该函数实际上是一个分段函数,在[-1,1]之间就是L2损失,解决L1在0处有折点,在[-1, 1]区间以外就是L1损失,解决离群点梯度爆炸问题,所以能从以下两个方面限制梯度:

  • 当预测值与真实值误差过大时,梯度值不至于过大;
  • 当预测值与真实值误差很小时,梯度值足够小。

下图为三者综合:

在这里插入图片描述

IOU 损失

IoU就是我们所说的交并比,是目标检测中最常用的指标,在anchor-based的方法中,他的作用不仅用来确定正样本和负样本,还可以用来评价输出框(predict box)和ground-truth的距离。
在这里插入图片描述

优点:
可以说它可以反映预测检测框与真实检测框的检测效果。
还有一个很好的特性就是尺度不变性,也就是对尺度不敏感(scale invariant), 在regression任务中,判断predict box和gt的距离最直接的指标就是IoU。
缺点:
如果两个框没有相交,根据定义,IoU=0,不能反映两者的距离大小(重合度)。同时因为loss=0,没有梯度回传,无法进行学习训练。
IoU无法精确的反映两者的重合度大小。如下图所示,三种情况IoU都相等,但看得出来他们的重合度是不一样的,左边的图回归的效果最好,右边的最差。
在这里插入图片描述

def box_iou_pairwise(boxes1, boxes2):
    area1 = box_area(boxes1)
    area2 = box_area(boxes2)

    lt = torch.max(boxes1[:, :2], boxes2[:, :2])  # [N,2]
    rb = torch.min(boxes1[:, 2:], boxes2[:, 2:])  # [N,2]

    wh = (rb - lt).clamp(min=0)  # [N,2]
    inter = wh[:, 0] * wh[:, 1]  # [N]

    union = area1 + area2 - inter

    iou = inter / union
    return iou, union

在这里插入图片描述

GIOU损失

在这里插入图片描述
先计算两个框的最小闭包区域面积 Ac (通俗理解:同时包含了预测框和真实框的最小框的面积),再计算出IoU,再计算闭包区域中不属于两个框的区域占闭包区域的比重,最后用IoU减去这个比重得到GIoU。

在这里插入图片描述

优点:
缺点:

def generalized_box_iou(boxes1, boxes2):
    """
    Generalized IoU from https://giou.stanford.edu/

    The boxes should be in [x0, y0, x1, y1] format

    Returns a [N, M] pairwise matrix, where N = len(boxes1)
    and M = len(boxes2)
    """
    # degenerate boxes gives inf / nan results
    # so do an early check
    assert (boxes1[:, 2:] >= boxes1[:, :2]).all()
    assert (boxes2[:, 2:] >= boxes2[:, :2]).all()

    iou, union = box_iou(boxes1, boxes2)

    lt = torch.min(boxes1[:, None, :2], boxes2[:, :2])
    rb = torch.max(boxes1[:, None, 2:], boxes2[:, 2:])

    wh = (rb - lt).clamp(min=0)  # [N,M,2]
    area = wh[:, :, 0] * wh[:, :, 1]

    return iou - (area - union) / (area + 1e-6)

DIOU损失

问题如下:此时iou与giou的损失一样大。此时的GIOU也退化为IOU
在这里插入图片描述
提出了DIOU
在这里插入图片描述

在这里插入图片描述

上述损失函数中,b,bgt分别代表了anchor框和目标框的中心点,且p代表的是计算两个中心点间的欧式距离。c代表的是能够同时覆盖anchor和目标框的最小矩形的对角线距离。

def Diou(bboxes1, bboxes2):
    rows = bboxes1.shape[0]
    cols = bboxes2.shape[0]
    dious = torch.zeros((rows, cols))
    if rows * cols == 0:  #
        return dious
    exchange = False
    if bboxes1.shape[0] > bboxes2.shape[0]:
        bboxes1, bboxes2 = bboxes2, bboxes1
        dious = torch.zeros((cols, rows))
        exchange = True
    # #xmin,ymin,xmax,ymax->[:,0],[:,1],[:,2],[:,3]
    w1 = bboxes1[:, 2] - bboxes1[:, 0]
    h1 = bboxes1[:, 3] - bboxes1[:, 1]
    w2 = bboxes2[:, 2] - bboxes2[:, 0]
    h2 = bboxes2[:, 3] - bboxes2[:, 1]

    area1 = w1 * h1
    area2 = w2 * h2

    center_x1 = (bboxes1[:, 2] + bboxes1[:, 0]) / 2
    center_y1 = (bboxes1[:, 3] + bboxes1[:, 1]) / 2
    center_x2 = (bboxes2[:, 2] + bboxes2[:, 0]) / 2
    center_y2 = (bboxes2[:, 3] + bboxes2[:, 1]) / 2

    inter_max_xy = torch.min(bboxes1[:, 2:], bboxes2[:, 2:])
    inter_min_xy = torch.max(bboxes1[:, :2], bboxes2[:, :2])
    out_max_xy = torch.max(bboxes1[:, 2:], bboxes2[:, 2:])
    out_min_xy = torch.min(bboxes1[:, :2], bboxes2[:, :2])

    inter = torch.clamp((inter_max_xy - inter_min_xy), min=0)
    inter_area = inter[:, 0] * inter[:, 1]
    inter_diag = (center_x2 - center_x1) ** 2 + (center_y2 - center_y1) ** 2
    outer = torch.clamp((out_max_xy - out_min_xy), min=0)
    outer_diag = (outer[:, 0] ** 2) + (outer[:, 1] ** 2)
    union = area1 + area2 - inter_area
    dious = inter_area / union - (inter_diag) / outer_diag
    dious = torch.clamp(dious, min=-1.0, max=1.0)
    if exchange:
        dious = dious.T
    return dious

CIOU损失

问题如下:由于没有考虑到长宽比例,其损失值相同
在这里插入图片描述

故而提出CIOU,CIOU引入了长宽比,即v,并在v前加了一个动态权重值a,其越大,说明更关注长宽比,而其要想变大,则iou应该较大。
在这里插入图片描述

其中v的求法中前面的常数项作为一个经验值。此外也可采用其他的函数而不使用arctan,其意图为当两者长宽比差距越小,那么损失值也就越小。
如下图中右图由于iou较小,我们肯定不会考虑长宽比,因为两图长宽比是相同的,那么此时a就应该越小,应该将重心放到如何使其宽高变大上,而在左图,其iou较大,即在大小上已经相似,那么我们就需要关注其长宽比,其注意到其形状。

在这里插入图片描述

def box_ciou(b1, b2):
    """
    输入为:
    ----------
    b1: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
    b2: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh

    返回为:
    -------
    ciou: tensor, shape=(batch, feat_w, feat_h, anchor_num, 1)
    """
    # 求出预测框左上角右下角
    b1_xy = b1[..., :2]
    b1_wh = b1[..., 2:4]
    b1_wh_half = b1_wh / 2.
    b1_mins = b1_xy - b1_wh_half
    b1_maxes = b1_xy + b1_wh_half

    # 求出真实框左上角右下角
    b2_xy = b2[..., :2]
    b2_wh = b2[..., 2:4]
    b2_wh_half = b2_wh / 2.
    b2_mins = b2_xy - b2_wh_half
    b2_maxes = b2_xy + b2_wh_half

    # 求真实框和预测框所有的iou
    intersect_mins = torch.max(b1_mins, b2_mins)
    intersect_maxes = torch.min(b1_maxes, b2_maxes)
    intersect_wh = torch.max(intersect_maxes - intersect_mins, torch.zeros_like(intersect_maxes))
    intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]
    b1_area = b1_wh[..., 0] * b1_wh[..., 1]
    b2_area = b2_wh[..., 0] * b2_wh[..., 1]
    union_area = b1_area + b2_area - intersect_area
    iou = intersect_area / torch.clamp(union_area, min=1e-6)

    # 计算中心的差距
    center_distance = torch.sum(torch.pow((b1_xy - b2_xy), 2), axis=-1)

    # 找到包裹两个框的最小框的左上角和右下角
    enclose_mins = torch.min(b1_mins, b2_mins)
    enclose_maxes = torch.max(b1_maxes, b2_maxes)
    enclose_wh = torch.max(enclose_maxes - enclose_mins, torch.zeros_like(intersect_maxes))

    # 计算对角线距离
    enclose_diagonal = torch.sum(torch.pow(enclose_wh, 2), axis=-1)
    ciou = iou - 1.0 * (center_distance) / torch.clamp(enclose_diagonal, min=1e-6)

    v = (4 / (math.pi ** 2)) * torch.pow((torch.atan(b1_wh[..., 0] / torch.clamp(b1_wh[..., 1], min=1e-6)) - torch.atan(
        b2_wh[..., 0] / torch.clamp(b2_wh[..., 1], min=1e-6))), 2)
    alpha = v / torch.clamp((1.0 - iou + v), min=1e-6)
    ciou = ciou - alpha * v
    return ciou

阿尔法IOU

在这里插入图片描述

阿尔法IOU为何有用?

在这里插入图片描述

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

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

相关文章

[HNCTF 2022 WEEK4]ezheap

Index 前言Checksec & IDA 前言 手把手教学,覆盖一切途中会遇到的问题。 [HNCTF 2022 WEEK4]ezheap Checksec & IDA 保护全开,但是四肢健全(四项功能 增删改查),因此是ezheap。 主要来观察函数add和show。 d…

注意力机制:基于Yolov5/Yolov7的Triplet注意力模块,即插即用,效果优于cbam、se,涨点明显

论文:https://arxiv.org/pdf/2010.03045.pdf 本文提出了可以有效解决跨维度交互的triplet attention。相较于以往的注意力方法,主要有两个优点: 1.可以忽略的计算开销 2.强调了多维交互而不降低维度的重要性,因此消除了通道和权…

信号完整性分析基础知识之传输线和反射(三):仿真和测试反射波形

使用上面反射系数的定义,可以计算来自任意阻抗的反射信号。当终端阻抗为阻性元件时,阻抗恒定,反射电压容易计算。当终端具有更复杂的阻抗行为(例如电容性或电感性终端,或两者的某种组合)时,如果…

3.QT布局管理

布局管理系统 布局管理器 QLayout类继承图: 新建Qt Widgets项目mylayout,选择基类QWidget,类名MyWidget .ui拖用Font Combo Box、Text Edit,单击主界面,ctrlL,发现两个部件填满界面,运行后随…

Docker部署MySQL主从复制

文章目录 平台说明一、Docker创建网络二、创建MySQL主从容器1.拉取镜像2.查看镜像3.创建启动容器 三、主从配置1.主机配置文件2.从机配置文件3.注意事项4.重启容器5.连接主从数据库主机配置从机配置启动从机复制 四、测试主从复制 平台说明 操作系统:Windows 11 Do…

接口测试入门必会知识总结(学习笔记)

目录 什么是接口? 内部接口 外部接口 接口的本质 什么是接口测试? 反向测试 为什么说接口测试如此重要? 越接近底层的 Bug,影响用户范围越广 目前流行的测试模型 接口测试的优越性 不同协议形式的测试 接口测试工作场景…

『python爬虫』01. 爬虫入门的基础知识(保姆级图文)

目录 1. 合法性2. 爬虫原理3. 网站源代码查看4. 查看网络请求总结 欢迎关注 『python爬虫』 专栏,持续更新中 欢迎关注 『python爬虫』 专栏,持续更新中 1. 合法性 查看网站的爬虫协议,简单介绍爬虫协议robots.txt,避免爬虫爬的好…

简单理解内存分页机制

文章目录 1.CPU寻址方式2.段式内存访问的缺点3.80386两级页表4.PAE三级页表5.x64四级页表6.虚拟内存 思考一个问题:如果没有这样的分页机制时应用程序是怎么访问物理内存地址? 1.CPU寻址方式 Effective Address Base (Index * Scale) Displacement …

加载自己的图像数据集

文章目录 1 加载图像数据集2 图像预处理3 再次加载数据集4 这里还有一个问题,我们没有验证集5 构建DataLoader6 检查是否正确导入数据集 原文链接:《加载自己的图像数据集》 ​ 数据集下载链接 1 加载图像数据集 目录结构: 针对这种非常典型…

Java+proj4j实现根据EPSG编码进行坐标系转换

场景 JavaGeoTools实现WKT数据根据EPSG编码进行坐标系转换: JavaGeoTools实现WKT数据根据EPSG编码进行坐标系转换_霸道流氓气质的博客-CSDN博客 上面使用GeoTools实现坐标系转换。 VueOpenlayersproj4实现坐标系转换: VueOpenlayersproj4实现坐标系转换_霸道流…

VUE3页面div点击改变样式

如题目所示。 用上VUE之后,前后端分离,组件式开发,代码复用、独立性和隔离性都挺好,可维护性得以提高。相比之下,以前用jQuery,代码实在太多了。 不过,vue有个地方不大好,就是控制…

算法基础(二)(共有30道例题)

六、数据结构 (一)数组 定义:数组是存放在连续内存空间上的相同类型数据的集合。数组可以方便的通过下标索引的方式获取到下标下对应的数据。 注意: (1)数组下标都是从0开始的。 (2&#xff0…

【SWAT水文模型】SWAT水文模型建立及应用第二期:土地利用数据的准备(待更新)

SWAT水文模型建立及应用:土地利用数据的准备 1 简介2 土地利用数据的下载1.1 数据下载方式1.2 数据下载 2 土地利用数据的准备2.1 矢量转栅格2.2 土地利用类型的重分类2.3 土地利用分布图投影调整2.4 土地利用类型索引表建立 参考 SWAT水文模型建立及应用第一期主要…

前苹果设计总监创办,Humane想用AI+AR界面取代手机

在2001年,微软研究院一位工程师Gordon Bell开始了一段长时间的“生活记录”(Lifelogging)之旅,他会在胸前、头顶或是眼镜腿处佩戴相机,每30秒自动拍摄一张照片,以捕捉自己生命中的瞬间,记录下他…

数字化转型导师坚鹏:金融科技与保险公司转型

金融科技与保险公司转型 课程背景: 数字化背景下,很多保险公司存在以下问题: 不了解保险公司数转型现状、困惑与成功方法? 不清楚金融科技如何赋能保险公司数字化转型? 不了解保险公司数字化转型标杆企业成功案…

Linux系统上C程序的编译与调试

gcc分布编译链接: 预处理(Pre-Processing)编译(Compiling)汇编(Assembling)链接(Linking) gcc -E hello.c -o hello.i #预处理 gcc -S hello.i -o hello.s #编译 gcc -c…

ThingsBoard教程更新通知,规则节点全解析系列更新

前言 自从 《ThingsBoard系列教程》 专栏上线,我收到了很多读者的认同和肯定,这是我一直坚持分享的理由之一,做有价值的事,帮助他人。前段时间因为写书和学习的原因,ThingsBoard专栏已经4个月没更新。这就导致一些读者…

【点击查看】讯飞星火正在回答···

Hi,开发者: 关于世界,你有过什么样的疑问?每一次的提问,都代表着我们在关注什么,思考什么,好奇什么。世界的每一次更新,都始于一个新的提问。 我是讯飞星火认知大模型,…

【爆肝更新】第二章:Python基础语法——保姆级,超万字!

这一章我们开始学习Python的基础语法,包含字面量,运算符,变量,字符串格式化,input函数等,这一章是为整个Python体系学习打好基础,所以一定要重视起来。 习惯看视频的同学可以看这个免费教程&am…

面试题30天打卡-day13

1、Linux 中的硬链接和软连接是什么,二者有什么区别? 在Linux系统下,有两种链接文件,一种是硬链接(Hard Link),一种是软链接,也称为符号链接(Symbolic Link)…