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

代码地址:https://github.com/yihui-he/KL-Loss

https://github.com/yihui-he/softer-NMS

作者Yihui He (何宜晖)的git主页

http://yihui-he.github.io/

参考:

https://www.cnblogs.com/fourmi/p/10721791.html

https://blog.csdn.net/lcczzu/article/details/86518615  (感觉这个讲的更详细)

预备知识:

KL散度(kullback-leibler divergence)

用途:比较两个概率分布的接近程度

在统计应用中,我们经常需要用一个简单的,近似的概率分布f来描述观察数据x.这个时候,我们需要一个量来衡量我们选择的近似分布f相比准确分布,究竟损失了多少信息量,这就是KL散度起作用的地方.

想要考察信息量的损失,就要先确定一个描述信息量的量纲,在信息论这门学科中,一个很重要的目标就是量化描述数据中含有多少信息.为此,提出了熵的概念,记作H,一个概率分布所对应的熵表达如下

如果我们使用log2作为底,熵可以被理解为,我们编码所有信息所需要的最小位数(minimum numbers of bits),(----怎么知道的?)

需要注意的是,通过计算熵,我们可以知道信息编码需要的最小位数,却不能确定最佳的数据压缩策略.怎样选择最优数据压缩策略,使得数据存储位数与熵计算的位数相同,达到最优压缩,是另一个庞大的课题.

KL散度的计算

现在,我们能够量化数据中的信息量了,就可以来衡量近似分布带来的信息损失了.KL散度的计算公式其实是熵计算公式的简单变形,在原有概率分布 p 上,加入我们的近似概率分布 q,计算他们的每个取值对应对数的差:

                                     (1)

对于连续系统来讲,就是

                  (2)

换句话说,KL散度计算的就是数据的原分布与近似分布的概率的对数差的期望值。
在对数以2为底时,log2 ,可以理解为“我们损失了多少位的信息”,写成期望形式

更常见的是以下形式:

现在,我们就可以使用KL散度衡量我们选择的近似分布与数据原分布有多大差异了。

论文贡献:

提出了learning NMS, KL损失,可以在训练时调整每个物体的边界方差,可以同时学习到边框回归和定位误差.特别的,为获取预测框的不确定性,本文把预测框建模为高斯分布,把ground-truth box建模为Dirac delta 函数.解决分类置信度和定位置信度不匹配问题.

这样做的优点有3个

(1) 可以有效捕捉数据集中的模糊标注.这些模糊标注所产生的损失比较小

(2) 学习到的偏差在后处理过程中很有用,本文提出了variance voting, 基于相邻box的位置,在NMS时, 它可以建议候选框的位置.

(3) 网络学习出的分布是可以解释的,因为它反映了预测框的不确定性,可能在自动驾驶或者机器人方面有潜在应用.

先看下传统的NMS的做法,一般会在NMS时候把得分较低,即置信度较低的那些box给舍弃掉,比如在retinanet中,就先会把那些得分<score_threshold=0.05的那些box舍弃,然后再nms,但实际上,有些box尽管得分低,但其位置是比较精确的,但他们是被舍弃了的.

    def _filter_detections(scores, labels):# threshold based on scoreindices = backend.where(keras.backend.greater(scores, score_threshold))#tf.greater()功能:比较scores, score_threshold两个值的大小,返回值:一个列表,元素值都是true和false#在用where返回索引值,总体返回了scores中那些值>score_threshold的元素的位置if nms:#truefiltered_boxes  = backend.gather_nd(boxes, indices)#先取出那些置信度大于阈值的boxfiltered_scores = keras.backend.gather(scores, indices)[:, 0]## perform NMS 调用了tensorflow.image.non_max_suppression执行最大值抑制,最多输出的300个nms_indices = backend.non_max_suppression(filtered_boxes, filtered_scores, max_output_size=max_detections, iou_threshold=nms_threshold)# filter indices based on NMSindices = keras.backend.gather(indices, nms_indices)#找出经过极大值抑制之后保留的box的索引号

改进:在本文中,针对上述情况,会采用var voting方法,根据相邻box来提升定位准确度.

soft nms及learning nms用于改进nms,相比删除所有类别分数较低的边界框,soft nms将衰减其他相邻框的检测分数.learning nms,提出学习一个新的网络只对boxes及分类分数进行nms处理.

