YOLOv5算法改进(19)— 更换NMS(DIoU-NMS、CIoU-NMS、EIoU-NMS、GIoU-NMS 、SIoU-NMS和Soft-NMS)

news2024/10/1 17:15:51

前言:Hello大家好,我是小哥谈。YOLOv5中的NMS指非极大值抑制(Non-Maximum Suppression),它是一种用于目标检测算法中的后处理技术。在检测到多个重叠的边界框时,NMS可以帮助选择最佳的边界框。NMS的工作原理是首先根据预测边界框的置信度对它们进行排序,然后从置信度最高的边界框开始遍历,将与当前边界框的重叠度(通常使用IoU,即交并比)大于某个阈值的边界框移除。这样可以保留置信度最高的边界框,并且消除冗余的边界框。本节课就简单介绍一下常见的NMS并重点讲解如何去更换NMS!🌈 

前期回顾:

            YOLOv5算法改进(1)— 如何去改进YOLOv5算法

            YOLOv5算法改进(2)— 添加SE注意力机制

            YOLOv5算法改进(3)— 添加CBAM注意力机制

            YOLOv5算法改进(4)— 添加CA注意力机制

            YOLOv5算法改进(5)— 添加ECA注意力机制

            YOLOv5算法改进(6)— 添加SOCA注意力机制

            YOLOv5算法改进(7)— 添加SimAM注意力机制

            YOLOv5算法改进(8)— 替换主干网络之MobileNetV3

            YOLOv5算法改进(9)— 替换主干网络之ShuffleNetV2

            YOLOv5算法改进(10)— 替换主干网络之GhostNet

            YOLOv5算法改进(11)— 替换主干网络之EfficientNetv2

            YOLOv5算法改进(12)— 替换主干网络之Swin Transformer

            YOLOv5算法改进(13)— 替换主干网络之PP-LCNet

            YOLOv5算法改进(14)— 更换Neck之BiFPN

            YOLOv5算法改进(15)— 更换Neck之AFPN

            YOLOv5算法改进(16)— 增加小目标检测层

            YOLOv5算法改进(17)— 更换损失函数(EIoU、AlphaIoU、SIoU和WIoU)

            YOLOv5算法改进(18)— 更换激活函数(SiLU、ReLU、ELU、Hardswish、Mish、Softplus等)

           目录

🚀1.NMS(非极大抑制)概念

🚀2.NMS(非极大抑制)工作原理 

🚀3.DIoU-NMS、CIoU-NMS、EIoU-NMS、GIoU-NMS和SIoU-NMS

💥💥3.1 更换DIoU-NMS

💞步骤1:修改general.py

💞步骤2:更换NMS

💥💥3.2 更换其他NMS

🚀4.Soft-NMS

💞步骤1:修改general.py

💞步骤2:更换NMS

🚀1.NMS(非极大抑制)概念

NMS(Non-Maximum Suppression)是一种目标检测算法中常用的技术,用于在多个候选框中选择最佳的目标框其主要目的是消除冗余的候选框,只保留最具代表性的目标框在最近几年常见的物体检测算法(包括RCNN、Fast-RCNN、Faster-RCNN等)中,最终都会从一张图片中找出很多个可能是物体的矩形框,然后为每个矩形框为做类别分类概率。

举例:目标检测的过程中,在同一目标的位置上会产生大量的候选框,这些候选框相互之间可能会有重叠,此时我们需要利用NMS(非极大值抑制)找到最佳的目标边界框,消除冗余的边界框。🌿

说明:♨️♨️♨️

NMS(Non-Maximum Suppression)在目标检测的最后一个阶段使用,即在候选框生成和分类完成后,用于消除冗余的候选框,保留最具代表性的目标框。


🚀2.NMS(非极大抑制)工作原理 

NMS 的工作原理如下:

  1. 根据模型预测结果,得到一系列候选框,并计算其置信度得分。
  2. 按照置信度得分降序排列候选框。
  3. 选择置信度得分最高的候选框,并将其添加到最终输出的目标框列表中。
  4. 逐个遍历剩余的候选框,与已选择的目标框计算重叠度(如交并比)。
  5. 如果某个候选框与已选择的目标框重叠度高于设定的阈值,则将该候选框舍弃。
  6. 重复步骤4和5,直到遍历完所有候选框。

