OHEM算法

OHEM算法版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/u014380165/article/details/73148073…

大家好,又见面了,我是你们的朋友全栈君。

论文:Training Region-based Object Detectors with Online Hard Example Mining
论文链接:https://arxiv.org/abs/1604.03540

算法概述:

OHEM(online hard example miniing)算法的核心思想是根据输入样本的损失进行筛选,筛选出hard example,表示对分类和检测影响较大的样本,然后将筛选得到的这些样本应用在随机梯度下降中训练。在实际操作中是将原来的一个ROI Network扩充为两个ROI Network,这两个ROI Network共享参数。其中前面一个ROI Network只有前向操作,主要用于计算损失;后面一个ROI Network包括前向和后向操作,以hard example作为输入,计算损失并回传梯度。作者将该算法应用在Fast RCNN中,网络结构还是采用VGG16和VGG_CNN_M_1024,数据集主要采用VOC2007,VOC2012和COCO数据集。
算法优点:1、对于数据的类别不平衡问题不需要采用设置正负样本比例的方式来解决,这种在线选择方式针对性更强。2、随着数据集的增大,算法的提升更加明显(作者是通过在COCO数据集上做实验和VOC数据集做对比,因为前者的数据集更大,而且提升更明显,所以有这个结论)。

算法的测试结果:在pascal VOC2007上的mAP为78.9%,在pascal VOC2012上的mAP为76.3%。注意,这些结果的得到包含了一些小tricks,比如multi-scale test(测试时候采用多尺度输入),bounding box的不断迭代回归。

代码的github地址:https://github.com/abhi2610/ohem

算法详解:

如前所述,OHEM算法的核心是选择一些hard example作为训练的样本,那么什么样的样本是hard example呢?答案是:有多样性和高损失的样本。

在论文中作者主要是将OHEM算法用在Fast RCNN结构中。因此可以先回顾下Fast RCNN的结构。
Fast RCNN的结构图如下,主要包含两个部分:1、卷积网络。主要由多个卷积层和max pooling层组成;2、ROI pooling网络。主要包括ROI pooling层,一些全连接层和两个损失层。

这里写图片描述

hard example是根据每个ROI的损失来选择的,选择损失最大的一些ROI。但是这里有一个问题:重合率比较大的ROI之间的损失也比较相似。因此这里作者采用NMS(non-maximum suppresison)去除重合率较大的ROI,这里作者给的阈值是当IOU大于0.7就认为重合率较高,需去除。
注意,这里作者没有采用设定背景和目标样本数的比例方式处理数据的类别不平衡问题。因为如果哪个类别不平衡,那么这个类别的损失就会比较大,这样被采样的可能性也比较大。

那么具体要怎么把OHEM放在Fast RCNN网络结构中呢?可能首先会想到的做法是修改损失层,将没选择的ROI的loss设置为0。但是这种做法并不高效,因为即便很多ROI的loss都是0,也就是不需要更新梯度,但是这样仍需要给每个ROI都分配存储空间,并且每个ROI都需要后向传播。

因此就有了作者将OHEM应用在Fast RCNN的网络结构,如下图。这里包含两个ROI network,上面一个ROI network是只读的,为所有的ROI在前向传递的时候分配空间。下面一个ROI network则同时为前向和后向分配空间。
首先,ROI经过ROI plooling层生成feature map,然后进入只读的ROI network得到所有ROI的loss;然后是hard ROI sampler结构根据损失排序选出hard example,并把这些hard example作为下面那个ROI network的输入。

这里写图片描述

实际训练的时候,每个mini-batch包含N个图像,共|R|个ROI,也就是每张图像包含|R|/N个ROI。经过hard ROI sampler筛选后得到B个hard example。作者在文中采用N=2,|R|=4000,B=128。
另外关于正负样本的选择:当一个ROI和一个ground truth的IOU大于0.5,则为正样本;当一个ROI和所有ground truth的IOU的最大值小于0.5时为负样本。

对上面Fig2中的图例截图放大:

这里写图片描述

实验结果:

数据集采用pascal VOC2007,结构包括VGG_CNN_M_1024(VGGM)和VGG16。这里作者的对比了许多因素,比如1,2和3,4是对比是否有hard mining的差异,也就是一个是数据不平衡,一个是采用hard mining控制正负样本的比例;还有减小每个batch中的图像数量的影响等。其中7,8,9,10是采用所有ROI训练的标准Fast RCNN,因为增加了ROI数量的同时也要增大学习率,实验结果也还可以。综上,实验证明这些的影响都不大,最后作者加上OHEM明显提高了mAP。

这里写图片描述