边界框的增强,MR-CNN首次提出在迭代定位中将框进行merge操作,IOU-NET提出学习预测框与ground truth框之间的iou,然后,根据学习到的iou应用iou-nms,与IOU-NET不同,本文以概率分布的角度对位置方差进行单独学习.因此,本文可以对四个坐标的方差进行单独的学习,而不只是iou.var voting通过由kl损失学习到的相邻边界框的方差来对选择的框产生新的位置.

方法:添加定位置信度

边界框参数化: 本文提出独立的对框的边界进行回归,(x1,x2,x3,x4)代表边界框的4维数组.不同于r-cnn使用的(x,y,w,h),本文使用参数化的(x1,y1,x2,y2)

其中:(x1,y1,x2,y2)代表预测的box的坐标值

代表ground trueth的坐标值

代表anchor的坐标值

代表anchor的宽高

为网络预测偏差

备注:网络本质上不是预测(x1,y1,x2,y2),而是预测偏差值,通过后处理再得到预测值(x1,y1,x2,y2),这个一般观察retinanet的代码可以看出来,比如下面的bbox_transform_inv()函数,就是一个后处理操作,其返回值pred_boxes代表的是预测值(x1,y1,x2,y2),神经网络本身的输出是偏差值deltas,就是我们在这里的

问题: 为什么要除以边框的w,h呢?

程序实现:keras_retinanet/backend/common.py/bbox_transform_inv()

def bbox_transform_inv(boxes, deltas, mean=None, std=None):""" Applies deltas (usually regression results) to boxes (usually anchors).Before applying the deltas to the boxes, the normalization that was previously applied (in the generator) has to be removed.The mean and std are the mean and std as applied in the generator. They are unnormalized in this function and then applied to the boxes.Argsboxes : np.array of shape (B, N, 4), where B is the batch size, N the number of boxes and 4 values for (x1, y1, x2, y2).deltas: np.array of same shape as boxes. These deltas (d_x1, d_y1, d_x2, d_y2) are a factor of the width/height.mean  : The mean value used when computing deltas (defaults to [0, 0, 0, 0]).std   : The standard deviation used when computing deltas (defaults to [0.2, 0.2, 0.2, 0.2]).ReturnsA np.array of the same shape as boxes, but with deltas applied to each box.The mean and std are used during training to normalize the regression values (networks love normalization)."""if mean is None:mean = [0, 0, 0, 0]if std is None:std = [0.2, 0.2, 0.2, 0.2]#mean [0 0 0 0].std [0.2 0.2 0.2 0.2], 问题,说这个均值和偏差是在generator中确定出来的,怎么没见到?width  = boxes[:, :, 2] - boxes[:, :, 0] #anchors中都是一个个的box,算出这些box的宽,height = boxes[:, :, 3] - boxes[:, :, 1]#算出这些box的高x1 = boxes[:, :, 0] + (deltas[:, :, 0] * std[0] + mean[0]) * width #这里是在原来的anchor的基础上,对box进行位置精调,y1 = boxes[:, :, 1] + (deltas[:, :, 1] * std[1] + mean[1]) * height#x1_new=x1+0.2*delta*widthx2 = boxes[:, :, 2] + (deltas[:, :, 2] * std[2] + mean[2]) * widthy2 = boxes[:, :, 3] + (deltas[:, :, 3] * std[3] + mean[3]) * heightpred_boxes = keras.backend.stack([x1, y1, x2, y2], axis=2)return pred_boxes

因为可以独立的回归每个坐标值,为简便起见,我们记坐标值为x.我们的目标是在估计box的位置的同时,估计这个box定位的准确度.

首先,除了预测box的位置之外,网络会预测一个位置的概率分布,尽管概率分布会是一个比较复杂的多变量的高斯分布,在本文中,我们假设四个坐标是分布独立的,定义了一个单变量的高斯分布:

这里不太懂x和都代表什么意思?

上述分布由一个全连接层预测得到,ground truth box也可以建模称为一个高斯分布,可以看作的高斯分布,为

3.2 基于kl loss的box 回归

目标检测的目的找到,使得在N个样本上的预测分布与真实分布之间的KL散度最小,根据前边的预备知识可知,这两个分布之间的散度越小,预测值就越接近真实值.

