RetinaNet和Focal Loss论文笔记

    论文:Focal Loss for Dense Object Detection.Tsung-Yi Lin Priya Goyal Ross Girshick Kaiming He Piotr Dollar.Facebook AI Research (FAIR)


摘要

    当前最精确的目标检测算法是two-stage的,这类方法的的分类器处理的包围框是稀疏的。而单阶段目标检测器处理的是规则的、稠密的的包围框上,因此更快、更简单,但是精度不及两阶段目标检测算法。本文对这个现象进行了研究,认为主要原因是密集检测器在训练过程中存在“前景-背景类别极端不平衡”的问题。本文通过对标准交叉熵损失函数进行改进解决类别不平衡的问题,降低分配给易分类样本的损失权重,称为Focal Loss。Focal Loss重点在难分类的样本上训练,防止易分类的样本压倒检测器。为了评估Focal Loss的效率,本文还设计了一个简单的密集检测器:RetinaNet。结果表明RetinaNet在速度上与one-stage一样快的同时,精度超越了two-stage算法。代码放在:https://github.com/facebookresearch/Detectron 


1.引言

    当前SOTA的目标检测器是基于two-stage的,第一个阶段生成一组稀疏的候选框,第二阶段对每个候选框进行分类。经过R-CNN Fast R-CNNFaster R-CNNMask R-CNNFPN等一系列两阶段的工作之后,two-stage方法在COCO benchmark上达到SOTA。

    one-stage目标检测器应用在规则的、稠密的候选包围框上。YOLOSSD等算法表明one-stage的速度要比two-stage快的多。那么one-stage可以达到two-stage那样的精度吗?

    本文展示了one-stage目标检测器可以达到SOTA的two-stage目标检测器的精度。本文发现类别不平衡是one-stage算法精度不佳的原因,通过减小这个现象提高one-stage的精度。

    two-stage算法通过两个阶段级联和启发式采样解决了类别不平衡的问题。第一个阶段(比如SS、EdgeBoxes、DeepMask、RPN等)将候选包围框的数量减小到很小的数量(比如1-2k),过滤掉大部分背景类别的包围框。在第二阶段,通过启发式采样(比如固定前景-背景包围框比例为1:3) 或 在线难例挖掘(OHEM) 来维持前景和背景类别的平衡。

    one-stage算法处理在图像中预定义的一组数量很大的候选包围框,通常超过~100k。启发式采样包围框是无效的,因为训练过程仍然被易分类的背景类别主导。这个问题通常使用bootstrapping或难例挖掘来解决。

    本文提出了一种新的损失函数Focal Loss,可以解决类别不平衡的问题。这个损失函数是一个动态系数的交叉熵损失,当正确类别的置信度增加时对应的系数逐渐衰减到0。如下图所示:

图片1.jpg

    直观上看,这个尺度系数可以自动降低易分类样本的权重,而增加难分类样本的权重。实验表明Focal Loss可以训练得到一个高精度、one-stage检测器,性能超过使用启发式采样或难例挖掘的one-stage算法。注意到focal loss的确切形式不重要,其它形式也可以得到类似的结果。

    为了演示focal loss的效率,本文还设计了一个简单的one-stage目标检测器,称为RetinaNet,Retina是视网膜,RetinaNet名字来源于它对输入图像的密集采样。它的使用FPN和anchor boxes,还包含了很多最近提出的tricks。RetinaNet高效而精确,基于ResNet-101-FPN,在COCO test-dev上达到39.1的AP,帧率为5fps,达到SOTA。与其它模型的对比如下:

图片2.jpg


2.相关工作

    类别不平衡:无论是经典的目标检测算法比如boosted detector、DPMs,还是现代算法比如SSD,都面临着训练时类别不平衡的问题。这些检测器处理10^4~10^5的候选框,但其中只有很少的候选框包含目标。这种不平衡会导致两个问题:(1)训练低效,大量的训练是无效训练,因为都是一些简单的负样本;(2)大量简单负样本将影响训练,导致模型退化。常用的解决方案是难例挖掘(hard negative mining),即采样的是困难的样本或复杂的样本。相反,focal loss可以自然地处理类别不平衡问题,从而高效的训练one-stage模型,


3.Focal Loss

    Focal Loss用于解决one-stage目标检测算法的极度前景-背景类别不平衡问题。二分类交叉熵(CE)的公式如下:

图片3.jpg

    其中y∈{±1}表示ground truth类别,p∈[0,1]是模型预测是这个类别的概率。为了便于记忆,定义:

图片4.jpg

    则CE(p,y)=CE(pt)=-log(pt)。如Figure 1最上面的蓝色曲线所示,CE即使对易分类的样本,即置信度高的样本,也会产生一个小的损失。但是当大量易分类的样本的损失求和后,将盖过少数难分类的样本。