然后是训练损失之间的对比,采用每个ROI的平均损失作为纵坐标,迭代次数为横坐标。可以看出如果bg_lo为0,也就是正负样本是不均衡的,那么损失是最大的。同时采用OHEM的损失是最小的。右边的图表和左边的图表的主要差别在于N=1,也就是min-batch的图像数量为1,损失上升了不少。

这里写图片描述

在计算时间和存储上是比Fast RCNN要差一些的。

这里写图片描述

最后是在VOC 2007数据集上各算法的mAP对比:除了OHEM本身的效果以外,也可以看出增加训练数据的效果以及在训练和测试时采用multi-scale,对bounding box采用multi-stage的回归等的效果。

这里写图片描述

以及在VOC2012上的对比:

这里写图片描述

一个更详细的关于multi-scale和iterative bbox regression的对比:可以看出multi-scale不管应用在训练还是测试阶段都有不错的提升效果,这个和很多采用特征融合的方式做目标检测的算法其实本质是一样的,比如SSD算法,FPN算法等等。还有就是Iterative bounding box regression也是非常有效,具体怎么实现还得看代码。

这里写图片描述

在COCO数据集上的对比可以参看论文,这里不再列出。

总结:

总的来讲,OHEM算法通过选择hard example的方式来训练,不仅解决了正负样本类别不均衡问题,同时提高了算法准确率,算是一个不错的trick。可以联系另一篇博文:A-Fast-RCNN算法,也是类似的关于利用hard example来提高mAP,只不过那篇算法是生成hard example,而这篇算法是选择hard example。

Caffe代码:

1、数据层

这里写图片描述

2、VGG16的卷积层

最后一层为conv5_3。

3、只读 ROI Network

包含一个ROI pooling层,两个常规全连接层(fc6,fc7),一个分类得分的全连接层,一个回归的全连接层,一个算分类概率的softmax层。

这里写图片描述

分类得分的全连接层:注意这里有个propagate_down参数设为false,也就是不回传梯度,后面的回归同理。

这里写图片描述

回归的全连接层:

这里写图片描述

算分类概率的softmax层:

这里写图片描述

4、hard ROI mining层

输入包括:分类概率的输出,回归的输出,最开始数据层的输出(rois,labels,targets和两个weights)

这里写图片描述

5、另一个ROI Network

注意这里的ROI pooling层和前面那个只读ROI Network的ROI pooling层的主要区别在于输入变成了rois_hard,即挑选后的hard example。然后依然是两个常规的全连接层(fc6,fc7),一个分类全连接层和一个回归全连接层。

这里写图片描述

看看ROI Network的分类全连接层:可以和前面只读ROI Network的分类全连接层做对比

这里写图片描述

6、分类损失层和回归损失层

(前者用SoftmaxWithLoss,后者用SmoothL1Loss)

这里写图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/139083.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • JVM参数汇总:JVM内存设置多大合适?Xmx和Xmn如何设置?[通俗易懂]

    JVM参数汇总链接:[#link](https://www.cnblogs.com/duanxz/p/3482366.html)一、java启动参数共分为三类:其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容…

  • 【转载】热电偶和热电阻的区别

    一、热电阻和热电偶的测量原理1、热电偶的测量原理热电偶工作原理是基于赛贝克(seeback)效应,即两种不同成分的导体两端连接成回路,如两连接端温度不同,则在回路内产生热电流的物理现象。热电偶由两根不同导线(热电极)组成,它们的一端是互相焊接的,形成热电偶的测量端(也称工作端)。将它插入待测温度的介质中;而热电偶的另一端(参比端或自由端)则与显示仪表相连。如果热电偶的测量端与参比端存在…

  • 爬虫之上传文件,request如何上传文件

    爬虫之上传文件,request如何上传文件

  • linux-fstab配置文件

    linux-fstab配置文件

  • 谷歌CTS测试(cta测试)

    CTS测试简介CTS兼容性测试的主要目的和意义在于使得用户在Android系统的应用过程中,有更好的用户体验,并展现出Android系统的优越特性;使得Android应用程序编写者更容易编写高质量的应用程序;充分展现AndroidMarket的优势,让获得CTS认证的终端得到AndroidMarket的使用许可.测试环境搭建测试包下载一共有两个包需要下载(CompatibilityTe

  • kworkers_work为什么名词

    kworkers_work为什么名词1.简介:    在spi驱动中用到了内核的线程,用的函数就是跟kthread_worker和kthread_work相关的函数,对于这两个名词的翻译,在网上暂时没有找到合适的,先翻译成线程内核线程相关的:工人和工作,这么直白的翻译是根据其工作原理相关的,本来想翻译成别的,一想到他的实现方式,直白的翻译,更能让人理解。    此部分介绍的函数主要在inc

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号