我们把KL散度作为box回归的损失函数.类别损失保持不变,仍然为,则对一个样本来讲,根据预备知识中(2)式可知,其带来的损失为:

                            (3)

根据冲激信号的筛选特性(忘记的同学去翻下大二学过的信号分析与处理这门课啊)

可知(3)式可化简为:

                    (4)

问题:这里的,不是意味这损失值是无穷大吗?

当预测的 不准确时,我们期望网络的预测值 比较大, 因此就会比较小,因为不依赖网络的预测值,因此

当网络的预测值时, ,KL LOSS 就退化为标准的欧氏损失

根据(4)将函数对于变量 进行求导可得:

       (5)

可以看出,网络的预测值在分母位置,在训练初期,因为网络的权重一般初始化在0的附近,所以会导致(5)的值比较大,即发生梯度爆炸现象,为避免这个问题,实际操作中,我们的网络不直接预测,而是预测 ,则.

                        (6)

时,我们采取近似与smooth L_1 损失,

初始化: 把预测 的全连接层的权重初始化为高斯分布(均值=0,方差=0.0001)

问题: 网络不直接预测,而是预测 就能解决梯度爆炸问题吗?

答: 沿改进后的(6)对变量 进行求导可得:

       (5)

可以看出,即使网络预测值(5)中两个算式值都不会出现无穷大的情况,解决了梯度爆炸问题.

3.3 差异投票

当我们得到预测的位置偏差后,比较直观的想法是根据学习到的偏差值对候选框的位置进行投票,如下表所示,我们改动了NMS的3行代码:

Algorithm 1 var voting

B 是 N×4 初始检测框,S包含了每个框的置信度得分, C是 N×4 的预测的偏差值(相当于我们retinanet程序中的delta),D是最终的检测结果, 是可调节参数, 蓝色字体代表的是soft-NMS, 绿色字体代表差异投票

改进的地方:

在标准的NMS或soft-NMS过程中,我们对被选中的框进行投票,选择好最高得分框b=后,会根据它自己和相邻框计算这个框b的更新位置.受soft-NMS的启发,我们会对离框b最近且具有比较小的不确定性的框给予比较大的权重.举例来讲,设x为坐标, 是第i个box的坐标,则框b按照以下规则进行更新:

时,

                  (6)

从(6)可以看出,有两种类型的box会获得较低的权重:

(1):若网络的预测值较大的box,因为从(6)可以看出,框的权重= 就会比较小.

(2)与框b的iou较小的那些box,从(6)的第一个算式可以看出iou越小,p_i就会越小, 框的权重= 就会越小.

(3)更新box的位置时,没有用到其置信度得分,并且那些iou较大的box没有被删除,而是用来更新了框b的位置.

4. 实验部分

本文用了4块GPU来训练,并且根据参考文献[15],对batch size 进行调节,可调节参数.

5.代码实现

3.3代码分析

softerNMS的开源代码在https://github.com/yihui-he/softerNMS。

在softer-NMS/detectron/core/test.py有Softer-NMS(配置cfg.STD_NMS), Soft-NMS(配置cfg.TEST.SOFT_NMS.ENABLED)以及NMS的实现。

在softer-NMS/detectron/utils/py_cpu_nms.py文件有Softer-NMS的具体实现,加权求平均在47-48行代码实现:

假设现在有boxes=[A1,A2,A3,A4,A5,A6],其位置置信度=confidence[c1,c2,c3,c4,c5,c6]

step1: 计算所有box两两之间的iou,并存储到了矩阵IOUS中

step2: 找出置信度最高的box, 假设为A4,记录其位置maxpos=3,(注意计算机中,A1在第一个位置,它的索引值=0)

maxpos = dets[i:N, 4].argmax()#找出所有的box中,置信度最高的哪一个, maxpos就是这个置信度最高的box所在的位置索引

step3: 把具有最高置信度的box=A4放在boxes的第一行,原来第一行A1放在原来具有最高置信度的位置,即boxes更新为[A4,A2,A3,A1,A5,A6]

 dets[[maxpos,i]] = dets[[i,maxpos]]#第一轮循环时, 把具有最高置信度的哪个box放在第一行

