[关闭]
@huanghaian 2020-11-02T00:22:40.000000Z 字数 5864 阅读 1080

mmdetection最小复刻版(九):广义FocalLoss深入分析

mmdetection


0 摘要

论文名称:Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Detection
论文地址:https://arxiv.org/pdf/2006.04388.pdf
原作者解读:https://zhuanlan.zhihu.com/p/147691786

本文从loss角度出发,针对目前目标检测存在的两个问题:
1. 分类预测分值和质量评估分值例如iou和centerness训练测试不一致
2. bbox回归采用的表示不够灵活,没有办法建模复杂场景下不确定性

提出了两个解决办法:
1. 将bbox预测质量和分类分支loss联合表示,解决两分支独立训练,联合测试不一致问题
2. 采用自发学习的灵活分布建模形式来表示bbox不确定性,具体是采用softmax+积分形式,相当于把回归问题转换为分类问题

整个做法一气呵成,通俗易懂,是个不错的思路。由于原作者在知乎上有非常详细的解读,而我不想又写一遍,故很多地方的表述copy于作者解读(已经征得李翔博士授权),我主要工作是在此基础上新增一些代码细节说明。

github地址:https://github.com/hhaAndroid/mmdetection-mini
欢迎star

1 目标检测算法问题分析

1.1 不一致分析

作者是以atss为例进行分析,但是可以推广到任意One-stage目标检测算法中。一般目标检测都包括分类和回归分支,fcos和atss在bbox回归分支特征处多引入了一条质量评估分支centerness,当然在 Iou-aware single-stage object detector for accurate localization论文中引入了iou分支,实验表明引入centerness或者iou分支可以提高性能,该分支的作用主要是反映bbox预测质量,在后续nms排序时候作用很大。 对fcos和atss不熟悉的请看本系列解读前文。

image.png-122.9kB

目前虽然引入了bbox质量评估分支,但是还是存在不一致问题,原因是:

1.用法不一致
训练的时候分类和质量估计各自训记几个儿的,但测试的时候却又是乘在一起作为NMS score排序的依据,这个操作显然没有end-to-end,必然存在一定的gap。以fcos为例,centerness分支的label是提前算好的,其实和分类和bbox回归分支没有任何联系,各自优化各自分支。

2.对象不一致
借助Focal Loss的力量,分类分支能够使得少量的正样本和大量的负样本一起成功训练,但是质量估计和bbox回归通常就只针对正样本训练,也就是说对于这两个分支而言,有很多位置都是忽略loss的。那么在做NMS score 排序的时候,所有的样本都会将分类score和质量预测score相乘用于排序,那么必然会存在一部分分数较低的“负样本”的质量预测是没有在训练过程中有监督信号的,有就是说对于大量可能的负样本,他们的质量预测是一个未定义行为。这就很有可能引发这么一个情况:一个分类score相对低的真正负样本,由于预测了一个不可信的极高质量score,而导致它可能排到一个真正的正样本(分类score不够高且质量score相对低)的前面

简单来说就是质量估计和bbox回归分支只有少部分样本参与训练,但是推理时候是全部一起用的,那么肯定存在某些位置质量估计存在虚高的情况,导致出现一些异常现象,这本质就是训练和测试不一致造成的。在fcos里面刚开始没有引入centerness时候这个问题比较严重,在引入该分支后能够得到缓解,但是依然存在少部分。
image.png-354.5kB

在fcos里面有一副实验图:
image.png-131.1kB

(b)是引入centerness后的iou质量分布图,虽然有改善,但是红线右下部还是存在一定比例的样本,所以说centerness只是缓解而已,没有真正解决。

要想解决这个问题,就必须要联合表示,也就是说不能独立训练,后面有解决办法。

1.2 bbox表示不够灵活分析