3.1平衡交叉熵

    一个常用的解决类别不平衡的方法是引入一个权重系数α∈[0,1],对于类别1是α,对类别-1是1-α。α可以设置为类别频率的倒数,也可以作为超参数通过交叉验证来设计。与pt类似的定义αt,则α-balanced CE损失函数为:

    CE(pt)=-αtlog(pt)

    本文以这个损失函数作为baseline。

3.2 Focal Loss定义

    密集目标检测器在训练时会遇到严重的类别不平衡问题。易分类的负样本占据了大部分损失,并主要了梯度。上面的α-balanced CE虽然可以平衡正负样本,但是它不区分难易样本。而本文提出的损失函数可以降低易分类样本的权重,而增加难分类样本的权重。

    Focal Loss在标准交叉熵上加入了调制系数(1-pt)γ ,聚焦参数γ>=0,定义如下:

FL(pt)=-(1-pt)γlog(pt)

    不同的γ 的曲线如下:

图片7.jpg

    focal loss具有两个属性:(1)当样本误分类时,pt很小,此时调制系数接近1,损失损失与CE一样。当pt接近1时,调制系数接近0,此时这种易分类的样本的损失被降低权重。(2)通过调整聚集参数γ,可以平滑的降低易分类样本的权重。当γ=0时,Focal Loss等价于CE,γ越大这种调制的效果越强。

    直观上看,调制系数减小了易分类样本对损失的贡献。比如当γ=2时,当pt=0.9时,在focal loss上比CE减小了100x,若pt=0.968时减小了1000x的损失。同时,focal loss增加了错误分类样本的损失,当γ=2,pt<=0.5时,损失将被放大四倍。

    还可以使用α-balanced Focal Loss:FL(pt)=-αt(1-pt)γlog(pt)

    加入α后实验结果得到微小提升。在代码实现中,sigmoid激活函数与loss的计算是一起的,这样可以提高数值稳定性。

3.3 类别不平衡与模型初始化

    二分类模型被默认初始化为对y=-1或y=1有相同的概率,当存在类别不平衡时,最常出现的类别会主要总的损失,导致早期训练不稳定。为了解决这个问题,在训练早期,本文为稀少类别(前景类别)的概率值p引入先验值(prior),记作π。因此保证模型对于稀少类别的样本预测的概率比较低。

3.4类别不平衡与Two-stage检测器

    two-stage算法通过两种机制解决类别不平衡的问题:(1)两阶段级联,(2)具有偏向性(biased)的minibatch采样。第一个阶段是候选包围框生成,可以将近乎无限多可能的包围框减少到1-2k。而且这些筛选出的包围框并不是随机的,而是有可能存在目标的包围框,因此去掉了大多数易分类的负样本。当训练第二阶段时,通常采用biased采样构造minibatches(比如包含正负样本的比例为1:3)。这个比例可以看作通过采样实现隐式的α-balanced系数。


4.RetinaNet

    RetinaNet是一个单阶段的目标检测网络,由backbone和两个并行的子网络组成。backbone负责在整个图片上计算卷积特征,而且是一个非自卷积网络。第一个子网络预测包围框的类别,第二个子网络回归包围框。这两个子网络的特征点设计简单,专为单阶段密集检测设计的。RetinaNet的各个组件都可以调整,网络结构如下:

图片9.jpg

    FPN Backbone:RetinaNet的backbone是FPN,如Figure 3的(a) (b)所示。FPN通过从上到下的通路和横向连接来增强卷积网络,可以从单分辨率的特征图中构造一个丰富的、多尺度的特征金字塔,金字塔的每层可以在检测不同尺度的目标。与FPN原文一样,这里在ResNet的顶部构造FPN。构造的金字塔从P3到P7,其中P_L中的L表示金字塔的层级,第L层的输出分辨率是输入特征图的1 / 2^L。通道数设置为256,其余细节与FPN原文一样。

    Anchors:这里使用的先验框(Anchors box)类似于RPN的变体,先验框的区域大小在P3到P7上分别是32^2到512^2。每个位置设置三个长宽比的先验框:{1:2,1:1,2:1}。为了使先验框的密度大于FPN原文,这里每个位置设置了三个不同尺度的先验框:{2^0,2^(1/3),2^(2/3)},这提高了RetinaNet的AP。因此每个位置共有A=9个先验框,这些包围框的覆盖范围从32到813像素。

    每个先验框通过K维one-hot向量指定类别,K是类别总数,以及一个4维向量指定边界。先验框的标签赋予的规则与RPN类似,但是修改了多类别检测并调整了阈值。具体地,如果先验框与ground truth的IoU>0.5,则设为正样本,若IoU在[0,0.4)内则设为负样本。当IoU在[0.4,0.5)中时,训练时忽视这个样本。包围框回归的目标是先验框与ground truth之间的偏置,若该先验框非正样本,则没有指定包围框回归的标签。

    分类子网络:分类子网络负责预测每个先验框的存在目标的概率和类别。是链接到FPN各层级的小型FCN网络,各个金字塔层之间的子网络的参数共享。该子网络的输入是包含C个通道的金字塔层,后接4个3x3卷积层,最后一个是3x3卷积层接sigmoid激活函数,输出KA个通道。本文设置C=256,A=9,该子网络如下图:

