目标检测(Object Detection)—— RetinaNet介绍
1 概述
- 主流目标检测框架可分成两类:①one-stage方法,以YOLO、SSD为代表;②two-stages方法,以RCNN系列为代表。前者检测速度快,但检测精度较低;后者检测速度慢,但是精度较高。
- 为什么one-stage方法不如two-stages方法? 这是RetinaNet的作者提出的问题。作者对此做出的回答是:one-stage方法生成的proposals中正负样本极不均衡造成了one-stage方法检测精度不如two-stages。
- 下面就来看看为什么样本不均衡是上述问题的答案,以及作者是如何证明这个结论的。看完之后,你一定会深深的被这种看似简单的答案后作者对问题的深刻分析和对主要矛盾的精准预判而叹服。
RetinaNet是2018年Facebook AI团队在目标检测领域新的贡献,该篇论文获得了计算机视觉三大顶会之一ICCV 2017年度最佳学生论文奖。它的重要作者名单中Ross Girshick与Kaiming He赫然在列。来自Microsoft的Sun Jian团队与现在Facebook的Ross/Kaiming团队在当前视觉目标分类、检测领域有着北乔峰、南慕容一般的独特地位。这两个实验室的文章多是行业里前进方向的指示牌。
2 one-stage与two-stages
- two-stages方法解决正负样本分布不均衡的问题可分为两个方面:一方面,在生成proposals时,就滤除了很多负样本(背景),另一方面,生成proposals后,常常在一个batch中固定正负样本的比例(常见正负样本的比例为1:3),或者采用OHEM(Online hard example mining)方法再次过滤proposals。
- one-stage方法会在输入图像上密集生成具有不同大小和长宽比的proposals。在解决正负样本分布不均衡的问题时,one-stage的方法也会采用上述two-stages的方法,可是这依然无法有效的解决这个问题,最后用于计算误差值的proposals中还是会有很多负样本,这些负样本会主导误差值,从而使反向传播后的参数更新沿着不那么正确的方向进行。
- 对于one-stage存在的这种问题,作者对标准交叉熵损失函数进行了改造,提出了称之为focal loss的损失函数。通过使用这种损失函数,one-stage方法在保持了检测速度的同时又实现了比two-stages方法更高的检测精度,这也是这篇论文的最大贡献。
3 Focal loss
- 作者改造后的损失函数如下(为了便于说明问题,以二分类为例,多分类问题简单推广就可以):
其中,pt表示proposal预测为正类的置信概率,γ是个可以设置的参数。
- 不同γ值下focal loss的函数值如下:
γ=0时focal loss即为标准的交叉熵损失函数(cross entropy loss, CE)。
可以看到,相比标准交叉熵损失函数,focal loss在置信概率更大的时候的值更接近零。这是什么意思呢?对某个样本,概率值更大,说明有更大的概率分类正确,理所应当的,我们就应该赋予这个样本更小的loss值,目的是在反向传播更新参数时,让参数向着可以使那些置信概率较低的样本的loss值下降的方向更新。也就是说,通过使用focal loss,每次更新参数时,尽量根据难分类的样本(置信概率)计算出的损失更新参数,对那些很好分类的样本(easy negative examples),基本不对loss做出贡献。
- 实际应用时,又在focal loss中增加了一个参数,如下:
4 RetinaNet网络
4.1 网络结构
- 为了证明作者做出的论断及focal loss的优越性,作者使用了一个简单的网络结构,如下:
对该网络,需要注意的是:
①网络以ResNet为基本框架,又采用了FPN结构,对FPN的每层特征,采用了两个全卷积子网络分别完成分类和回归
②边框回归时,不考虑边框的类别
③两个子网络不共享参数,每个子网络对FPN网络每一层共享参数
4.2 训练过程
- 每次前向传播得到proposals后,只对FPN网络每层(共5层)依据loss排序后的前1000个propsals计算总的损失值。完成网络的训练后,最终的检测结果是这5000个proposals使用NMS算法后的结果。
- 训练时只在分类网络中使用focal loss,回归网络使用正常的回归损失。
- 分类网络应用focal loss时,使用上述5000个proposals的loss,求和,再进行标准化(如果不标准化,会发生梯度爆炸现象)。标准化的方式是将总的focal loss值除以与ground truth匹配的proposals的数目。
- 值得注意的是,对分类子网络的最后一个卷积层,在初始化参数时,对偏置bias设置如下:请先点击这里
这里为什么不将bias设置为0呢?归根结底,还是因为正负样本分布不均衡的问题。从本质上讲,用于反向传播更新参数的误差反映的是当前网络参数与理想网络参数间的距离。one-stage方式产生的proposals绝大部分是负样本,如果bias设置为0,那么刚开始训练时很多负样本会被错误分类成正类,从而使误差进行无谓的增大。将bias按这种方式设置,就是在告诉网络,我期望proposals被分类成负类样本,这样就可以稍微缓解大量负样本带来的影响。
5 实验
- 使用标准交叉熵损失函数,测试不同α值下网络的性能
- 不同γ值与α值下网络的性能
- anchor boxes的不同尺寸和比例带来的影响
- 使用focal loss和使用OHEM的网络性能的对比
- ResNet不同版本和不同尺寸的输入图像下RetinaNet网络的性能
- 与其它方法对比
6 总结
- 大道至简,我想这是没错的。一个看似简单的改变,居然可以带来如此效果,值得深思。
- 另一方面,看似简单的改动,其背后实则是对问题的深刻剖析,只有对主流方法庖丁解牛般熟悉,才能天才般的提出直击主要矛盾的假设。
- 回到网络本身,初始化网络时使用有偏初始化,挺有创意的,在解决相关问题时值得借鉴。