这样,NMS 可以在一系列候选框中选择出最具代表性的目标框,并消除冗余。这对于目标检测任务中的多目标检测非常重要。🌴

名词解释:

IOU即交并比,是目标检测中衡量目标检测算法准确度的一个重要指标,顾名思义,即交集与并集的比值。

局限性:

  • 循环步骤,GPU难以并行处理,运算效率低;
  • 以分类置信度为优先衡量指标分类置信度高的定位不一定最准,降低了模型的定位准确度;
  • 直接提高阈值暴力去除bbox 将得分较低的边框强制性地去掉,如果物体出现较为密集时,本身属 于两个物体的边框,其中得分较低的框就很有可能被抑制掉,从而降低了模型的召回率,且阈值设定完全依赖自身经验。

🚀3.DIoU-NMS、CIoU-NMS、EIoU-NMS、GIoU-NMS和SIoU-NMS

💥💥3.1 更换DIoU-NMS

非最大抑制(NMS)主要用于基于深度学习的目标检测模型输出的后处理,从而去除冗余的检测框,获得正确的检测结果。其具体意义是指在目标检测的预测阶段时,会输出许多候选的anchor box,其中有很多是明显重叠的预测边界框都围绕着同一个目标,这时候就可以使用NMS来合并同一目标的类似边界框,或者说是保留这些边界框中最好的一个。

在经典的NMS中,得分最高的检测框和其它检测框逐一算出一个对应的IOU值,并将该值超过NMS threshold的框全部过滤掉。可以看出,在经典NMS算法中,IOU是唯一考量的因素。但是在实际应用场景中,当两个不同物体挨得很近时,由于IOU值比较大,往往经过NMS处理后,只剩下一个检测框,这样导致漏检的错误情况发生。基于此,DIOU-NMS就不仅仅考虑IOU,还考虑两个框中心点之间的距离。如果两个框之间IOU比较大,但是两个框的距离比较大时,可能会认为这是两个物体的框而不会被过滤掉。 

实验证明,将NMS替换为DIoU-NMS,可初步改善YOLOv5对重叠遮挡目标的识别。🌱

公式:

论文题目:《Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression》

论文地址:  https://arxiv.org/pdf/1911.08287.pdf

代码实现:  https://github.com/Zzh-tju/DIoU

💞步骤1:修改general.py

将如下代码复制粘贴到utils / general.py

def NMS(boxes, scores, iou_thres, GIoU=False, DIoU=True, CIoU=False, EIoU=False, SIoU=False):
    B = torch.argsort(scores, dim=-1, descending=True)
    keep = []
    while B.numel() > 0:
        index = B[0]
        keep.append(index)
        if B.numel() == 1: break
        iou = bbox_iou(boxes[index, :], boxes[B[1:], :], GIoU=GIoU, DIoU=DIoU, CIoU=CIoU, EIoU=EIoU, SIoU=SIoU)
        inds = torch.nonzero(iou <= iou_thres).reshape(-1)
        B = B[inds + 1]
    return torch.tensor(keep)


def soft_nms(bboxes, scores, iou_thresh=0.5, sigma=0.5, score_threshold=0.25):
    order = scores.argsort(descending=True).to(bboxes.device)
    keep = []
    while order.numel() > 1:
        if order.numel() == 1:
            keep.append(order[0])
            break
        else:
            i = order[0]
            keep.append(i)
        iou = bbox_iou(bboxes[i], bboxes[order[1:]]).squeeze()
        idx = (iou > iou_thresh).nonzero().squeeze()
        if idx.numel() > 0:
            iou = iou[idx]
            new_scores = torch.exp(-torch.pow(iou, 2) / sigma)
            scores[order[idx + 1]] *= new_scores
        new_order = (scores[order[1:]] > score_threshold).nonzero().squeeze()
        if new_order.numel() == 0:
            break
        else:
            max_score_index = torch.argmax(scores[order[new_order + 1]])
            if max_score_index != 0:
                new_order[[0, max_score_index],] = new_order[[max_score_index, 0],]
            order = order[new_order + 1]
    return torch.LongTensor(keep)

然后导入包:

from utils.metrics import box_iou, fitness, bbox_iou

💞步骤2:更换NMS

non_max_suppression函数中的代码:

i = torchvision.ops.nms(boxes, scores, iou_thres)

