目标检测中的NMS,soft NMS,softer NMS,Weighted Boxes Fusion
NMS
非最大值抑制算法,诞生至少50年了。
在经典的两阶段目标检测算法中,为了提高对于目标的召回率,在anchor阶段会生成密密麻麻的anchor框。
所以在后处理的时候,会存在着很多冗余框对应着同一个目标。
因此NMS就是后处理中去除冗余框的必不可少的步骤。
NMS算法的具体流程:
输入 boxes,scores, iou_threshold
step-1:将所有检出的output_bbox按cls score划分(如pascal voc分20个类,也即将output_bbox按照其对应的cls score划分为21个集合,1个bg类,背景类直接剔除);
step-2:在每个类集合内根据各个bbox的cls score做降序排列,得到一个降序的list_k;
step-3:对所有的list_k进行遍历,如有20个类,就得对这20个list都进行遍历。从list_k中top1 cls score开始,计算该bbox_x与list中其他bbox_y的IoU,若IoU大于阈值T,则剔除该bbox_y,最终保留bbox_x,从list_k中取出,保存在output_k中最后作为结果输出;
step-4:继续选择list_k中top1 cls score,重复step-3中的迭代操作,直至list_k中所有bbox都完成筛选;
step-5:对每个集合的list_k,重复step-3、4中的迭代操作,直至所有list_k都完成筛选;
import torch
from torch import Tensor
from typing import Tuple
from ._box_convert import _box_cxcywh_to_xyxy, _box_xyxy_to_cxcywh, _box_xywh_to_xyxy, _box_xyxy_to_xywh
import torchvision
from torchvision.extension import _assert_has_ops[docs]def nms(boxes: Tensor, scores: Tensor, iou_threshold: float) -> Tensor:"""Performs non-maximum suppression (NMS) on the boxes accordingto their intersection-over-union (IoU).NMS iteratively removes lower scoring boxes which have anIoU greater than iou_threshold with another (higher scoring)box.If multiple boxes have the exact same score and satisfy the IoUcriterion with respect to a reference box, the selected box isnot guaranteed to be the same between CPU and GPU. This is similarto the behavior of argsort in PyTorch when repeated values are present.Args:boxes (Tensor[N, 4])): boxes to perform NMS on. Theyare expected to be in ``(x1, y1, x2, y2)`` format with ``0 <= x1 < x2`` and``0 <= y1 < y2``.scores (Tensor[N]): scores for each one of the boxesiou_threshold (float): discards all overlapping boxes with IoU > iou_thresholdReturns:keep (Tensor): int64 tensor with the indicesof the elements that have been keptby NMS, sorted in decreasing order of scores"""_assert_has_ops()return torch.ops.torchvision.nms(boxes, scores, iou_threshold)
NMS存在的一些问题
物体重叠:如下面第一张图,会有一个最高分数的框,如果使用nms的话就会把其他置信度稍低,但是表示另一个物体的预测框删掉(由于和最高置信度的框overlap过大)
存在一些,所有的bbox都预测不准,不是所有的框都那么精准,有时甚至会出现某个物体周围的所有框都标出来了,但是都不准的情况
传统的NMS方法是基于分类分数的,只有最高分数的预测框能留下来,但是大多数情况下IoU和分类分数不是强相关,很多分类标签置信度高的框都位置都不是很准
Soft NMS
Improving Object Detection With One Line of Code
论文发表于 ICCV 2017
http://arxiv.org/abs/1704.04503
传统NMS的不足之处:
- 为了尽可能较小的增加假阳性率,临近检测的分数应该被抑制,同时要保证其得分在所有检测结果中明显高于假阳性样本;
- 在使用较低的NMS阈值来去除临近检测冗余的时候效果是sub-optimal,当使用高阈值的时候又会产生漏检率;
- 当使用比较高的NMS阈值的时候,在测量有重叠阈值范围内的mAP效果会下降;
引入soft NMS的核心就是不会直接通过一个NMS阈值去去除冗余检测,而是对于高度冗余的检测结果通过惩罚函数进行抑制,使得其得分下降;
IOU冗余的越厉害,其得分下降的越厉害;
论文中描述了两种惩罚函数,一种线性函数,一种高斯函数
线性函数,最简单的 就是 f = 1- iou()
高斯函数
惩罚函数的自变量是冗余样本与最大得分样本之间的IOU。
Soft-NMS也是一种贪婪算法,没有找到检测盒的全局最优重新评分。 检测盒的重新评分是以贪婪的方式进行的,因此那些具有较高局部评分的检测不会被抑制。
在soft NMS流程的最后也是有一个阈值,对于列表中所有检测结果的置信度低于阈值的检测结果 进行淘汰;
它仅需要对传统的NMS算法进行简单的改动且不增额外的参数。该Soft-NMS算法在标准数据集PASCAL
VOC2007(较R-FCN和Faster-RCNN提升1.7%)和MS-COCO(较R-FCN提升1.3%,较Faster-RCNN提升1.1%)上均有提升。 Soft-NMS具有与传统NMS相同的算法复杂度,使用高效。
Soft-NMS不需要额外的训练,并易于实现,它可以轻松的被集成到任何物体检测流程中。
优点:
1、Soft-NMS可以很方便地引入到object detection算法中,不需要重新训练原有的模型、代码容易实现,不增加计算量(计算量相比整个object detection算法可忽略)。并且很容易集成到目前所有使用NMS的目标检测算法。
2、soft-NMS在训练中采用传统的NMS方法,仅在推断代码中实现soft-NMS。 作者应该做过对比试验,在训练过程中采用soft-NMS没有显著提高。
3、NMS是Soft-NMS特殊形式,当得分重置函数采用二值化函数时,Soft-NMS和NMS是相同的。soft-NMS算法是一种更加通用的非最大抑制算法。
缺点:
soft-NMS也是一种贪心算法,并不能保证找到全局最优的检测框分数重置。除了以上这两种分数重置函数,我们也可以考虑开发其他包含更多参数的分数重置函数,比如Gompertz函数等。但是它们在完成分数重置的过程中增加了额外的参数。
soft NMS的pytorch代码实现
在Pytorch版本的Faster RCNN当中,roi_head.py文件中执行了nms处理,
所以我要做的是基于pytorch官方实现的nms函数的参数构建复现soft_nms函数。
#= 计算面积
def area_of(left_top, right_bottom):"""Compute the areas of rectangles given two corners.Args:left_top (N, 2): left top corner.right_bottom (N, 2): right bottom corner.Returns:area (N): return the area.return types: torch.Tensor"""hw = torch.clamp(right_bottom - left_top, min=0.0)return hw[..., 0] * hw[..., 1]
# 计算IOU
def iou_of(boxes0, boxes1, eps=1e-5):"""Return intersection-over-union (Jaccard index) of boxes.Args:boxes0 (N, 4): ground truth boxes.boxes1 (N or 1, 4): predicted boxes.eps: a small number to avoid 0 as denominator.Returns:iou (N): IoU values."""overlap_left_top = torch.max(boxes0[..., :2], boxes1[..., :2])overlap_right_bottom = torch.min(boxes0[..., 2:], boxes1[..., 2:])overlap_area = area_of(overlap_left_top, overlap_right_bottom)area0 = area_of(boxes0[..., :2], boxes0[..., 2:])area1 = area_of(boxes1[..., :2], boxes1[..., 2:])return overlap_area / (area0 + area1 - overlap_area)
# 自定义复现 soft_nms函数
def soft_nms(boxes, scores, score_threshold=0.001, sigma=0.5, top_k=-1):"""Soft NMS implementation.References:https://arxiv.org/abs/1704.04503https://github.com/facebookresearch/Detectron/blob/master/detectron/utils/cython_nms.pyxArgs:pytorch 官方实现的nms当中传入的是boxes:Tensor[N,4] scores:Tensor[N], N表示的是每张图片所有检测框的数量box_scores (N, 5): boxes in corner-form and probabilities.score_threshold: boxes with scores less than value are not considered.sigma: the parameter in score re-computation.scores[i] = scores[i] * exp(-(iou_i)^2 / simga)top_k: keep top_k results. If k <= 0, keep all the results.Returns:keep : Tensor 1维的tensor 保存的是boxes中保留下来的框的序号 比如 [2,1,0]int64 tensor with the indicesof the elements that have been keptby NMS, sorted in decreasing order of scores#picked_box_scores (K, 5): results of NMS.sc"""scores = scores.unsqueeze(1)box_scores = torch.cat((boxes,scores), dim=1) # 将boxes和scores合并为[N,5]的tensorpicked_box_scores = []while box_scores.size(0) > 0:max_score_index = torch.argmax(box_scores[:, 4]) # 取出得分最高的框的索引#print(box_scores[:, 4])cur_box_prob = box_scores[max_score_index, :].clone() # 拷贝得到cur_box_prob:得分最高框的x1,y1,x2,y2和score#print(cur_box_prob)picked_box_scores.append(cur_box_prob) # 将其填入到框中if len(picked_box_scores) == top_k > 0 or box_scores.size(0) == 1: # 所有框都遍历则退出breakcur_box = cur_box_prob[:-1] # 取出当前得分最高的框的四维坐标 x1,y1,x2,y2#print(cur_box)box_scores[max_score_index, :] = box_scores[-1, :]#print("box_scores[-1, :]")#print(box_scores[-1,:])box_scores = box_scores[:-1, :]ious = iou_of(cur_box.unsqueeze(0), box_scores[:, :-1])box_scores[:, -1] = box_scores[:, -1] * torch.exp(-(ious * ious) / sigma) # 用的是soft NMS论文中的高斯函数box_scores = box_scores[box_scores[:, -1] > score_threshold, :]if len(picked_box_scores) > 0:end_socre = torch.stack(picked_box_scores)[:,-1] # 先转为tensor,然后取出最后的得分一列keep = end_socre.sort(descending = True).indices # 根据降序排序 并取得排序前的indicesreturn keep # 返回所有检测框的得分排名,不进行淘汰#return torch.stack(picked_box_scores)else:return torch.tensor([])
softer NMS
论文:Bounding Box Regression with Uncertainty for Accurate Object Detection
地址:https://arxiv.org/abs/1809.08545
Comments: CVPR 2019
WBF
论文:Weighted Boxes Fusion: ensembling boxes for object detection models
论文 :Weighted boxes fusion: Ensembling boxes from different object detection models
地址:https://arxiv.org/abs/1910.13302
Comments: CVPR 2019、CVPR2021
NMS和Soft-NMS都排除了一些框,而WBF则使用了所有框。因此,它可以修复所有模型都预测不准确的情况。本案例如下图所示。NMS/Soft-NMS将只留下一个不准确的框,而WBF将使用所有预测的框来融合它。
代码已开源:https://github.com/ZFTurbo/Weighted-Boxes-Fusion
在这里插入代码片
目标检测中的NMS,soft NMS,softer NMS,Weighted Boxes Fusion相关推荐
- 目标检测中的LOU(交并比)和NMS(非极大值抑制)代码实现
1.LOU, 两个box框的交集比上并集,示意图如下所示: 代码如下所示: #假设box1的维度为[N,4] box2的维度为[M,4] def Lou(box1, box2):N = box1.si ...
- 目标检测中NMS和mAP指标中的的IoU阈值和置信度阈值
有时候路走的太远,会忘了为什么要出发. 学习亦如是 在目标检测中,经常看到置信度阈值和IoU阈值这两个关键参数,且NMS计算和mAP计算中都会有这两个,那它们的区别是什么?本文就这个问题做一次总结. ...
- 检测到目标服务器启用了trace方法_综述:目标检测中的多尺度检测方法
↑ 点击蓝字 关注极市平台作者丨SFXiang来源丨AI算法修炼营编辑丨极市平台 极市导读 本文从降低下采样率与空洞卷积.多尺度训练.优化Anchor尺寸设计.深层和浅层特征融合等多个方面入手,对目标 ...
- 综述 | 目标检测中的多尺度检测方法
本文从降低下采样率与空洞卷积.多尺度训练.优化Anchor尺寸设计.深层和浅层特征融合等多个方面入手,对目标检测中的多尺度检测方法进行了全面概述,并介绍了多尺度检测相关方法. 前面的话 传统卷积网络通 ...
- 目标检测中的样本不平衡处理方法——OHEM, Focal Loss, GHM, PISA
GitHub 简书 CSDN 文章目录 1. 前言 2. OHEM 3. Focal Loss 3.1 Cross Entropy 3.2 Balanced Cross Entropy 3.3 Foc ...
- 目标检测中的Label Assignment
©PaperWeekly 原创 · 作者|燕皖 单位|渊亭科技 研究方向|计算机视觉.CNN Label Assignment Label assignment 主要是指检测算法在训练阶段,如何给特征 ...
- 目标检测中的性能提升方法综述
文章目录 一.多尺度检测 1.什么是多尺度检测? 2.降低下采样率与空洞卷积 3.多尺度训练 4.优化Anchor尺寸训练 5.深层与浅层特征融合 6.SNIP,尺度归一化 7.TridentNet, ...
- 目标检测中特征融合技术(YOLO v4)(上)
目标检测中特征融合技术(YOLO v4)(上) 论文链接:https://arxiv.org/abs/1612.03144 Feature Pyramid Networks for Object De ...
- 目标检测中的Tricks
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 来自 | 知乎 作者 | roger 链接 | https: ...
最新文章
- 表达式树 java_Linq表达式树编译非平凡的对象常量,并以某种方式引用它们
- 任意角度人脸检测pcn
- 什么是延迟?怎样解决?—Vecloud微云
- python交互界面用图片当背景_wxPython实现窗口用图片做背景
- 当.NET遇到机器学习
- 架构师必须掌握的 10 条设计原则
- snapchat_我刚刚在Snapchat获得开发人员职位。
- 国科大高级人工智能-总结
- python调用ping命令_python调用系统命令ping
- OpenShift 4 - 在控制台中安装使用 Web Terminal
- Dart基础第10篇:类 静态成员 操作符 类的继承
- 这个教授的观点颇犀利
- Atitit 软件运行环境平台的变迁 attilax大总结 1.1.Native os时代 1.2.Vm时代 java net php 1.3.Script时代 js node。js 1.4.B
- Cisco2811配置Qos实现带宽分流
- unity3d的下载与安装
- android手机内存越来越小,手机内存越来越小怎么办 手机内存清理方法【步骤】...
- 技术中的形而上(一)----Linux下的usb四大家族
- ietester测试本地html,网站浏览器兼容测试软件–IETester
- 含论文基于JAVA户籍信息管理系统【数据库设计、论文、源码、开题报告】
- 在Word2019中,如何让回车符消失
热门文章
- 总有人会偷看你的朋友圈
- f2fs学习笔记 - 5. f2fs基本类图
- Dynamics 365 on-premises9.0版本开放下载,附上8.2升级9.0过程
- 大型仪器一般都是用计算机,问题:大型仪器一般都使用计算机进行控制,对该计算机除了在性能上能满足要求,在使用方面原则上有何要求。...
- 2020-09-07-中国人寿两年java岗位一面
- python-docx 不改变原文件调整段落行间距的问题
- springboot 模块引用_Spring Boot(三):SpringBoot多模块(module)项目搭建
- VB封装的WebSocket模块,拿来即用
- Storyboard Animations
- 最新的IP归属地数据库-最新IP地址数据库