在复杂场景中,边界框的表示具有很强的不确定性,而现有的框回归本质都是建模了非常单一的狄拉克分布,非常不flexible,我们希望用一种general的分布去建模边界框的表示。问题二如图所示(比如被水模糊掉的滑板,以及严重遮挡的大象

image.png-573.7kB

可以看出,任何一个特征图上面点的bbox target不再是atss里面的距离4条边的距离,而是一个分布,这个分支是自发学到的,在训练过程中没有提前设置。

对于bbox表示不够灵活分析的问题,作者的解决办法是选择直接回归一个任意分布来建模框的表示。当然,在连续域上回归是不可能的,所以可以用离散化的方式,通过softmax来实现即可,这里面涉及到如何从狄拉克分布的积分形式推导到一般分布的积分形式来表示框。

2 广义focalloss解决办法

image.png-79.9kB

2.1 不一致问题解决

前面说过不一致原因主要是各分支独立训练,测试联合。那么如果我能够训练时候就联合起来,那是不是可以进一步缓解了,为此作者在分类分支引入了bbox预测质量值作为样本分类的label。原始focal loss仅仅能处理label非0即1的场景,现在label是0-1的连续值,故作者对其进行了魔改:

image.png-15.3kB
image.png-9.9kB

其中y为0~1的质量标签,来自预测的bbox和gt bbox的iou值,注意如果是负样本,则y直接等于0。是分类分支经过sigmoid后的预测值,注意QFL的全局最小解即是。这样交叉熵部分变为完整的交叉熵,同时调节因子变为距离绝对值的幂次函数。和Focal Loss类似,我们实验中发现一般取为最优。
image.png-54.4kB

上图为时候,选取不同情况下的Loss曲线图,可以发现当预测值为0.5时候是全局最小值。所以说bce loss的label不一定必须是非0即1,0-1连续值其实也是可以优化的

在代码方面quality_focal_loss实现也非常简单:
image.png-144.6kB

先算负样本的loss,并且此时不需要score,而是强制为0;然后在算正样本的loss,此时正样本label是预测bbox和gt bbox的iou值

score[pos_inds] = bbox_overlaps(
            pos_decode_bbox_pred.detach(),
            pos_decode_bbox_targets,
            is_aligned=True)

其中pos_decode_bbox_pred是预测bbox,pos_decode_bbox_targets是gt bbox,注意都是特征图维度,is_aligned=True表示bbox1和bbox2的维度完全相同。

image.png-99.4kB

其中表格各行的含义如下:
image.png-49.1kB

guided操作的含义是将iou或者centerness的label作为分类分支的权重,相比不采用质量预测分支,效果有一定提升,但是不如引入质量评估分支,而本文的联合训练模式效果最出色。

不管是FCOS还是ATSS,引入质量预测分支都有性能提升,其中iou分支效果始终比centerness分值效果好(iou分支的做法来自论文:Iou-aware single-stage object detector for accurate localization,就是每个正样本位置预测一个iou分值而已),作者试图分析原因:

(1) IoU本身就是最终metric的衡量标准,所以用来做质量估计和排序是非常自然的
(2) centerness有一些不可避免的缺陷,比如对于stride=8的FPN的特征层(也就是P3),会存在一些小物体他们的centerness label极度小甚至接近于0,如下图所示
image.png-35.4kB

也就是说centerness label其实不像iou那样是尺度无关的,其在大小尺度下值不一样,而IoU就会相对好很多,是尺度无关的。我们也统计了一下两者作为label的分布情况
image.png-65.7kB

这意味着IoU的label相对都较大,而centerness的label相对都较小,同时还有非常非常小的。可以想见,如果有一些正样本的centerness的label本身就很小,那么他们最后在做NMS排序的时候,乘上一个很小的数(假设网络学到位了),那么就很容易排到很后面,那自然性能就不容易上去了。所以,综合各种实验以及上述的分析,个人认为centerness可能只是一个中间产物(当然,其在FCOS中提出时的创新性还是比较valuable的),最终历史的发展轨迹还是要收敛到IoU来。

2.2 bbox表示不够灵活问题解决

由于标注的时候无法标注不确定性,故目前大家训练都是把gt bbox当做单一的狄拉克分布,也就是对应gt bbox值位置为1,其余都是0,很明显这无法反应自遮挡和物体间遮挡现象。故作者的做法是将回归问题转化为分类问题,例如待回归值是4.6,那么我假设分布长度是8,那么我可以设置分类label=(0.0733,0,0,0.0067,0.02,0.9,0,0,0),这个label要满足分布特性即sum(label)=1,并且0xlabel[ 0 ]+1xlabel[ 1 ]+2*label[ 2 ]+...=4.6。 可想而知,这种Label分布是无穷无尽的,我上面只是随意写了一个。也就是说这个分布的label肯定无法提前给定。
image.png-15kB

首先作者对所有 gt bbox映射到特征图维度,并计算所有coco数据集中正样本的回归范围,如下所示:
image.png-31.9kB
可以发现最大值大概可以设置为16,也就是说分布长度可以设置为16+1,而且需要特别指出不同的数据集由于分布不一致,你可以需要针对你的数据特点重新确定这个超参。总结来说,本文思想图示为:
image.png-27.7kB

非常灵活。将分布映射到浮点值的做法非常简单,就是我上面举例的做法,代码如下:
image.png-86kB

由于任意预测分布都可以直接转化得到浮点坐标,所以其实对转化后的浮点坐标采用giou loss监督即可,根本不需要考虑前面我们说的分布label如何设置问题,理论上其可以自行优化。但是大家也可以想到这样处理的缺点是优化效率极低,因为无穷多个分布都可以得到相同的浮点坐标,优化方向实在是太多了。

考虑到真实分布通常不会距离标注的位置太远,所以又额外加了个loss,希望网络能够快速地聚焦到标注位置附近的数值,使得他们概率尽可能大。基于此,我们取了个名字叫Distribution Focal Loss (DFL)

image.png-10.6kB

yi和yi+1是浮点值y的左右整数值,S是输出分布,长度为17,可以看出这本质就是一个bce loss,作者通过计算,全局最优解是:
image.png-4.8kB

也就是说学出来的分布理论上是在真实浮点坐标的附近,并且以线性插值的模式得到距离左右整数坐标的权重。例如假设浮点数4.6,那么左右label=4,5,并且对应分布索引处的预测值理论上是0.4,0.6,此时就可以4x0.4+5x0.6=4.6了。这是非常符合直觉的。

代码也非常简单:
image.png-52.8kB

可视化结果如下:
image.png-309.9kB

伞这个物体,它的伞柄被椅子严重遮挡。如果我们不看伞柄,那么可以按照白色框(gt)来定位伞,但如果我们算上伞柄,我们又可以用绿色框(预测)来定位伞。在分布上,它也的确呈现一个双峰的模式(bottom),它的两个峰的概率会集中在底部的绿线和白线的两个位置。这也从侧面验证了dfl的作用,并且这可能带来一个妙用,就是我们可以通过分布shape的情况去找哪些图片可能有界定很模糊的边界,从而再进行一些标注的refine或一致性的检查等等。颇有一种Learn From Data,再反哺Data的感觉。

image.png-71.8kB

2.3 总Loss分析

本文一共包括3个loss,分别是分类分支的改进focal loss即qfl;bbox预测分支包括两个loss,giou loss和dfl。由于已经联合训练了,故iou或者centerness的质量评估分支不需要。

需要注意的是,既然分类分支的label可以来自回归分支以加强联合表示,那么bbox分支的训练应该也可以借鉴分类分支的信息,故在具体代码上面对于bbox分支,其权重来组分类分支预测类别对应的分值,这样就可以达到相互利用,相互提高的,目的,进一步加强一致性:
image.png-53.8kB

weight_targets = cls_score.detach().sigmoid()
# 预测类别所对应的输出分值
weight_targets = weight_targets.max(dim=1)[0][pos_inds]

并且需要特别注意的是:所有loss都是在特征图维度进行计算,也就是都除以了stride,故在前向推理时候,得到的输出值也需要乘上stride,才能得到原图尺度

scores = cls_score.permute(1, 2, 0).reshape(
            -1, self.cls_out_channels).sigmoid()
bbox_pred = bbox_pred.permute(1, 2, 0)  # 输出是特征图维度
# 需要乘以stride,变成原图维度
bbox_pred = self.integral(bbox_pred) * stride[0]
bboxes = distance2bbox(
            self.anchor_center(anchors), bbox_pred, max_shape=img_shape)

整个代码都是在ATSS代码基础上构建的,所以如果你熟悉ATSS,那么本文你仅仅需要关注新引入的两个loss就行,其余是完全相同的。

3 总结

本文从质量预测分支的训练和测试不一致性出发,提出了针对分类分支和bbox回归分支联合表示的QFL损失函数,利用bbox预测值和gt bbox的iou作为分类分支label,加强一致性,进而将仅仅支持0-1值的focal loss推广到0-1离散值可用的Qualified focal loss;同时针对狄拉克分布建模bbox值无法表示不确定性,而提出了采用预测分布来代替回归值的做法,具体是将分布经过softmax+积分形式,为了加快收敛速度,更进一步的提出了Distributed focal loss。特别的Qualified focal loss和Distributed focal loss可以统一起来,变成Generalized Focal Loss。全文通俗易懂、实验和图表丰富,值得学习。

再次贴一下github地址:https://github.com/hhaAndroid/mmdetection-mini
欢迎star

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注