一分钟速学 | NMS, IOU 与 SoftMax
非极大抑制
NMS的英文是Non-maximum suppression的缩写。
简单的说,就是模型给出了多个重叠在一起的候选框,我们只需要保留一个就可以了。其他的重叠的候选框就删掉了,效果可见下图:

交并比
IoU的英文全称Intersection over Union,就是两个候选框区域的交集面积比上并集的面积,用下图可以理解:

hard-NMS
hard-nms其实就是经典版本的NMS的方法。就是根据模型给出每个box的置信度从大到小进行排序,然后保留最大的,删除所以与这个最大置信度的候选框的IoU大于阈值的其他候选框。
举个例子吧,现在有4个候选框:
(box1,0.8),(box2,0.9),
(box3,0.7),(box4,0.5)
我们把这四个候选框按照置信度从大到小排序:
box2>box1>box3>box4
现在我们保留置信度最大的候选框box2,然后计算剩下三个box与box2之间的IoU,如果IoU大于一个事先设置的阈值,那么就删除这个box。假设,阈值是0.5:
IoU(box1,box2)=0.1<0.5,保留;IoU(box3,box2)=0.7<0.5,删除;IoU(box4,box2)=0.2<0.5,保留;
现在还有box1和box4,然后再重复上面的过程,排序,然后删除。
下面是python实现的hard-NMS:
def hard_nms(box_scores, iou_threshold, top_k=-1, candidate_size=200):
"""
Args:
box_scores (N, 5): box的集合,N为框的数量,5即4(位置信息)+1(可能为物体的概率)
iou_threshold: 我们用IOU标准去除多余检测框的阈值
top_k: 保留多少个计算后留下来的候选框,如果为-1则全保留
candidate_size: 参与计算的boxes数量
Returns:
picked: 经过nms计算后保留下来的box
"""
scores = box_scores[:, -1] # 首先我们取出box中的最后一个元素也就是当前box检测到物体的概率
boxes = box_scores[:, :-1] # 取出box中的四个坐标(左上、右下)
picked = []
_, indexes = scores.sort(descending=True) # 按照降序排列所有的物体的概率,得到排序后在原数组中的索引信息 indexes
indexes = indexes[:candidate_size] # 只保留前 candidate_size 个 boxes 其余的不考虑了
while len(indexes) > 0:
current = indexes[0] # 每次取出当前在 indexes 中 检测到物体概率最大的一个
picked.append(current.item()) # 将这个最大的存在结果中
if 0 < top_k == len(picked) or len(indexes) == 1:
break
current_box = boxes[current, :] # 当前第一个也就是最高概率的box
indexes = indexes[1:]
rest_boxes = boxes[indexes, :] # 剩下其余的box
iou = iou_of( # 将当前的box与剩下其余的boxes用IOU标准进行筛选
rest_boxes,
current_box.unsqueeze(0),
)
indexes = indexes[iou <= iou_threshold]# 保留与当前box的IOU小于一定阈值的boxes,
return box_scores[picked, :]
如何计算iou的面积呢?实现方法在下面:
def area_of(left_top, right_bottom) -> torch.Tensor:
"""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.
"""
hw = torch.clamp(right_bottom - left_top, min=0.0)
return hw[..., 0] * hw[..., 1]
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 + eps)
soft-NMS
在密集目标检测任务中,hard-NMS会有一些问题,看下面的例子:

两个物体重叠起来了,但是根据hard-NMS绿色的框会被掉。
Soft-NMS就改动了一个地方。 在判断最高的置信度的box和其他box的IoU的时候增加了一个系数,可以更好的选择哪些才是多余的box。
对于hard-NMS来说,\(iou(M,b_i)<N_t\)的时候,保留,大于等于的时候删除,\(s\)表示置信度:

对于soft-NMS来说,\(iou(M,b_i)<N_t\)的时候,保留,大于的时候削减:

