focal loss RitinaNet学习笔记

机器学习中期报告

Focal Loss for Dense Object Detection

Tsung-Yi Lin   Priya Goyal   Ross Girshick   Kaiming He   Piotr Dollar´

Facebook AI Research (FAIR)

 

参考:

https://blog.csdn.net/c9Yv2cf9I06K2A9E/article/details/78920998

https://blog.csdn.net/u014380165/article/details/77019084

1、提出背景:

1.1、问题提出

object detection的算法主要可以分为两大类:two-stage detector和single-stage detector。前者是指类似Faster RCNN,RFCN这样需要region proposal的检测算法,这类算法可以达到很高的准确率,但是速度较慢。虽然可以通过减少proposal的数量或降低输入图像的分辨率等方式达到提速,但是速度并没有质的提升。后者是指类似YOLO,SSD这样不需要region proposal,直接回归的检测算法,这类算法速度很快,但是准确率不如前者。简单来看就是如图1.1所示。

 

 

 

 

 

图1.1 目标检测算法分类

本文思考:能否single-stage detector在保持原有速度的情况下,有和two-stage相似的精确度呢?

1.2、解决问题

本文从为什么single-stage精确度低而two-stage精确度高入手,作者认为是:single-stage detector样本的类别数量不均衡导致精确度低,且类别多的样本又多为easy-sample,导致了hard-easy sample不平衡那就要从以下几点仔细思考这个问题:

1.2.1、 为什么single-stage类别不平衡?

对于single-stage一张图像可能生成成千上万的candidate locations(100k/image),因为要考虑到比例、大小、旋转不变性等因素所以生成的是十分密集的proposals。但是其中只有很少一部分是包含object的,及是ground truth的前景,而大多数都是背景。这就带来了严重的正负样本(及前景背景类间)不均衡。

1.2.2、 two-stage为什么不存在类别不平衡?

由于two-stage的结构性质,在第一个stage(比如rpn)之后,通过得到的fore的置信度和nms,把大量背景概率高的easy negative给过滤掉。并且在进入第二个stage进行类别和回归预测之前会根据IOU的大小来调整positive和negative example的比例,比如设置为fore:back=1:3。如果fore太少人工补齐。这样就避免了fore-back不平衡问题。

1.2.3、 类别不平衡带来什么后果?

1)负样本数量太大,占总的loss的大部分,而且多是容易分类的,因此使得模型的优化方向并不是我们所希望的那样。及原文说的“lead to degenerate models”

2)大多negative example不在前景和背景的过渡区域上,分类很明确(这种易分类的negative称为easy negative),训练时对应的背景类score会很大,换个角度看就是单个example的loss很小,反向计算时梯度小。梯度小造成easy negative example对参数的收敛作用很有限,我们更需要loss大的对参数收敛影响也更大的example即hard positive/negative example,简称hard sample。及原文说的“training is inefficient: most easy negatives contribute no useful learning signal”

2、研究

2.1、以往研究

论文里提出了两个解决hard-easy sample的方法:

  1. bootstrapping:

定义:在有限的样本中进行重采样,主要用于传统机器学习方法中。

举例:在二分类SVM中,对于在分界线周围的值(相当于loss大,不容易拟合的值)我们在后面的迭代中保留,离分界线远的值(相当于Loss小,容易分类的值)在后面的迭代中去掉。

  1. Online Hard Example Mining (OHEM):

定义:在目标检测中对每个box的loss值进行排序。之后对box之间进行nms。选择loss较大的进行反向传播,loss晓得直接忽略。

缺点:增加hard sample的权重,但完全忽略了easy sample的迭代。

2.2、研究思路(非论文)

二分类问题的标准 loss 是交叉熵。

其中 y∈{0,1} 是真实标签,是预测值。当然,对于二分类我们几乎都是用 sigmoid 函数激活 y =σ(x),所以相当于:

我们有 1−σ(x)=σ(−x)。

提出一个类似于OHEM的一种loss,主要思想为:正样本的预测值大于 0.5 的,或者负样本的预测值小于 0.5 的,我都不更新了,把注意力集中在预测不准的那些样本,阈值可以调整。假设阈值为0.5则,其中:上面的loss可以和下面的Loss等价。   其中:  而这个loss又和下面的Loss等价:。注:我们并不在乎里的x是什么,只在乎他是不是大于0,小于0的。而和并不等,但是符号相同,那么上式就成立。