step4: 对应的,因为step3调整了box的位置,所以需要对应调整位置置信度的位置=confidence[c4,c2,c3,c1,c5,c6]

 confidence[[maxpos,i]] = confidence[[i,maxpos]]

step5: 对应的,因为step3调整了box的位置,所以需要更新IOUS的值,这里需要注意,行,列位置都要调整

 ious[[maxpos,i]] = ious[[i,maxpos]]ious[:,[maxpos,i]] = ious[:,[i,maxpos]]

step6: 考虑其他box A4的iou, 若大于给定阈值,就把这些box的位置存储下来,记录到ovr_bbox,假设A3,A5满足条件,其他的都不满足,此时ovr_bbox=[2,4]

ovr_bbox = np.where((ious[i, i:N] > thresh))[0] + i##第一轮循环时,只考虑与最大值信度box相互之间iou>给定阈值的那些box

step7: 根据公式,计算p值,

p = np.exp(-(1-ious[i, ovr_bbox])**2/cfg.STD.IOU_SIGMA)

注意程序实现时,ious都是做的矩阵运算,所以计算结果p中是一个行向量,计算了A3,A5与A4的pi值,计算结果

,其中参数cfg.STD.IOU_SIGMA是自己配置的参数=0.02

step8:更新A4的4个坐标值(x1,y1,x2,y2),更新公式为

dets[i,:4] = p.dot(dets[ovr_bbox, :4] / confidence[ovr_bbox]**2) / p.dot(1./confidence[ovr_bbox]**2)#加权更新x1,y1,x2,y2,但这里为什么没有#求和呢?

完整代码:

def soft(dets, confidence=None, ax = None,softer=True):thresh = 0.6 #.6score_thresh = .7sigma = .5 N = len(dets)x1 = dets[:, 0].copy()y1 = dets[:, 1].copy()x2 = dets[:, 2].copy()y2 = dets[:, 3].copy()areas = (x2 - x1 + 1) * (y2 - y1 + 1)ious = np.zeros((N,N))for i in range(N):xx1 = np.maximum(x1[i], x1)yy1 = np.maximum(y1[i], y1)xx2 = np.minimum(x2[i], x2)yy2 = np.minimum(y2[i], y2)w = np.maximum(0.0, xx2 - xx1 + 1)h = np.maximum(0.0, yy2 - yy1 + 1)inter = w * hovr = inter / (areas[i] + areas - inter)ious[i,:] = ovri = 0while i < N:maxpos = dets[i:N, 4].argmax()maxpos += idets[[maxpos,i]] = dets[[i,maxpos]]areas[[maxpos,i]] = areas[[i,maxpos]]confidence[[maxpos,i]] = confidence[[i,maxpos]]ious[[maxpos,i]] = ious[[i,maxpos]]ious[:,[maxpos,i]] = ious[:,[i,maxpos]]ovr_bbox = np.where((ious[i, :N] > thresh))[0]avg_std_bbox = (dets[ovr_bbox, :4] / confidence[ovr_bbox]).sum(0) / (1/confidence[ovr_bbox]).sum(0)if softer:dets[i,:4] = avg_std_bboxelse:assert(False)areai = areas[i]pos = i + 1while pos < N:if ious[i , pos] > 0:ovr =  ious[i , pos]dets[pos, 4] *= np.exp(-(ovr * ovr)/sigma)if dets[pos, 4] < 0.001:dets[[pos, N-1]] = dets[[N-1, pos]]areas[[pos, N-1]] = areas[[N-1, pos]]confidence[[pos, N-1]] = confidence[[N-1, pos]]ious[[pos, N-1]] = ious[[N-1, pos]]ious[:,[pos, N-1]] = ious[:,[N-1, pos]]N -= 1pos -= 1pos += 1i += 1keep=[i for i in range(N)]return dets[keep], keep

