> ## Content Index
> Fetch the complete content index at: https://yinguobing.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 读懂RetinaNet
- URL: https://yinguobing.com/blog/understanding-retinanet/
- Published: 2020-11-18T11:24:16.000Z
- Updated: 2020-11-18T11:30:37.000Z
- Description: 使用Focal Loss解决物体检测中的样本均衡问题。
- Author: 尹国冰
- Tags: 深度学习

封面图片：Photo by Ali Hajian

---

本文内容摘自文章 *Focal Loss for Dense Object Detection*，作者是Facebook的AI研究团队。这篇文章发表于2018年，你可以在这里找到原文：

[Focal Loss for Dense Object DetectionThe highest accuracy object detectors to date are based on a two-stageapproach popularized by R-CNN, where a classifier is applied to a sparse set ofcandidate object locations. In contrast, one-stage detectors that are appliedover a regular, dense sampling of possible object locations have the po…![](https://static.arxiv.org/static/browse/0.3.2.6/images/icons/favicon.ico)arXiv.orgTsung-Yi Lin![](https://static.arxiv.org/static/browse/0.3.2.6/images/icons/social/bibsonomy.png)](https://arxiv.org/abs/1708.02002?ref=yinguobing.com)

---

如今准确率最高的物体检测框架均是基于R-CNN提出的两步方案，分类器需要处理的待测物体位置是稀疏分布的。与之相反，单步方案需要处理的候选位置规则且密集分布，因此更加简单快速，但是在准确率上却不及前者。我们发现密集分布检测器在训练过程中遇到的极端不平衡的前景背景样本数量是造成这一结果的核心因素。为此提出了将分类较好样本的loss权重降低的方案，名为Focal Loss。

### 背景

R-CNN类检测器在第一个提案阶段快速地将可能的待检对象数量缩减到1～2千，并排除了绝大部分背景；在第二个分类阶段则使用启发式采样如固定前景背景数量比例、实时困难样本挖掘来维持前景与背景的均衡。

与之不同，单步检测器要处理的候选位置则均匀分布在整张图像上，覆盖了不同的空间位置、尺度以及比例，数量巨大，通常可达10万左右。尽管可以采用类似的启发式采样，但是训练过程依旧被容易分类的背景样本所主导。这是物体检测中的经典问题，通常使用bootstrapping或者困难样本挖掘来解决。

Focal Loss是具备动态缩放功能的交叉熵损失函数。缩放因子随着正确分类样本的置信度增加而趋于0，进而自动降低容易样本对loss的贡献权重并集中在困难样本上。如下图所示：

![](https://yinguobing.com/blog/content/images/2020/11/focal-loss.jpg)

缩放因子。作者：Tsung-Yi Lin et, al.

实验显示FocalLoss的表现要优于困难样本挖掘。并且曲线的具体形态并没有特别重要。在此基础上，作者设计了单步物体检测模型 RetinaNet。它使用内嵌式特征金字塔与anchor boxes，在COCO测试中表现超过了之前的两步检测器。

### 相关工作

早期的物体检测多使用滑动窗口与分类器配合行动。在两步方案中，R-CNN首先在第二阶段使用卷积神经网络极大的提升了准确率，开启了物体检测的新纪元。RPN的出现则将两步方案统一在一个神经网络中，得名Faster R-CNN。单步检测器的出现极大的提升了检测速度，但是却以准确率下降为代价。

单步检测器面临的最大问题在于训练过程中样本的极端不均衡。每张图像成千上万个待检对象中，只有数个包含了有效物体。这造成两个不利后果。

1. 训练的效率下降。大部分位置极易被归为负样本，对有效的学习没有帮助。
2. 大量的容易负样本主导了训练过程，造成模型退化。

稳健的损失函数一直是研究的热点之一。例如Huber loss降低异常样本（困难样本）的权重。而Focal loss则注重降低常规样本（简单样本）的权重，集中精力在困难样本上。

### Focal Loss

定义二元分类任务损失函数如下：

$$ CE(p, y) =\\begin{cases} −\\log(p) & \\text{if } y=1 \\\\ -\\log(1-p) & \\text{otherwise}\\end{cases} $$

若定义 $P\_t$ ：

$$ p\_t = \\begin{cases} p & \\text{if } y = 1 \\\\ 1-p & \\text{otherwise} \\end{cases} $$

则 $CE(p, y) = CE(p\_t) = -\\log(p\_t)$。见图1中的蓝色曲线。

引入权重因子 $\\alpha\_t \\in{\[0, 1\]}$，得到：

$$ CE(p\_t) = -\\alpha\_t \\log(p\_t) $$

但是此刻的损失仅能平衡正负样本，为了让它能够平衡难易样本，定义Focal loss为：

$$ FL(p\_t) = -(1-p\_t)^\\gamma \\log(p\_t) $$

不同 $\\gamma$ 值的曲线见图1。

Focal loss有两个特点：

1. 当样本被错误分类，$p\_t$很小，调整因子接近1，不影响loss。当 $p\_t$ 趋近于1，因子趋于0，正确分类的样本被降权。
2. 参数 $\\gamma$ 平滑调整了简单样本的降权比例。当 $\\gamma=0$，FL等同于CE。当$\\gamma$ 增加，调整因子也随之增大。在实验中 $\\gamma = 2$ 为最佳。

实际情况中，作者使用了均衡后的Focal loss：

$$ FL(P\_T) = - \\alpha\_t(1-p\_t)^\\gamma\\log(p\_t) $$

它的实际表现要稍微优于前者。并且值得注意的是，最终的分类层使用`sigmoid`运算可以增强数值稳定性。

#### 考虑类别不均的权重初始化

二元分类的输出结果不是-1就是1。在训练中大量的背景loss会造成早期训练的不稳定。为此在模型训练开始前，针对罕见类别（前景）的概率预测值 $p$ 引入先验值 $\\pi$ ，并赋予它一个较小的值如0.01。这样模型早期对于罕见类别的预测输出概率会降低。我的理解是这样更加符合实际情况，有助于模型收敛到“正确”的状态。

#### 考虑类别不均的两步检测器

两步检测器较少使用均衡损失函数。它们通常使用两步级联与偏置迷你采样来解决这个问题。

### RetinaNet检测器

RetinaNet检测器由一个骨干网络以及两个子任务网络组成。骨干网络负责计算获得特征图。第一个子网络负责在骨干网络输出的特征图基础上通过卷积计算获得物体的分类。第二子网络则通过卷积计算获得边界框的回归值。如下图。

![](https://yinguobing.com/blog/content/images/2020/11/retina-net.jpg)

RetinaNet架构图。作者：Tsung-Yi Lin et, al.

#### FPN主干

作者采用Feature Pyramid Network作为RetinaNet主干，并在ResNet基础上完成了网络构建。具体选择了 $P\_3$ 至 $P\_7$层作为特征层，并统一采用256个通道。

#### Anchor

Anchor的选择类似RPN。从 $P\_3$ 至 $P\_7$ anchor的尺寸从 322 到 5122 。每一层的anchor比例为\[1:2, 1:1, 2:1\]，尺度为\[20 , 21/3 , 22/3 \]。这样每一层一共有9个类别的anchor，覆盖了输入图像的大小为32到813像素。

每个anchor都匹配了长度为K的独热编码，K为物体类别的数量。同时还有长度为4的边界框回归目标。作者采用了RPN的匹配规则并做了修改，以便适用于多类别与阈值调整。具体为：

- IoU大于0.5视为匹配。
- IoU小于0.4视为背景。
- IoU在0.4到0.5之间的，忽略。

每个anchor最多匹配一个物体边界框，当匹配时设定长度为K的对应编码为1，其它为0。如果anchor没有获得匹配前景也没有匹配背景，则将其忽略。边界框的回归目标为anchor与匹配边界框之间的偏移。如果无匹配则忽略。

#### 分类子网络

分类子网络为一个附加在FPN上的小型FCN。它在每个层级的feature上叠加4个3x3卷积层，每个卷积层有C个filter并且跟随ReLU激活，最终附加一个K×A个filter的3x3卷积层。最后使用sigmoid激活来获取每个位置处的分类预测结果。大部分实验中C=256，A=9。

#### 边界框回归子网络

回归子网络是与分类子网络平行的小型FCN，与分类子网络的结构大致相同。区别在于最终的输出大小为4×A。

### 推演与训练

#### 推演

RetinaNet是一个单一的全卷积神经网络。为了加速推演，在最后解码box时仅仅选择每个FPN层级上得分排名前1000个执行，且限制评分值在0.05以上。使用NMS融合box，使用0.5阈值过滤最终的结果。

#### Focal loss

网络采用的 $\\gamma$ 值为2。训练时，每张图片约10万个anchor都参与运算。最终的loss为所有anchor对应loss的和与获得匹配anchor的数量的归一化。这么做的原因在于绝大部分未匹配的anchor的loss在focal loss中可以忽略。最后还有权重参数 $\\alpha$，它的值与 $\\gamma$相匹配，实验中 $ \\gamma =2, \\alpha=0.25 $表现最好。

#### 初始化

除了backbon网络外，除了最后一层所有新增卷积层在初始化时 $b=0$，权重高斯分布参数 $\\sigma=0.01$。分类子网络最后一层的bias为$b=-\\log((1-\\pi)/\\pi)$，其中$\\pi=0.01$。

#### 优化器

RetinaNet使用同步SGD作为优化器。训练在8个GPU上进行，batch size为16。训练步数为90k。初始学习率为0.01，之后在60k步和80k步时缩小10倍。最终的loss为Focal loss和回归子网络平滑L1 loss的和。训练过程持续时长在10～35小时之间。

### 模型架构设计

#### Anchor密度

作者通过扫描实验发现，3个scale与3个aspect ratio的组合可以获得最优的结果。

#### 速度与准确率

ResNet-101-FPN在输入图像尺度为600pixel时，推演耗时122ms。设备为Nvidia M40。

### 结论

单步检测器超越两步检测器的最大障碍在于训练过程中类别的不均衡。作者提出了Focal Loss来促使网络将学习注意力集中在困难的负样本上。并设计了全卷积单步检测器RetinaNet以及大量实验证明了Focal Loss的有效性，获得了State-of-the-art的结果。

---

### 补充

在复现BlazeFace时我大量参考了RetinaNet的TensorFlow实现，原因很简单——同样是学术文章，BlazeFace文章透漏的技术细节太少太少了。如果说RetinaNet文章给出了100个技术参数的话，BlazeFace估计只给出了10个。因此最初选择BlazeFace入手是因为它结构简单，现在看来无疑是一个巨大的错误。当我对物体检测框架还不熟悉的时候，它无法提供一个正确有效的groud truth实现用来参考。

因此，我推荐对深度学习物体检测感兴趣的小伙伴以RetinaNet作为自己学习的参照物。文章写的非常详细，同时提供PyTorch与TensorFlow的高质量实现，便于文码比对，是绝佳的学习样本。