替换为:

i = NMS(boxes, scores, iou_thres, class_nms='DIoU')

然后就可以训练了!~🌟

说明:♨️♨️♨️

经过实际检验,NMS耗时对比:

NMS:2.7ms

DIoU-NMS:9.1ms

💥💥3.2 更换其他NMS

更换其他NMS与上述更换DIoU-NMS步骤是一样的,区别在于需要在步骤2改个名称。👇

关于更换其他NMS,具体代码分别如下所示:

DIoU-NMS:

i = NMS(boxes, scores, iou_thres, class_nms='DIoU') 

CIoU-NMS:

i = NMS(boxes, scores, iou_thres, class_nms='CIoU') 

EIoU-NMS:

i = NMS(boxes, scores, iou_thres, class_nms='EIoU') 

GIoU-NMS :

i = NMS(boxes, scores, iou_thres, class_nms='GIoU') 

SIoU-NMS:

i = NMS(boxes, scores, iou_thres, class_nms='SIoU') 

🚀4.Soft-NMS

Soft-NMS是一种目标检测算法,用于提高检测结果的准确性。传统的非极大抑制(NMS)算法在处理重叠的边界框时,会选择具有最高置信度的边界框,并抑制与其IoU(交并比)大于一定阈值的其他边界框。然而,这种方法可能会忽略具有稍低置信度但仍然准确的边界框。

Soft-NMS通过降低与最高置信度边界框重叠的边界框的得分,而不是直接抑制它们,来解决这个问题。它引入了一个衰减函数,根据两个边界框之间的IoU值来减少得分。这样,即使是与最高置信度边界框重叠较多的边界框也能保留一定得分,并且不会被完全抑制。🌻

论文题目:《Improving Object Detection With One Line of Code》

论文地址:  https://arxiv.org/pdf/1704.04503v2.pdf

代码实现:  mirrors / bharatsingh430 / soft-nms · GitCode

💞步骤1:修改general.py

将如下代码复制粘贴到utils / general.py

def my_soft_nms(bboxes, scores, iou_thresh=0.5, sigma=0.5, score_threshold=0.25):
 
    bboxes = bboxes.contiguous()
 
    x1 = bboxes[:, 0]
    y1 = bboxes[:, 1]
    x2 = bboxes[:, 2]
    y2 = bboxes[:, 3]
    # 计算每个box的面积
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    # 首先对所有得分进行一次降序排列,仅此一次,以提高后续查找最大值速度. oeder为降序排列后的索引
    _, order = scores.sort(0, descending=True)
    # NMS后,保存留下来的边框
    keep = []
 
    while order.numel() > 0:
        if order.numel() == 1:  # 仅剩最后一个box的索引
            i = order.item()
            keep.append(i)
            break
        else:
            i = order[0].item()  # 保留首个得分最大的边框box索引,i为scores中实际坐标
            keep.append(i)
        # 巧妙使用tersor.clamp()函数求取order中当前框[0]之外每一个边框,与当前框[0]的最大值和最小值
        xx1 = x1[order[1:]].clamp(min=x1[i])
        yy1 = y1[order[1:]].clamp(min=y1[i])
        xx2 = x2[order[1:]].clamp(max=x2[i])
        yy2 = y2[order[1:]].clamp(max=y2[i])
        # 求取order中其他每一个边框与当前边框的交集面积
        inter = (xx2 - xx1).clamp(min=0) * (yy2 - yy1).clamp(min=0)
        # 计算order中其他每一个框与当前框的IoU
        iou = inter / (areas[i] + areas[order[1:]] - inter)  # 共order.numel()-1个
 
        idx = (iou > iou_thresh).nonzero().squeeze()  # 获取order中IoU大于阈值的其他边框的索引
        if idx.numel() > 0:
            iou = iou[idx]
            newScores = torch.exp(-torch.pow(iou, 2) / sigma)  # 计算边框的得分衰减
            scores[order[idx + 1]] *= newScores  # 更新那些IoU大于阈值的边框的得分
 
        newOrder = (scores[order[1:]] > score_threshold).nonzero().squeeze()
        if newOrder.numel() == 0:
            break
        else:
            newScores = scores[order[newOrder + 1]]
            maxScoreIndex = torch.argmax(newScores)
 
            if maxScoreIndex != 0:
                newOrder[[0, maxScoreIndex],] = newOrder[[maxScoreIndex, 0],]
            # 更新order.
            order = order[newOrder + 1]
 
    # 返回保留下来的所有边框的索引值,类型torch.LongTensor
    return torch.LongTensor(keep)

