论文阅读笔记 | 目标检测算法——Generalized Focal Lossv1,v2

简介: 论文阅读笔记 | 目标检测算法——Generalized Focal Lossv1,v2

1. Generalized Focal Loss


Abstract

One-stage检测器基本上将目标检测定义为密集分类和定位(即边界盒回归)。该分类方法通常采用Focal loss进行优化,回归框位置通常采用狄拉克分布法进行学习。One-stage检测器的一个最新趋势是引入一个独立的预测分支来估计定位质量,预测的质量有助于分类,以提高检测性能。本文研究了质量估计、分类和定位这三个基本要素的表示。


1.1 Problem

作者发现了目前这种方法的两个问题:


  1. 质量的评估在训练与推理之使用不一致。

1)定位质量估计和分类评分通常是独立训练的,但在推理过程中会综合使用(如乘法)

image.png

2) 目前定位质量估计的监督只分配给阳性样本,这是不可靠的,因为阴性样本可能有机会获得不可控制的更高的质量预测

image.png

ps:图 (b)中的散点图表示具有预测分数的随机抽样实例,其中蓝点清楚地说明了单独表示时预测分类分数和预测IoU分数之间的弱相关性。红圈中的部分包含许多可能的负面因素,伴随着大量的质量预测,其中所蕴含的负样本,可能会排在正样本前面,削弱了检测器的性能。


这两个因素导致了训练和测试之间的差距,并可能会降低检测性能,例如,在NMS中,随机高质量分数的负实例可能排在质量预测较低的正实例前面。


  1. 边界框的不灵活表示

广泛使用的包围盒表示可以看作是目标盒坐标的Dirac delta分布,但是它没有考虑到数据集的模糊性和不确定性。作者希望用一种general的分布去建模边界框的表示。

image.png

ps:希望这一般分布的学习表示方法可以通过其形状来反映底层信息,其中平坦分布表示边界不清楚、不明确(圆形),尖锐分布表示边界清楚的情况。


1.2 Solve

为了解决上述问题,作者设计了新的边界框表示及其定位质量。


1)For localization quality representation

为了保证training和test一致,同时还能够兼顾分类score和质量预测score都能够训练到所有的正负样本,那就是将两者的表示进行联合。这个合并也非常有意思,从物理上来讲,依然还是保留分类的向量,但是对应类别位置的置信度的物理含义不再是分类的score,而是改为质量预测的score,这样就做到了两者的联合表示。 将分类分数和IoU分数统一为一个联合的单一变量(记作“分类IoU联合表征”) 。 此外,负面的将被监督为0质量分数,从而整体质量预测变得更加可靠。


2)For bounding box representation

提出通过直接学习其连续空间上的离散概率分布来表示盒位的任意分布,而不引入任何其他更强的先验(如高斯分布)。然而,对于提出的分类­IoU联合表征的情况,除了仍然存在不平衡风险外,我们还面临一个新的问题,即连续IoU标签(0~ 1)作为监管,因为原来的FL目前只支持离散的{1,0}类别标签。我们成功地解决了这个问题,将FL从{1,0}离散版本扩展到其连续变体,称为Generalized Focal Loss广义焦点损耗(GFL)。

Quality Focal Loss (QFL)专注于一组稀疏的难例子,同时对相应类别产生连续的0 ~ 1质量估计;Distribution Focal Loss(DFL)使得网络在任意、灵活分布的情况下,快速地专注于学习目标包围盒连续位置周围值的概率。


Generalized Focal Loss (GFL)带来了三个优点:

1)当One­stage与附加的质量估计想结合时,它弥补了训练和测试之间的差距,从而使分类和定位质量的表示更加简单、联合和有效

2)很好地模拟了边界框的底层分布,提供了更丰富、更准确的盒位置

3)不引入额外开销的情况下,性能持续提高


Quality Focal Loss (QFL)

为了解决上述训练阶段和测试阶段不一致的问题,我们提出了质量(即IoU分数)和分类分数(以下简称“分类­IoU”)的联合表示,其监督软化了标准one­hot类别标签,导致可能浮动相应的类别,使得targety在∈[0,1]上。具体来说,y = 0表示负样本质量分数为0,而0 < y ≤ 1表示Iou分数为y的正样本。其中,质量标签y遵循常规定义,既预测的边界框与对应的真实边界框之间的iou得分,动态值为0~1.之后,对y进行sigmoid算子运算,实现多类实现,将sigmoid的输出标记为σ。

image.png


Distribution Focal Loss (DFL)

采用从位置到边界盒四周的相对偏移量作为回归目标(见图4中的回归分支)。边界盒回归模型的常规操作被标记为Dirac delta分布δ(x ­ y)。作者提出通过明确鼓励接近目标的值的高概率来优化p(x)的形状。此外,通常情况下,最合适的底层位置(如果存在的话)将离粗标签不远。