softer nms论文阅读Bounding Box Regression with Uncertainty for Accurate Object Detection相关推荐

  1. softer-nms论文学习详解(Bounding Box Regression with Uncertainty for Accurate Object Detection)

    <Bounding Box Regression with Uncertainty for Accurate Object Detection> 论文地址: https://arxiv.o ...

  2. 【CV论文阅读】:Rich feature hierarchies for accurate object detection and semantic segmentation...

    R-CNN总结 不总结就没有积累 R-CNN的全称是 Regions with CNN features.它的主要基础是经典的AlexNet,使用AlexNet来提取每个region特征,而不再是传统 ...

  3. 【论文阅读】Point-GNN: Graph Neural Network for 3D Object Detection in a Point Cloud

    最近在看3d目标检测的文章,感觉看完东西还是要记一下自己的想法,尤其是有思考的文章. 论文题目:Point-GNN: Graph Neural Network for 3D Object Detect ...

  4. 论文阅读笔记:(2021.10 CoRL) DETR3D: 3D Object Detection from Multi-view Images via 3D-to-2D Queries

    论文地址:DETR3D: 3D Object Detection from Multi-view Images via 3D-to-2D Queries | OpenReviewWe introduc ...

  5. 目标检测论文阅读:Cascade R-CNN: Delving into High Quality Object Detection(CVPR2018)

    Cascade R-CNN: Delving into High Quality Object Detection(CVPR2018) 论文链接:https://arxiv.org/abs/1712. ...

  6. [论文阅读] Stereoscopically Attentive Multi-scale Network for Lightweight Salient Object Detection

    论文地址:https://dx.doi.org/10.1109/TIP.2021.3065239 代码:https://mmcheng.net/SAMNet 发表于:TIP 2021 Abstract ...

  7. 论文阅读:Hit-Detector: Hierarchical Trinity Architecture Search for Object Detection

    简介: Hit-Detector是第一个可以同时搜索检测网络的backbone.neck和head的NAS,在低算力.低参数量的情况下得到高mAP. 论文链接 代码链接 前言: NAS在图像识别任务中 ...

  8. 论文精读:R-CNN:Rich feature hierarchies for accurate object detection and semantic segmentation...

    1.论文核心 我们提出了一种简单且可扩展的检测算法,相对于之前对VOC2012的最佳结果,它将平均平均精度(mAP)提高了30%以上--实现了53.3%的mAP.我们的方法结合了两个关键的见解:(1) ...

  9. [论文阅读] A Simple Pooling-Based Design for Real-Time Salient Object Detection

    论文地址:https://arxiv.org/abs/1904.09569 代码:http://mmcheng.net/poolnet/ 发表于:CVPR'19 Abstract 我们通过研究如何扩大 ...

最新文章

  1. mysql-5.7.24-winx64忘记密码该咋解决
  2. 你了解 Java 的 jstat 命令吗?
  3. Windows 查看所有进程命令tasklist
  4. [转载]ASP.NET中IsPostBack详解
  5. MySQL主备复制原理、实现及异常处理
  6. wordpress漏洞上传php文件夹,WordPress Asset-Manager PHP文件上传漏洞
  7. Android 第十六课 使用LitePal查询数据
  8. python框架源码学习
  9. java生成pdf417_生成PDF417的JAVA包.rar
  10. android 常用命令随手记
  11. 跨平台开发与原生开发优劣比较
  12. 数据结构图文解析之:二分查找及与其相关的几个问题解析
  13. java switch finally_Java中的switch疑问
  14. 阿里云centos7.4安装并部署svn1.10.0版本(配置多仓库,加入开机自启动)
  15. 数据脱敏 Data Masking
  16. 移动手机网站H5页面如何一键打开拉起微信小程序快速关注公众号功能?
  17. 用脚本语言对 Excel 分组汇总
  18. 计算机二级各个科目的区别,计算机二级考试的各个科目的内容及区别
  19. Windows用户管理、文件权限、本地策略、组策略说明
  20. python中文版加密解密_python加密与解密

热门文章

  1. 1.Cocos跑酷游戏——List工具篇
  2. 全球与中国回音壁市场深度研究分析报告
  3. 京东智能供应链平台应急场景实践
  4. FPGA中利用ICAP原语实现Multiboot功能-总结篇
  5. 重要信息:如何扫描和删除恶意病毒
  6. android线刷软件,android线刷一般用什么软件?哪一个好用一些?
  7. 当黑夜自此笼罩-白夜行之感想一二
  8. 中医济世促醒汤-----发作性睡病
  9. (百度之星资格赛) 度度熊与邪恶大魔王 (dp)
  10. html实现多图片上传并预览,【前端预览】实现多张上传图片预览查看