但是很明显完全像OHEM是不合理的,及“不能只是要告诉模型正样本的预测值大于0.5就不更新了,而是要告诉模型当其大于0.5后就只需要保持就好了”。及我们不能对Loss小的级完全忽略不迭代了。解决这个问题的一个方法就是“软化” loss,“软化”就是把一些本来不可导的函数用一些可导函数来近似,数学角度应该叫“光滑化”。我们将θ(x)“软化”,而软化它就再容易不过,它就是 sigmoid 函数。我们有:

2.3 Focal loss

2.3.1、Focal Loss

如果::。

2.3.2、参数含义

1):调节权重,调节easy-hard sample。>0使得减少易分类样本的损失。使得更关注于困难的、错分的样本。例如为2,对于正类样本而言,预测结果为0.95肯定是简单样本,所以(1-0.95)的次方就会很小,这时损失函数值就变得更小。而预测概率为0.3的样本其损失相对很大。对于负类样本而言同样,预测0.1的结果应当远比预测0.7的样本损失值要小得多。对于预测概率为0.5时,损失只减少了0.25倍,所以更加关注于这种难以区分的样本。这样减少了简单样本的影响,大量预测概率很小的样本叠加起来后的效应才可能比较有效。

2):控制权重,调节fore-back sample。为0时即为交叉熵损失函数,当增加时,影响也在增加。实验发现为2是最优。

具体影响如图2.1。

图2.1 foclal loss 对各种样本的loss影响

3、建模

3.1、整体网络结构

本文基于focal loss提出了一个新的目标检测网络:RitinaNet。网络整体结构可以总结为:RetinaNet = ResNet50(101)+FPN + Decoupled sub-network + Focal loss。具体可以如图3.1所示:

图3.1 RitinaNet网络结构

3.2、主干网结构

3.2.1、Resnet

以resnet50为主,结构如下图3.2所示。

图3.2 Resnet50结构

主要代码段:(Pytorch框架)

class BasicBlock(nn.Module):

    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):

        super(BasicBlock, self).__init__()

        self.conv1 = conv3x3(inplanes, planes, stride)

        self.bn1 = nn.BatchNorm2d(planes)

        self.relu = nn.ReLU(inplace=True)

        self.conv2 = conv3x3(planes, planes)

        self.bn2 = nn.BatchNorm2d(planes)

        self.downsample = downsample

        self.stride = stride

    def forward(self, x):

        residual = x

        out =self.relu( self.bn1(self.conv1(x)))

        out = self.bn2(self.conv2(out))

       if self.downsample is not None:

            residual = self.downsample(x)

        out += residual

        out = self.relu(out)

        return out

3.2.2、FPN

RitinaNet里的FPN与FPN论文提出的有了一些改动,本论文里的框架如图3.3所示。

图3.3 RitinaNet里FPN结构

主要代码段:

def forward(self, inputs):

        C3, C4, C5 = inputs

        P5_x = self.P5_1(C5)

        P5_upsampled_x = self.P5_upsampled(P5_x)

        P5_x = self.P5_2(P5_x)

        

        P4_x = self.P4_1(C4)

        P4_x = P5_upsampled_x + P4_x

        P4_upsampled_x = self.P4_upsampled(P4_x)

        P4_x = self.P4_2(P4_x)

 

        P3_x = self.P3_1(C3)

        P3_x = P3_x + P4_upsampled_x

        P3_x = self.P3_2(P3_x)

 

        P6_x = self.P6(C5)

 

        P7_x = self.P7_1(P6_x)

        P7_x = self.P7_2(P7_x)

 

        return [P3_x, P4_x, P5_x, P6_x, P7_x]

3.3.3、分类和回归预测

4、试验

4.1论文试验

图4.1对比forground和background样本在不同γ情况下的累积误差。纵坐标是归一化后的损失,横坐标是总的foreground或background样本数的百分比。可以看出γ的变化对正(forground)样本的累积误差的影响并不大,但是对于负(background)样本的累积误差的影响还是很大的(γ=2时,将近99%的background样本的损失都非常小)。

图4.1 对比forground和background样本在不同γ情况下的累积误差

图4.2进行了的对比。可以看出太大就相当于OHEM,不理想。如果太小又不能很好收有效训练。

图4.2 对比实验结果

图4.3是与不同模型在coco数据集上的test结果比较。可以看出他在保持准确度的情况下比其他的快,而保持速度的情况下比其他的准确度高。及曲线一直处在其他结果的左上方

图4.3 与不同模型在coco数据集上的test结果比较

4.2自己试验

图4.4是基于COCO数据集加载预训练resnet50权重,并且自己分6批次(6次调节参数)bathsize=5训练近70次的结果。左图是COCO数据集里的val数据。右图是自己数据。Fps~4.1。

图4.4 实验结果

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值