image.png

image.png


Generalized Focal Loss (GFL)

值得注意的是,QFL和DFL可以统一成一个一般形式,在本文中称为Generalized Focal Loss (GFL)。

image.png

损失函数的演化过程:

image.png


1.3 Append

about the Distributions

下图描述了狄拉克delta、高斯分布和提出的一般分布的思想:

image.png

以下表格是这几个分布的关键比较:

image.png

高斯假设的损耗目标实际上是动态加权的L2 loss,其训练权值与预测方差σ相关。当在边缘水平优化时,它在某种程度上类似于Dirac delta(标准L2损耗)。此外,还不清楚如何将高斯假设集成到基于iou-base的Loss公式中,因为它将目标表示的表达式与其优化目标紧密耦合。因此它不能享受基于iou-base的优化的好处。相比之下,作者提出的一般分布解耦了表示和损失目标,使其适用于任何类型的优化,包括边缘级和盒级。


IoU-branch superior than centerness-branch

在对比实验中,作者发现IoU作为框预测质量的度量会始终比centerness更优。具体深入分析了一些原因,发现的确从原理上来讲,IoU可能作为质量的估计更加合适。具体原因如下:


1) IoU本身就是最终metric的衡量标准,所以用来做质量估计和排序是非常自然的。


2) centerness有一些不可避免的缺陷,比如对于stride=8的FPN的特征层(也就是P3),会存在一些小物体他们的centerness label极度小甚至接近于0,而IoU就会相对好很多,如下图所示。

image.png

这里引用作者知乎的一段话:


我们也统计了一下两者作为label的分布情况,如图:

image.png

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


More Examples of Distributed Bounding Boxes

以下是作者的发现:


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


例子:

image.png

image.png


2. Generalized Focal Loss V2


2.1 Problem

在GFLV1中,作者提出了对边界框进行一个一般化的分布表示建模,有了这个可以学习的表示之后,可以对物品的位置进行一个可视化。基本上那些非常清晰明确的边界,它的分布都很尖锐;而模糊定义不清的边界,它们学习到的分布基本上会平下来,而且有的时候还经常出现双峰的情况。


所以这就是GFLV1中遗漏的一个重要问题,如何让这个一般化的分布充分发挥出它的作用?


作者的想法:


这也是GFLV2的一大出发点,在GFLV2中,我们正是利用了刚才可视化观察到的这个普适的规律:既然分布的形状和真实的定位质量非常相关,那么我们为什么不好好利用一下,用能够表达分布形状的统计量去指导最终定位质量的估计


此前观察得出的“分布的形状与真实的定位质量具有较强的相关性”这个假设是基本成立的。基于这个分析,我们即决定采用学习到的分布的形状来帮助(协助指导)定位质量估计,从而提升检测的整体性能。


2.2 Solve

那么如何来刻画分布的形状呢?我们采用了一个非常简单的做法,就是直接取我们学习到的分布(分布是用离散化的多个和为1的回归数值表示的)的Topk数值。其实理解起来也不难,因为所有数值和为1,如果分布非常尖锐的话,Topk这几个数通常就会很大;反之Topk就会比较小。选择Topk还有一个重要的原因就是它可以使得我们的特征与对象的scale尽可能无关,如下图所示:

image.png

简单来说就是长得差不多形状的分布要出差不多结果的数值,不管它峰值时落在小scale还是大scale。我们把4条边的分布的Topk

concat在一起形成一个维度非常低的输入特征向量(可能只有10+或20+),用这个向量再接一个非常小的fc层(通常维度为32、64),最后再变成一个Sigmoid之后的scalar乘到原来的分类表征中,就完事啦~具体model参考下图,其中红色框就是比GFLV1多出来的Distribution-Guided

Quality Predictor部分,也就是本文的核心。


结构如图所示:

image.png


要说GFLV2最大的亮点其实是从思考角度上的。如下图所示,此前有很多工作都在尝试用不同空间维度的卷积特征去增强分类表示(或者是分类-质量联合表示),但鲜有工作落脚于找到一个更加相关的、复杂度非常低的统计特征来指导质量的估计。用一张图可以体现出GFLV2和现有工作的最大区别(同时,如果我没有miss掉一些工作的话,GFLV2也是检测历史上第一个用学习到的分布的统计特征去指导质量估计的)

image.png


2.3 Append

最后,我们还可视化了一下GFLV2是如何利用好更好的定位质量估计来保障更精准的结果的(我们给出了NMS前后的所有框,并列出了NMS

score排前4的框和它们的分数):

image.png

大家可以看到,其他算法里面也有非常准的预测框,但是它们的score通常都排到了第3第4的位置,而score排第一的框质量都比较欠佳。相反,GFLV2也有预测不太好的框,但是质量较高的框都排的非常靠前,性能就是这么的给提上来。