图片10.jpg

    与RPN不同,本文的分类子网络更深,只使用了3x3卷积。而且分类子网络与边框回归子网络不共享参数。这个选择比超参数设置更加重要。

    边框回归子网络:这也是一个小型FCN,用于回归各个正样本的边框。该网络与分类子网络一样,不同的是边框回归子网络输出激活函数使用线性激活函数,输出通道数为4A。每个空间位置有A个先验框,每个先验框的4个值表示先验框和ground truth之间的相对偏置。这个回归网络与最近的其它模型不同,它与类别无关,参数更少,因此更加高效。

推断和训练

    RetinaNet整体就是一个FCN,包含了ResNet-FPN、分类子网络、边框回归子网络。为了提高推断速度,这里使用置信度阈值0.05过滤后,在每个金字塔层上最多解码1k个最高置信度的包围框。然后融合各金字塔层预测的包围框,并执行阈值为0.5的NMS产生最终的结果。

    Focal Loss:这里使用focal loss作为分类子网络损失函数,γ在[0.5,5]之间比较鲁棒,γ=2相对最好。focal loss被应用于所有的先验框(数量~100k)上,这与启发式采样(比如RPN)或OHEM(比如SSD)不同选择少量的候选框不同。单张图片的总的focal loss计算方法为:首先计算所有先验框的focal loss的和,然后通过先验框正样本的数量进行归一化。这里通过先验框正样本的数量进行归一化,而不是所有的先验框数量,是因为绝大部分先验框都是易分类的负样本,易分类负样本的损失值非常小。另外,α参数具有某个稳定的范围,但通常根据γ来确定。当γ增加时,α轻微较小,比如γ=2时α最好。

    初始化:本文用到的ResNet均在ImageNet1k上进行预训练。FPN中新添加层的初始化与FPN原文的类似,除了最后一层外新添加的层使用方差为0.01的高斯分布进行随机初始化,偏置为0。对于分类子网络的最后一层,偏置初始化为b=-log((1-π)/π),其中π表示在训练开始时,每个先验框是前景类别的概率为~π,这里设置π=0.01。这种初始化预防了第一次迭代时产生的巨大的、不稳定的损失值。

    优化:这里使用SGD在8个GPU上进行训练,每个minibatch是16张图像,每个GPU2张图像。首选迭代次数为90k,初始学习率为0.01,其中60k和80k时学习率除以10。数据增强仅用水平翻转。权重衰减系数为0.0001,动量系数为0.9。总的损失包括分类子网络的focal loss和边框回归子网络的smooth L1 loss。


5.实验

    在COCO数据集上进行训练和评估。下面是实例中各个参数设置的对比结果:

图片11.jpg

Focal loss分析

    为了更好的理解focal loss,这里分析了收敛模型的损失的分布。使用ResNet-101 600,γ=2,AP=36.0。用模型处理了大量的随机的图像,然后采样预测的~10^7个负样本窗口和~10^5个正样本窗口。然后分别计算了focal loss,并归一化使得损失和为1。然后将loss从高到第排序,画出正样本和负样本在不同γ下的累积分布函数(CDF),曲线如下图所示:

图片12.jpg

    观察正样本的CDF,可以看到对于不同的γ值CDF 看起来相当相似。而对负样本来说,随着γ的增加,loss逐渐关注前20%的难分类负样本。因此可以看到,focal loss能够有效降低易分类负样本的损失值。

    下表是RetinaNet与其它SOTA目标检测算法的对比,可以发现RetinaNet遥遥领先了它们。

图片13.jpg


6.Focal Loss*

    focal loss的确切形式不重要,这里提出一个新的损失函数可以达到与FL类似的性能,称为FL*,定义如下:

    xt=yx,y∈{+-1},y表示ground truth类别

    前面定义了pt=σ(xt),这里定义pt*和FL*如下:

图片14.jpg

    FL与FL*的曲线如下:

图片15.jpg

    下表是FL和FL*应用在RetinaNet-50-600上的对比结果:

图片16.jpg

    下图是不同的γ和σ对精度的影响:

图片17.jpg


7.损失函数的导数

    损失函数的导数如下:

图片18.jpg

    导数曲线:

图片19.jpg



上一篇:

首页 所有文章 机器人 计算机视觉 自然语言处理 机器学习 编程随笔 关于