FCOS原理与代码解析(更新改进trick)

目录

摘要

Pipeline

Loss函数

与RetinaNet的不同

更新一些改进trick(2021.3.25)

摘要

anchor-based目标检测存在的缺陷:

  1. anchor会引入很多需要优化的超参数, 比如anchor number、anchor size、anchor ratio
  2. 因为anchor的大小、比例、数量都是提前确定的,会影响模型的泛化性能。对于新的检测任务,需要重新设计anchor的各种参数。
  3. 为了保证high recall rate,需要大量密集分布的anchor boxes,会导致训练阶段正负样本不均衡的问题。
  4. 因为anchor boxes数量特别多,训练阶段需要计算所有anchor boxes和ground-truth boxes的IOU,导致特别大的计算量和内存(显存)占用

Pipeline

FCOS原理与代码解析(更新改进trick)_第1张图片

模型采用ResNet50作为backbone,后面接FPN,FPN的P5后接两个stride=2的3*3conv得到P6、P7,P3~P7每个feature map分别接2个不同的FCN分支用于分类和边框回归,其中每个conv分支由4个3*3的conv加最后的预测conv组成,注意这里centerness和分类共享同一分支

Loss函数

在计算Loss之前首先要确定target,对于feature map \(F_{i}\)上的每个点(x,y),映射回输入图片中的对应位置(\left \lfloor \frac{s}{2} \right \rfloor+xs, \left \lfloor \frac{s}{2} \right \rfloor+ys),s是 \(F_{i}\)相对于输入图片的stride。位于gt box内的点视为正样本,该点分类的target即为对应gt box的类别。该点与gt box四条边的距离\(l^{*}、t^{*}、r^{*}、b^{*}\)为回归的target。由于检测目标可能会重叠,可能存在一个点同时位于多个gt box内的情况,但是作者发现实际发生重叠的gt box之间的尺度变化非常大,而神经网络浅层更多的是细节特征,对小目标检测有利,深层更多的是语义特征,有利于检测大目标,因此通过限制不同层负责回归不同大小的目标,可有效减少这种情况。即m_{i-1}< max(l^{*},t^{*},r^{*},b^{*})<m_{i},对于P3~P7,\(m_{2}\)~\(m_{7}\)分别设为0,64,128,256,512,\infty。如果这种情况还存在,就选择小的那个进行回归。

通过多级预测之后作者发现FCOS的检测效果和anchor-based的检测器之间仍然存在着一定的差距,主要原因是距离目标中心较远的位置产生了很多低质量的预测框。因此作者提出了和分类分支并行的单一分支centerness来抑制这些低质量的预测边界框,而且不引入任何超参数。centerness描述的是负责预测某个gt box的点与该gt box中心点的距离大小,范围在0~1之间,公式如下

FCOS原理与代码解析(更新改进trick)_第2张图片

测试过程中,最终的分类预测值会乘以centerness,这样距离中心远的预测框的score会变小,从而在NMS阶段更有可能被过滤掉。

对于网络的三个输出分支,分类分支采用focal loss,centerness分支采用BCE loss,回归分支采用Iou loss,都是常用的loss,这里不再展开解释。

与RetinaNet的不同

因为FCOS的模型结构和RetinaNet非常相似,作者在论文中也提到backbone阶段的超参数和后处理部分都和RetinaNet完全一样,因此这里列举一下FCOS和RetinaNet的不同来帮助理解。(https://github.com/xuannianz/keras-fcos这一版的keras-fcos是在keras-retinanet基础上改的,改动不多,可以对照着看)

模型结构的不同

  • 因为回归目标l^{*}t^{*}r^{*}b^{*}永远是正的,FCOS的回归分支最终输出多做了一步exp操作
  • 分类和回归分支最后一层卷积核数量分别由9*49*20变成420
  • FCOS增加了一个centerness分支,和分类分支共享参数。不同的是最后一个卷积核数量是1,然后reshape再接一个sigmoid激活函数
  • Forward时,__build_anchors函数变成了__build_locations,其实只是把3种大小*3种比例的anchor变成比例和大小都为1anchor
  • 回归的target变了,retinanet的是feature-map映射回原图的点对应的anchor的左上和右下坐标与gt的差并分别除以anchor的宽和长,而fcos是映射到原图的点到gt四边的距离
  • filter步骤做nms之前,fcosscores乘以了centerness并开平方。然后select top k阶段也对classification_score乘以了centerness并开平方。

Loss的不同

  • cla_loss都是用的focal_loss,参数也一样。只有一处不同,RetinaNetgt_boxiou介于0.40.5之间的anchor设为ignore不参与计算。而FCOSfeature_map映射回原图的点只有posneg之分,没有ignore
  • reg_lossRetinaNet用的是smooth L1 loss,而FCOS用的是iou loss
  • FCOS新增了一条centerness的分支,这一分支的loss用的binary cross entropy

更新一些改进trick(2021.3.25)

  1. centerness on reg。centerness分支由原始的和cls分支共享权重变成和reg分支共享权重
  2. center sampling。原始是gt box内的点都作为正样本,改为gt box中心radius*stride小区域内的点视为正样本。
  3. norm on bbox。原始的reg分支最终的exp操作改成relu。
  4. giou loss。原始reg分支的loss为iou loss,改为giou loss。
  5. bbox loss weight。由原始的平权改为用 centerness 分支的 target,即离gt中心越近,权重越大。

参考

FCOS 的改进 trick - 知乎

【庖丁解牛】从零实现FCOS(终):CenterSample的重要性 - 知乎

FCOS及其优化实验 - 知乎

你可能感兴趣的:(目标检测,目标检测,深度学习,人工智能)