3. Code


参考代码:https://github.com/RangiLyu/nanodet


import torch
import torch.nn as nn
import torch.nn.functional as F
from .utils import weighted_loss
@weighted_loss
def quality_focal_loss(pred, target, beta=2.0):
    r"""Quality Focal Loss (QFL) is from `Generalized Focal Loss: Learning
    Qualified and Distributed Bounding Boxes for Dense Object Detection
    <https://arxiv.org/abs/2006.04388>`_.
    Args:
        pred (torch.Tensor): Predicted joint representation of classification
            and quality (IoU) estimation with shape (N, C), C is the number of
            classes.
        target (tuple([torch.Tensor])): Target category label with shape (N,)
            and target quality label with shape (N,).
        beta (float): The beta parameter for calculating the modulating factor.
            Defaults to 2.0.
    Returns:
        torch.Tensor: Loss tensor with shape (N,).
    """
    assert (
        len(target) == 2
    ), """target for QFL must be a tuple of two elements,
        including category label and quality label, respectively"""
    # label denotes the category id, score denotes the quality score
    label, score = target
    # negatives are supervised by 0 quality score
    pred_sigmoid = pred.sigmoid()
    scale_factor = pred_sigmoid
    zerolabel = scale_factor.new_zeros(pred.shape)
    loss = F.binary_cross_entropy_with_logits(
        pred, zerolabel, reduction="none"
    ) * scale_factor.pow(beta)
    # FG cat_id: [0, num_classes -1], BG cat_id: num_classes
    bg_class_ind = pred.size(1)
    pos = torch.nonzero((label >= 0) & (label < bg_class_ind), as_tuple=False).squeeze(
        1
    )
    pos_label = label[pos].long()
    # positives are supervised by bbox quality (IoU) score
    scale_factor = score[pos] - pred_sigmoid[pos, pos_label]
    loss[pos, pos_label] = F.binary_cross_entropy_with_logits(
        pred[pos, pos_label], score[pos], reduction="none"
    ) * scale_factor.abs().pow(beta)
    loss = loss.sum(dim=1, keepdim=False)
    return loss
@weighted_loss
def distribution_focal_loss(pred, label):
    r"""Distribution Focal Loss (DFL) is from `Generalized Focal Loss: Learning
    Qualified and Distributed Bounding Boxes for Dense Object Detection
    <https://arxiv.org/abs/2006.04388>`_.
    Args:
        pred (torch.Tensor): Predicted general distribution of bounding boxes
            (before softmax) with shape (N, n+1), n is the max value of the
            integral set `{0, ..., n}` in paper.
        label (torch.Tensor): Target distance label for bounding boxes with
            shape (N,).
    Returns:
        torch.Tensor: Loss tensor with shape (N,).
    """
    dis_left = label.long()
    dis_right = dis_left + 1
    weight_left = dis_right.float() - label
    weight_right = label - dis_left.float()
    loss = (
        F.cross_entropy(pred, dis_left, reduction="none") * weight_left
        + F.cross_entropy(pred, dis_right, reduction="none") * weight_right
    )
    return loss
class QualityFocalLoss(nn.Module):
    r"""Quality Focal Loss (QFL) is a variant of `Generalized Focal Loss:
    Learning Qualified and Distributed Bounding Boxes for Dense Object
    Detection <https://arxiv.org/abs/2006.04388>`_.
    Args:
        use_sigmoid (bool): Whether sigmoid operation is conducted in QFL.
            Defaults to True.
        beta (float): The beta parameter for calculating the modulating factor.
            Defaults to 2.0.
        reduction (str): Options are "none", "mean" and "sum".
        loss_weight (float): Loss weight of current loss.
    """
    def __init__(self, use_sigmoid=True, beta=2.0, reduction="mean", loss_weight=1.0):
        super(QualityFocalLoss, self).__init__()
        assert use_sigmoid is True, "Only sigmoid in QFL supported now."
        self.use_sigmoid = use_sigmoid
        self.beta = beta
        self.reduction = reduction
        self.loss_weight = loss_weight
    def forward(
        self, pred, target, weight=None, avg_factor=None, reduction_override=None
    ):
        """Forward function.
        Args:
            pred (torch.Tensor): Predicted joint representation of
                classification and quality (IoU) estimation with shape (N, C),
                C is the number of classes.
            target (tuple([torch.Tensor])): Target category label with shape
                (N,) and target quality label with shape (N,).
            weight (torch.Tensor, optional): The weight of loss for each
                prediction. Defaults to None.
            avg_factor (int, optional): Average factor that is used to average
                the loss. Defaults to None.
            reduction_override (str, optional): The reduction method used to
                override the original reduction method of the loss.
                Defaults to None.
        """
        assert reduction_override in (None, "none", "mean", "sum")
        reduction = reduction_override if reduction_override else self.reduction
        if self.use_sigmoid:
            loss_cls = self.loss_weight * quality_focal_loss(
                pred,
                target,
                weight,
                beta=self.beta,
                reduction=reduction,
                avg_factor=avg_factor,
            )
        else:
            raise NotImplementedError
        return loss_cls
