kaiming!!!神一样的存在!!!
论文地址:https://arxiv.org/abs/1708.02002
MXnet代码地址:https://github.com/miraclewkf/FocalLoss-MXNet
知乎讨论:如何评价 Kaiming 的 Focal Loss for Dense Object Detection?
记得查看;http://www.sohu.com/a/225849848_473283
摘要
目前准确度最高的目标检测器采用的是一种常在 R-CNN 中使用的 two-stage 方法,这种方法将分类器应用于一个由候选目标位置组成的稀疏样本集。相反,one-stage 检测器则应用于一个由可能目标位置组成的规则密集样本集,而且更快更简单,但是准确度却落后于 two-stage 检测器。在本文中,我们探讨了造成这种现象的原因。
我们发现,在训练密集目标检测器的过程中出现的严重的 foreground-background 类别失衡,是造成这种现象的主要成因。我们解决这种类别失衡(class imbalance)的方案是,重塑标准交叉熵损失,使其减少分类清晰的样本的损失的权重。Focal Loss 将训练集中在一个稀疏的困难样本集上,并防止大量简单负样本在训练的过程中淹没检测器(主导了梯度的更新方向,掩盖了重要的信息)。为了评估该损失的有效性,我们设计并训练了一个简单的密集目标检测器—RetinaNet。试验结果证明,当使用 Focal Loss训练时,RetinaNet 不仅能赶上 one-stage 检测器的检测速度,而且还在准确度上超越了当前所有最先进的 two-stage 检测器。
图1:我们提出了一种新的损失函数 Focal Loss(焦点损失),这个损失函数在标准的交叉熵标准上添加了一个因子 (1- pt) γ 。设定 γ > 0 可以减小分类清晰的样本的相对损失(pt > .5),使模型更加集中于困难的错误分类的样本。试验证明,在存在大量简单背景样本(background example)的情况下,我们提出的 Focal Loss 函数可以训练出准确度很高的密集对象检测器。
1 简介
当前最优秀的目标检测器使用的都是一种由 proposal 驱动的 two-stage 机制。和在 R-CNN 框架中一样,第一个阶段生成一个候选目标位置组成的稀疏样本集,第二个阶段使用一个卷积神经网络将各候选位置归至 foreground 类别或 background 类别。随着一些列的进步,这个 two-stage 框架可以在难度极高的 COCO benchmark 上一直保持很高的准确度。
既然 two-stage 检测器的结果这么好,那么一个很自然的问题是:简单的 one-stage 检测器是否也能实现类似的准确度? one-stage 检测器主要应用在一个由目标位置(object locations)、尺度(scales)和长宽比(aspect ration)组成的规则密集样本集上。最近对 one-stage 检测器(如 YOLO 和 SSD)进行的试验都得出了优秀的结果,相比最优秀的 two-stage 方法,得出的检测器检测速度更快,而且能实现 10%- 40% 的准确度。
本文进一步提高了 one-stage 检测器的性能:我们设计出了一个 one-stage 目标检测器,并首次达到了更复杂的 two-stage 检测器所能实现的最高 COCO 平均精度,例如(特征金字塔网络,Feature Pyramid Network ,FPN)或 Faster R-CNN 的 Mask R-CNN 变体。我们发现训练过程中的类别失衡是阻碍单阶段检测器实现这个结果的主要障碍,并提出了一种新的损失函数来消除这个障碍。
通过两阶段的级联(cascade)和采样的启发(sampling heuristics),我们解决了像 R-CNN 检测器的类别失衡问题。候选阶段(如Selective Search、EdgeBoxes 、DeepMask 和 RPN)可以快速地将候选目标位置的数目缩至更小(例如 1000-2000),过滤掉大多数背景样本。在第二个分类阶段中,应用抽样启发法(sampling heuristics),例如一个固定的前景样本背景样本比(1:3),或者在线困难样本挖掘法(online hard example mining),在 foreground 样本和 background 样本之间维持可控的平衡。
相反,one-stage 检测器则必须处理一个由图像中规则分布的候选目标位置组成的大样本集。在实践中,目标位置的总数目通常可达 10 万左右,并且密集覆盖空间位置、尺度和长宽比。虽然还可以应用类似的抽样启发法,但是这些方法可能会失效,如果容易分类的背景样本仍然支配训练过程话。这种失效是目标识别中的一个典型问题,通常使用 bootstrapping 或困难样本挖掘来解决。
在本文中,我们提出了一个新的损失函数,它可以替代以往用于解决类别失衡问题的方法。这个损失函数是一个动态缩放的交叉熵损失函数,随着正确分类的置信度增加,函数中的比例因子缩减至零,见图1。在训练过程中,这个比例因子可以自动地减小简单样本的影响,并快速地将模型集中在困难样本上。
试验证明,Focal Loss 函数可以使我们训练出准确度很高的 one-stage 检测器,并且在性能上超越使用抽样启发法或困难样本挖掘法等以往优秀方法训练出的 one-stage 检测器。最后,我们发现 Focal Loss 函数的确切形式并不重要,并且证明了其他实例(instantiations)也可以实现类似的结果。
为了证明这个 Focal Loss 函数的有效性,我们设计了一个简单的 one-stage 目标检测器—RetinaNet,它会对输入图像中目标位置进行密集抽样。这个检测器有一个高效的 in-network 特征金字塔(feature pyramid),并使用了锚点盒(anchor box)。我们在设计它时借鉴了很多种想法。RetinaNet 的检测既高效又准确。我们最好的模型基于 ResNet-101- FPN 骨干网,在 5fps 的运行速度下,我们在 COCO test-dev 上取得了 39.1 AP 的成绩,如图2 所示,超过目前公开的单一模型在 one-stage 和 two-stage 检测器上取得的最好成绩。
图2:横坐标是检测器在COCO test-dev 上的检测速度(ms),纵坐标是准确度(AP: average precision)的比值。在 Focal Loss 的作用下,我们简单的 one-stage RetinaNet 检测器打败了先前所有的 one-stage 检测器和 two-stage 检测器,包括目前成绩最好的 Faster R-CNN系统。我们在图 2 中按 5 scales(400-800 像素)分别用蓝色圆圈和橙色菱形表示了 ResNet-50-FPN 和 ResNet-101-FPN 的 RetinaNet 变体。忽略准确度较低的情况(AP < 25),RetinaNet 的表现优于当前所有的检测器,训练时间更长时的检测器达到了 39.1 AP 的成绩。
2 相关工作
Classic Object Detectors:滑动窗口。HOG(方向梯度直方图,Histogram of oriented gradient)。DPMs。
Two-stage Detectors: Selective Search,R-CNN,RPN(Region Proposal Networks)。Faster R-CNN。
One-stage Detectors: OverFeat, SSD, YOLO。 SSD在 AP上低了10-20%。最近two-stage方法通过减少输入图片的分辨率和proposal的数量增加速度,one-stage方法训练用更大的计算budget。本文的目的是理解one-stage方法可以匹配或者超过two-stage的精度同时标尺相似或者更快的速度。RetinaNet与之前方法有很多相似,像RPN的anchor和在SSD和FPN中的feature pyramid。
Class Imbalance:之前的one-stage方法训练时都面临类别不平衡问题。要评估10^4-10^5候选定位,但是只有很少包含对象。类别不平衡导致两个问题:
(1)训练不高效,大多数位置都是easy negtive,贡献很少的有用学习信号(useful learning signal)。
(2)easy negative 会overwhelm主导训练,导致退化的模型(degenerate models)。
常用的解决思路是用hard negative mining。难分类负样本挖掘。在训练时采样难分样本,或者更复杂的采样、重新分配权重计划。Focal loss不用sample,也不会让easy negative主导损失和梯度。
Robust Estimation:Focal loss是通过降低inliers(easy examples)的权值,这样它们对总的loss的贡献很小(即使它的值很大)。换句话说,focal loss有robust loss的对立作用,它将训练集中在hard example的稀疏集合上面。(it focuses training on a sparse set of hard examples)
解释inliers:
如图所示,给定一些点(红+绿+黑)要求用这些数据点拟合椭圆以ransac拟合椭圆为例,可以看出,红色椭圆为拟合结果,红色点是由ransac随机选择用来拟合的数据点黑色点是除红色点外距离椭圆距离小于某一阈值的点,而绿色点是距离椭圆距离大于这一阈值的点那么,红色+黑色点即为内点,而绿色点为外点。
3. Focal Loss
Focal Loss是被设计来针对one-stage object detection方案的,其中在训练中有在前景和背景类别之间的完全不平衡存在(1:1000)。先从对于binary classification的交叉熵(CE,cross entropy)损失来介绍Focal Loss。
移除y∈{-1,1}是ground truth class,p∈[0,1]是模型对于标签y=1的估计概率。
为了方便标记,记Pt:
重写
当大量的easy examples叠加,这些小的损失值可以主导那些稀少的类。
针对class imbalance的常用方法是用一个权重参数α∈[0,1]对于类1,1-α对于类-1。实际应用上,α一般被设定为类频率的逆或者作为超参数,通过交叉验证设定。为了标记方便,定义αt,相似的定义Pt。α-balanced CE loss:
训练时遇到很大的类别不平衡会主导交叉熵损失。易分负样本在梯度和损失中占据主导地位。而α平衡了正负样本的重要性,它不会区别易分样本和难分样本。与之不同,作者将损失函数变形降低易分样本的权重,专注于训练难分负样本。
更加形式化地来说,作者加了(1-Pt)^γ到交叉熵上。γ是可以可以调节的专注参数γ>0。这样,Focal loss定义为:
γ不同时的图。
说一下Focal loss的属性:
(1)当一个样例被误分类,那么Pt很小,那么调制因子(1-Pt)接近1,损失不被影响;当Pt→1,因子(1-Pt)接近0,那么分的比较好的(well-classified)样本的权值就被调低了。
(2)专注参数γ平滑地调节了易分样本调低权值的比例。γ增大能增强调制因子的影响,实验发现γ取2最好。
直觉上来说,调制因子减少了易分样本的损失贡献,拓宽了样例接收到低损失的范围。举例来说,当γ=2时,一个样本被分类的Pt=0.9的损失比CE小1000多倍。这样就增加了那些误分类的重要性(它们损失被缩了4倍多,当Pt<0.5且γ=2)
作者用了α-balanced的Focal Loss的变体。作者发现它能提升一点点精度。
作者也提到,在利用损失层时候,结合sigmoid计算p,然后算损失,能增加数值稳定性。
Binary分类模型是默认初始化为对于y=-1和y=1有相同的概率的。在这样的初始化之下,由于类不平衡,出现频率高的类会主导总的损失,在训练早期导致不稳定。为了对抗这个,作者提出“优先”的概念,在训练初期对于模型对于低频率的类(背景)估计的p给予“优先”。作者把这个“优先”(prior)记做 ,设定它,以至于模型对于低频率类别(rare class)的样本的估计p很低,比如说0.001。这是模型初始化的改变,而不是损失函数的改变。作者发现这点能改进训练的稳定性(对于在类极不平衡的情况下的交叉熵和focal loss都有效)。
Two-stage detectors常用交叉熵损失,而不用 或者作者的方法。它们用两种途径解决这个问题:
第一个stage是一个object proposal机理,将几乎无穷个可能的object locations减少到一两千个。重要的是,这种方法的选择不是随机的,是跟true object locations(标签的框)相关的,能够除掉大部分的easy negative。
第二个stage的训练中,biased sampling是一种典型的构建minibatch的方法,比如说1:3的正负样本比例。这个比例就像在采样时使用了 项。作者的方法focal loss是用来在one-stage的检测中通过损失函数来解决这个问题。
RetinaNet是单个、统一化的网络,由backbone网络和task-specific任务相关的子网络组成。Backbone是负责计算卷积的feature map的,是一个现存的卷积网络。第一个子网络是在Backbone输出上面进行object classification目标分类的;第二个子网络是在产生bounding box regression的。网络结构给出:
Feature Pyramid Network Backbone:
作者用了Feature Pyramid Network,FPN作为Retina的Backbone。FPN提出标准的有top-down pathway上下通道和lateral connections横向连接的卷积网络,所以网络从单分辨率的图像中构建了一个丰富、多尺度特征金字塔。从上图的(a)(b)可以看出来。
作者在ResNet的顶部构建FPN,用P3到P7层构建了金字塔。(第 层分辨率是第一层的 )。只用最后一层的特征的话AP很低。
Anchors:
作者用了translation-invariant anchor boxes 平移不变锚与RPN的变体相似。这个anchor在金字塔层P3到P7有相应的 到 的区域。在每个金字塔层,作者用的长宽比是{ }。在每层,对于三个长宽比的anchor,加了anchor的形状的{ }的anchor。这能够增加AP。对于每层,有A=9个anchor,穿过这些层,它们可以覆盖32-813个输入图片中的像素。每个Anchor都是K个分类目标的one-hot向量(K是目标类别数)和4个box regression目标。作者设定anchor的方式是与ground-truth 的intersection-over-union (IoU) 阈值0.5,与背景IOU 。所有的anchor都被设定为一个box,在预测向量的对应的类位置设1,其他的设为0。如果没有被设定,那么 ,它是在训练时候被忽略的。Box regression targets是计算出来的每个anchor和它设定的object box的偏移量,如果没有设定那么忽略。
Classification Subnet:
分类子网络在每个空间位置,为A个anchor和K个类别,预测object presence的概率。这个子网络是小的FCN(全卷积网络),与FPN中的每层相接;这个子网络的参数在整个金字塔的层间共享。设计方法是:如果一个从金字塔某个层里来的feature map是C个通道,子网络使用 四个 的卷积层,C个滤波器,每个都接着ReLU激活函数;接下来用 的卷积层,有 个滤波器。最后用sigmoid激活函数对于每个空间位置,输出 个binary预测。作者用实验中 。
与RPN对比,作者的object classification子网络更深,只用 卷积,且不和box regression子网络共享参数。作者发现这种higer-level设计决定比超参数的特定值要重要。
Box Regression Subnet:
与object classification子网络平行,作者在金字塔每个层都接到一个小的FCN上,意图回归每个anchor box对邻近ground truth object的偏移量。回归子网络的设计和分类相同,不同的是它为每个空间位置输出4A个线性输出。对于每个空间位置的A个anchor,4个输出预测anchor和ground-truth box的相对偏移。与现在大多数工作不同的是,作者用了一个class-agnostic bounding box regressor,这样能用更少的参数更高效。Object classification和bounding box regression两个网络共享一个网络结构,但是分别用不同的参数。
Inference:
RetinaNet的inference涉及把图片简单地在网络中前向传播。为了提升速度,作者只在每个FPN,从1k个top-scoring预测中提取box预测(在置信度阈值0.05处理之后)。多个层来的Top prediction聚在一起然后用NMS(非极大值抑制)以0.5为阈值。
Focal loss:
作者在分类子网络输出的地方用了focal loss。 发现在 为2的时候效果比较好。同时RetinaNet在 有相对的鲁棒性。作者重点指出训练Retina时候,在每个采样图片里面,focal loss被加到所有的100K个anchor上面的。这与通常的heuristic sampling(RPN)或者 hard example mining(OHEM,SSD)选择anchor的一小部分集合(对于每个minibatch大概256)不同。作者用了特定的anchor(不是全部的anchor,因为大部分的anchor是easy negative在focal loss中有微小的作用)来归一化。最后 是用在设定在出现频率低的类别,有一个稳定的范围,它也和 一起。 这样能把两者融合,调两个参数。一般来说,当 增大 ,应该稍微减小( 和 效果最好) 。
Initialization:
作者在ResNet-50-FPN和ResNet-101-FPN的backbone上面做实验。基础模型是在ImageNet1K上面预训练的。除了最后一层,RetinaNet的子网络都是初始化为bias b=0和权值weight用高斯初始化 。classification子网络的最后一层的conv层,作者的bias初始化为 其中 表示每个anchor在开始训练的时候应该被标记为背景的置信度 。作者用 在所有的实验中。这样初始化能够防止大的数量的背景anchor在第一次迭代的时候产生大的不稳定的损失值。
Optimization:
RetinaNet是用SGD训练的。作者用了同步的SGD在8个GPU上面,每个minibatch16张图,每个GPU2张图。所有的模型都是训练90K迭代的,初始学习率是0.01(会在60k被除以10,以及在80K除以10)。作者只用图像的横向翻转作为唯一的数据增广方式。权值衰减0.0001以及动量0.9。训练的损失是focal loss和标准的smooth L1 loss作为box回归。
5 训练
表1: RetinaNet 和 Focal Loss 剥离试验(ablation experiment)
6 试验
图4:收敛模型的不同 γ 值的正、负样本的归一化损失的累积分布函数。 改变 γ 对于正样本的损失分布的影响很小。 然而,对于负样本来说,大幅增加 γ 会将损失集中在困难的样本上,而不是容易的负样本上。
表2:目标检测单模型结果(边界框AP)VS COCO test-dev 最先进的方法
6 结论
作者将类别不平衡作为阻碍one-stage方法超过top-performing的two-stage方法的主要原因。为了解决这个问题,作者提出了focal loss,在交叉熵里面用一个调整项,为了将学习专注于hard examples上面,并且降低大量的easy negatives的权值。作者的方法简单高效。并且设计了一个全卷积的one-stage的方法来验证它的高效性。在具有挑战性的COCO数据集上面也达到了state-of-the-art的精度和运行时间。
图5: 作为 xt = yx 的函数,Focal Loss 变体与交叉熵相比较。原来的 FL(Focal Loss)和替代变体 FL* 都减少了较好分类样本的相对损失(xt> 0)。
表3:FL 和 FL* VS CE(交叉熵) 的结果
其中 是输入的数据 是输入的标签。
其中
为了计算前向公式(3)的梯度我们,首先计算单元 的导数。
计算计算 导数:
有了(4)和(5)我们就来对(3)进行推倒。
在(6)中把(4)(5)带入并合并整理就得到(7)
(7)就是Focal loss的后向的最后结果。要是在Caffe中实现Focal Loss 即可采用(7)实现backward。
之前一直认为one-stage detector结果不够好的原因是使用的feature不够准确(使用一个位置上的feature),所以需要Roi Pooling这样的feature aggregation办法得到更准确的表示。但是这篇文章基本否认了这个观点,提出one-stage detector不好的原因完全在于:
所以作者的解决方案也很直接:直接按照loss decay掉那些easy example的权重,这样使训练更加bias到更有意义的样本中去。很直接地,如下图所示:
实验中作者比较了已有的样本选择方式:
Focal loss在coco上AP的提升都在3个点左右,值得注意的是,3的结果比2要更差,其实这也表明,其实正负样本不平衡不是最核心的因素,而是由这个因素导出的easy example占领的问题。结果上,最好的模型(ResNet101+FPN)做到了single model39.1 AP,其余的model在speed和accuracy之间的tradeoff也都是在efficient边界上。
https://zhuanlan.zhihu.com/p/28873248
https://blog.csdn.net/qq_34564947/article/details/77200104