💞步骤2:更换NMS

non_max_suppression函数中的代码:

i = torchvision.ops.nms(boxes, scores, iou_thres)

替换为:

     i = my_soft_nms(boxes, scores, iou_thres)  # 

然后就可以训练了!~🌟


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

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

相关文章

main函数中两个参数的作用

一般我们在使用C语言时不太用到main函数自带的参数&#xff0c;因此最常见的main函数就像下面这样。 int main() {...... }上面这种main函数是省略了其形参的&#xff0c;C语言中规定main函数的参数只能有两个&#xff0c;习惯上这两个参数写为argc和argv&#xff0c;其中&…

SIEM 中的事件关联

什么是 SIEM 中的事件关联 SIEM 中的事件关联可帮助安全团队识别来自不同来源的安全事件并确定其优先级&#xff0c;从而提供更全面的整体安全环境视图。 在典型的 IT 环境中&#xff0c;会跨各种系统和应用程序生成大量事件和日志。孤立地看&#xff0c;其中许多事件可能看起…

3.zigbee开发,OSAL原理及使用(类似操作系统)

一。cc2530&#xff08;zigbee的一种芯片&#xff09;使用中断 通过使用OSAL进行事件的切换&#xff0c;就是中断。 二。OSAL初步使用 1.对zigbee的工程文件进行分析&#xff08;上一节的工程模版文件&#xff09; &#xff08;1&#xff09;osal初始化&#xff1a;中断暂停…

JMeter断言之JSON断言

JSON断言 若服务器返回的Response Body为JSON格式的数据&#xff0c;使用JSON断言来判断测试结果是较好的选择。 首先需要根据JSON Path从返回的JSON数据中提取需要判断的实际结果&#xff0c;再设置预期结果&#xff0c;两者进行比较得出断言结果。 下面首先介绍JSON与JSON…

Vue模板语法集(上)

1.插值 插值&#xff1a;用双大括号{{}}将数据绑定到模板中&#xff0c;实现简单的数据渲染。例如&#xff1a;<p>{{message}}</p>&#xff0c;其中message是一个变量。 1.1.3 属性 HTML属性中的值应使用v-bind指令 1.1.4 表达式 1.1.1 文本 {{msg} 1.1.2 html 使…

HY57V561620FTP_SDRAM文档总结