可以看出来,hard-NMS对于IoU大于阈值的候选框,直接把其置信度变成0,这样就相当于删除了这个box;但是soft-NMS的会根据IoU的大小,去适当的削减置信度,从而留下一些余地。
【如何削减】
这里有两种方法来降低重叠候选框的置信度:
- \(s=s(1-iou(M,b))\)简单的线性衰减;
- \(s = se^{-\frac{iou(M,b)^2}{\sigma}}\)指数衰减。其中sigma是常数,一般是0.5.
第二种方法更为常见。
下面是python来实现的soft-NMS,其实跟hard-NMS相比,就多了一行代码罢了:
def soft_nms(box_scores, score_threshold, sigma=0.5, top_k=-1):
"""Soft NMS implementation.
References:
https://arxiv.org/abs/1704.04503
https://github.com/facebookresearch/Detectron/blob/master/detectron/utils/cython_nms.pyx
Args:
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:
picked_box_scores (K, 5): results of NMS.
"""
picked_box_scores = []
while box_scores.size(0) > 0:
max_score_index = torch.argmax(box_scores[:, 4])
cur_box_prob = torch.tensor(box_scores[max_score_index, :])
picked_box_scores.append(cur_box_prob)
if len(picked_box_scores) == top_k > 0 or box_scores.size(0) == 1:
break
cur_box = cur_box_prob[:-1]
box_scores[max_score_index, :] = box_scores[-1, :]
box_scores = box_scores[:-1, :]
ious = iou_of(cur_box.unsqueeze(0), box_scores[:, :-1])
# 以下这句是新加的,如果没有这句就是Hard-NMS了
box_scores[:, -1] = box_scores[:, -1] * torch.exp(-(ious * ious) / sigma)
box_scores = box_scores[box_scores[:, -1] > score_threshold, :]
if len(picked_box_scores) > 0:
return torch.stack(picked_box_scores)
else:
return torch.tensor([])
一分钟速学 | NMS, IOU 与 SoftMax的更多相关文章
- 周根项《一分钟速算》全集播放&下载地址
点击图片就可以观看 ↓↓↓↓↓↓↓↓ 第1章:指算法 周根项<一分钟速算>第1章:指算法 第一节 对手的认识 周根项<一分钟速算>第1章:指算法 第二节 个位数比十位数大1乘以 ...
- 从头学pytorch(四) softmax回归实现
FashionMNIST数据集共70000个样本,60000个train,10000个test.共计10种类别. 通过如下方式下载. mnist_train = torchvision.dataset ...
- Hive基础语法5分钟速览
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行. 其优点是学习成本低,可以通过 ...
- [Machine Learning] logistic函数和softmax函数
简单总结一下机器学习最常见的两个函数,一个是logistic函数,另一个是softmax函数,若有不足之处,希望大家可以帮忙指正.本文首先分别介绍logistic函数和softmax函数的定义和应用, ...
- Logistic 分类器与 softmax分类器
首先说明啊:logistic分类器是以Bernoulli(伯努利) 分布为模型建模的,它可以用来分两种类别:而softmax分类器以多项式分布(Multinomial Distribution)为模型 ...
- 论文笔记之:Multiple Object Recognition With Visual Attention
Multiple Object Recognition With Visual Attention Google DeepMind ICRL 2015 本文提出了一种基于 attention 的用 ...
- face recognition[angular/consine-margin-based][L2-Softmax]
本文来自<L2-constrained Softmax Loss for Discriminative Face Verification>,时间线为2017年6月. 近些年,人脸验证的性 ...
- [论文理解] Acquisition of Localization Confidence for Accurate Object Detection
Acquisition of Localization Confidence for Accurate Object Detection Intro 目标检测领域的问题有很多,本文的作者捕捉到了这样一 ...
- 堆(c++)
5分钟速成堆 FBI⚠WARNING 本文要素过多 吐槽 堆是我迄今为止学过最简单的数据结构 我还没学会最小生成树.最短路时就学会了 堆实用高效,值得推荐 (如果你看完了这篇文章还不会,你可以直接Co ...
随机推荐
- GDI+ 双缓冲实现
早前曾为此问题在CSDN发帖求助(GDI+ 如何使用双缓冲绘制图像),得到了一个GDI+下较可行的方法,虽然绘制效果比直接绘制要好一些,不过还不能跟GDI的双缓冲方式比肩. 现在,我终于找到了一个 ...
- 为什么 group by后面 必须跟selecte 后面的除了聚集函数外的所有字段
如:SELECT store_name, SUM(Sales) FROM Store_Information GROUP BY store_name 可以而SELECT store_name, add ...
- Redis系列(八):发布与订阅
Redis的发布与订阅,有点类似于消息队列,发送者往频道发送消息,频道的订阅者接收消息. 1. 发布与订阅示例 首先,在本机开启第1个Redis客户端,执行如下命令订阅blog.redis频道: SU ...
- 【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值
[SpringCloud]Gateway 配置全局过滤器获取请求参数和响应值 实现Ordered接口getOrder()方法,数值越小越靠前执行,记得这一点就OK了. 获取请求参数RequestBod ...
- 好看css搜索框样式_分享8款纯CSS搜索框
最简单实用的CSS3搜索框样式,纯CSS效果无需任何javascript,其中部分搜索框在点击的时候有动画特效,搜索框的应用也是比较普通的,效果如下: 设计网站大全https://www.wode00 ...
- css div如何隐藏?
在我们平时布局网站的时候,想要把div进行隐藏,但是很多人不知道css控制div显示隐藏?下面我们来讲解一下css如何让div隐藏. 1.使用display:none来隐藏div 我们可以使用disp ...
- NOI Online #3 提高组 T1水壶 题解
题目描述 有 n 个容量无穷大的水壶,它们从 1∼n 编号,初始时 i 号水壶中装有 Ai 单位的水. 你可以进行不超过 k 次操作,每次操作需要选择一个满足 1≤x≤n−1 的编号 x,然后把 x ...
- Maven一键部署Springboot到Docker仓库,为自动化做准备
1 前言 前面<Springboot整合MongoDB的Docker开发,其它应用也类似>讲解了如何做Docker开发.如何把Springboot应用打包成一个镜像,但它是手动的,本文将讲 ...
- one-hot 编码
def onehot(labels): '''one-hot 编码''' #数据有几行输出 n_sample = len(labels) #数据分为几类.因为编码从0开始所以要加1 n_class = ...
- [apue] Linux / Windows 系统上只能建立不超过 PATH_MAX / MAX_PATH 长度的路径吗?
问题的提出 在处理文件系统路径的时候,我们一般会先开辟一块内存区,用来接收路径.或者拼接好路径传递给系统调用.这是因为路径在各个系统上都有最大长度限制,在 Windows 上这个值是 MAX_PATH ...