class DistributionFocalLoss(nn.Module):
    r"""Distribution Focal Loss (DFL) is a variant of `Generalized Focal Loss:
    Learning Qualified and Distributed Bounding Boxes for Dense Object
    Detection <https://arxiv.org/abs/2006.04388>`_.
    Args:
        reduction (str): Options are `'none'`, `'mean'` and `'sum'`.
        loss_weight (float): Loss weight of current loss.
    """
    def __init__(self, reduction="mean", loss_weight=1.0):
        super(DistributionFocalLoss, self).__init__()
        self.reduction = reduction
        self.loss_weight = loss_weight
    def forward(
        self, pred, target, weight=None, avg_factor=None, reduction_override=None
    ):
        """Forward function.
        Args:
            pred (torch.Tensor): Predicted general distribution of bounding
                boxes (before softmax) with shape (N, n+1), n is the max value
                of the integral set `{0, ..., n}` in paper.
            target (torch.Tensor): Target distance label for bounding boxes
                with shape (N,).
            weight (torch.Tensor, optional): The weight of loss for each
                prediction. Defaults to None.
            avg_factor (int, optional): Average factor that is used to average
                the loss. Defaults to None.
            reduction_override (str, optional): The reduction method used to
                override the original reduction method of the loss.
                Defaults to None.
        """
        assert reduction_override in (None, "none", "mean", "sum")
        reduction = reduction_override if reduction_override else self.reduction
        loss_cls = self.loss_weight * distribution_focal_loss(
            pred, target, weight, reduction=reduction, avg_factor=avg_factor
        )
        return loss_cls



参考链接:


1. 大白话 Generalized Focal Loss

2. 大白话 Generalized Focal Loss V2

3. Nanodet


目录
相关文章
|
3天前
|
机器学习/深度学习 自然语言处理 算法
调研180多篇论文,这篇综述终于把大模型做算法设计理清了
《A Systematic Survey on Large Language Models for Algorithm Design》综述了过去三年大型语言模型(LLMs)在算法设计中的应用。LLMs通过自然语言处理技术,助力生成、优化和验证算法,在优化、机器学习、数学推理等领域展现出广泛应用前景。尽管存在资源需求高、结果不确定等挑战,LLMs仍为算法设计带来新机遇。论文地址:https://arxiv.org/abs/2410.14716。
29 14
|
1月前
|
机器学习/深度学习 监控 算法
基于反光衣和检测算法的应用探索
本文探讨了利用机器学习和计算机视觉技术进行反光衣检测的方法,涵盖图像预处理、目标检测与分类、特征提取等关键技术。通过YOLOv5等模型的训练与优化,展示了实现高效反光衣识别的完整流程,旨在提升智能检测系统的性能,应用于交通安全、工地监控等领域。
|
2月前
|
监控 算法 数据安全/隐私保护
基于三帧差算法的运动目标检测系统FPGA实现,包含testbench和MATLAB辅助验证程序
本项目展示了基于FPGA与MATLAB实现的三帧差算法运动目标检测。使用Vivado 2019.2和MATLAB 2022a开发环境,通过对比连续三帧图像的像素值变化,有效识别运动区域。项目包括完整无水印的运行效果预览、详细中文注释的代码及操作步骤视频,适合学习和研究。
|
1月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于GA-PSO-SVM算法的混沌背景下微弱信号检测matlab仿真
本项目基于MATLAB 2022a,展示了SVM、PSO、GA-PSO-SVM在混沌背景下微弱信号检测中的性能对比。核心程序包含详细中文注释和操作步骤视频。GA-PSO-SVM算法通过遗传算法和粒子群优化算法优化SVM参数,提高信号检测的准确性和鲁棒性,尤其适用于低信噪比环境。
|
1月前
|
存储 JSON 算法
TDengine 检测数据最佳压缩算法工具,助你一键找出最优压缩方案
在使用 TDengine 存储时序数据时,压缩数据以节省磁盘空间是至关重要的。TDengine 支持用户根据自身数据特性灵活指定压缩算法,从而实现更高效的存储。然而,如何选择最合适的压缩算法,才能最大限度地降低存储开销?为了解决这一问题,我们特别推出了一个实用工具,帮助用户快速判断并选择最适合其数据特征的压缩算法。
56 0
|
2月前
|
机器学习/深度学习 安全 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(下)
50 0
|
2月前
|
安全 搜索推荐 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(上)
38 0
|
3天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
110 80
|
22天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
8天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。

热门文章

最新文章