文章目录 前言一、sdram简介1、名称解释2、发展历史3、与原先学习的RAM区别4、SDRAM分类 二、HY57V561620FTP1、描述1、内存划分2、特征3、引脚说明4、内部结构介绍5、交流特性6、可能涉及到的命令组合 2、SDRAM 具体操作流程1、整体状态图2、SDRAM指令及时序图3、芯片初始化(这…

​全国馆藏《乡村振兴战略下传统村落文化旅游设计》许少辉八一著作——2023学生开学季辉少许

​全国馆藏《乡村振兴战略下传统村落文化旅游设计》许少辉八一著作——2023学生开学季辉少许

一招制胜,如何写好一份优秀的营销策划方案?

我相信很多策划人一直都在积累很多策划模版和案例&#xff0c;觉得写策划案不就是照着相似的案例抄一抄。 虽然说这样做不是什么错误&#xff0c;但太依赖这样的方式的话&#xff0c;对于自己所写的东西&#xff0c;总会有一种掌控力不足的感觉。 究其原因&#xff0c;是你钻…

成集云 | 用友U8集成聚水潭ERP(用友U8主管库存)| 解决方案

源系统成集云目标系统 方案介绍 用友U8是一套企业级的解决方案&#xff0c;可满足不同的制造、商务模式下&#xff0c;不同运营模式下的企业经营管理。它全面集成了财务、生产制造及供应链的成熟应用&#xff0c;并延伸客户管理至客户关系管理&#xff08;CRM&#xff09;&am…

容器的数据卷

容器的数据卷 操作数据卷 # 基本格式 docker volume [common] # 创建一个volume docker volume create # 显示一个或多个volume docker volume inspect # 列出所以的volume docker volume ls # 删除未使用的volume docker volume prune # 删除一个或多个volume docker volume…

计算机视觉与深度学习-卷积神经网络-纹理表示卷积神经网络-卷积神经网络-[北邮鲁鹏]

这里写目录标题 参考文章全连接神经网络全连接神经网络的瓶颈全连接神经网络应用场景 卷积神经网络卷积层(CONV)卷积核卷积操作卷积层设计卷积步长(stride)边界填充特征响应图组尺寸计算 激活层池化层(POOL)池化操作定义池化操作作用池化层超参数常见池化操作 全连接层(FC)样本…

ESD最常用的3种模型?|深圳比创达EMC

为了定量表征 ESD的特性&#xff0c;一般将 ESD 转化成模型表达方式&#xff0c;ESD 的模型有很多种&#xff0c;下面介绍最常用的三种。 1.HBM&#xff1a;Human Body Model&#xff0c;人体模型 该模型表征人体带电接触器件放电&#xff0c;Rb 为等效人体电阻&#xff0c;Cb…

Pikachu XSS(跨站脚本攻击)

文章目录 Cross-Site ScriptingXSS&#xff08;跨站脚本&#xff09;概述反射型[xss](https://so.csdn.net/so/search?qxss&spm1001.2101.3001.7020)(get)反射型xss(post)存储型xssDOM型xssDOM型xss-xxss-盲打xss-过滤xss之htmlspecialcharsxss之href输出xss之js输出 Cros…

02. Springboot集成Flyway

目录 1、前言 2、什么是Flyway&#xff1f; 3、为什么要使用 Flyway&#xff1f; 4、简单示例 4.1、创建Spring Boot工程 4.2、添加Flyway依赖 4.3、Springboot添加Flyway配置 4.4、创建执行SQL脚本 4.5、启动测试 4.6、Flyway版本管理 5、SQL脚本文件命名规则 6、…

比特币 ZK 赏金系列:第 2 部分——查找哈希冲突

在我们的零知识赏金 (ZKB) 系列的第二部分中&#xff0c;我们将其应用于解决哈希冲突难题。在这样的谜题中&#xff0c;两个不同的输入散列到相同的输出。此类赏金可用于&#xff1a; 充当煤矿中的金丝雀&#xff0c;给我们一个有价值的提醒。存在冲突是散列函数较弱的标志&…

LCP 06. 拿硬币【向上取整】

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;贪心 知识回顾向上、向下取整 写在最后 Tag 【贪心】【数组】 题目来源 LCP 06. 拿硬币 题目解读 数组 coins 中存放的是一堆堆的力扣币&#xff0c;对于每一堆力扣币&#xff0c;你可以选择拿走一枚或者两枚&#x…

SOCKS5 认证的方法

在进行网络浏览或爬虫等相关工作时&#xff0c;我们经常会遇到需要使用 SOCKS5 代理认证的情况。然而&#xff0c;某些浏览器可能不提供原生支持 SOCKS5 代理认证的选项&#xff0c;给我们带来了一些困扰。本文将为大家介绍几种解决浏览器不支持 SOCKS5 代理认证问题的方法。 …

java图形化工具编写初试

java图形化工具编写初试 前言&#xff1a; 照虎画猫——用WgpSec 说书人师傅的‘用友NC系列检测利用工具’结合本人为数不多的java基础再结合gpt&#xff0c;学习了一下java图形化工具的编写&#xff0c;实现了最基础的漏洞检测功能........用大华的两个漏洞为例&#xff0c;分…

kafka消费/发送消息,消息过大报错解决whose size is larger than the fetch size 1048576

目录 一、kafka消费报错原因二、解决方案1、原因一的解决方案2、原因二的解决方案 一、kafka消费报错原因 问题原因一&#xff1a;个是kafka本身的配置没有调整到上限 问题原因二&#xff1a;就是我们自己写python消费kafka代码的时候没有参数配置没有限制 RecordTooLargeE…

实践分享:vue模块化基本用法

首先还是来看看什么是模块化。 常见的概括&#xff1a;模块化就是把单独的一个功能封装到一个模块&#xff08;文件&#xff09;中&#xff0c;模块之间相互隔离&#xff0c;但是可以通过特定的接口公开内部成员&#xff0c;也可以依赖别的模块&#xff08;方便代码的重用&…