目标检测中加入背景样本的思考,基于NanoDetPlus的QualityFocalLoss(原创)

引言

在目标检测的很多应用场景中,大多数情况下视野中是不存在检测目标的,但是在这些无目标场景下,又很容易出现误检框。为了解决这个问题,理所当然地会想到把这些无目标场景图像放入训练集中进行训练,但是这样做真的有用吗?我们需要思考一下底层的作用机制,并且进一步分析这种方法的作用有多大?最好可以进行量化分析。

训练集加入无目标图像的作用

在目标检测任务中,加入背景样本(负样本)对于训练模型具有重要作用。负样本是指那些不包含目标物体的图像或图像区域,它们对于提高模型的泛化能力和检测性能至关重要。以下是加入背景样本的几个主要作用:

  1. 降低误检测率:通过训练包含背景样本的数据集,模型可以学习到哪些区域是不包含目标物体的,从而在实际检测中减少将背景错误识别为目标的情况。

  2. 提高模型泛化能力:背景样本帮助模型理解目标物体与背景之间的区别,使模型能够更好地泛化到新的、未见过的数据上。这对于在多样化场景中进行准确检测是非常有用的。

  3. 平衡类别比例:在实际应用中,背景样本的数量往往远远超过前景样本(即包含目标的样本)。如果没有背景样本,模型可能会过度关注少数的前景样本,导致类别不平衡。加入背景样本可以帮助平衡正负样本的比例,提高模型的分类性能。

  4. 避免过拟合:在目标检测中,为了避免过拟合,需要确保模型不仅仅在训练数据上表现良好,也能在新数据上保持较好的性能。通过包含背景样本,模型可以学习到更加一般化的特征,而不是仅仅记住训练集中的特定样本。

  5. 提高检测精度:在一些目标检测算法中,如Faster R-CNN,会使用区域建议网络(RPN)来生成候选区域。通过将背景样本作为负样本,模型可以更准确地区分前景和背景,从而提高检测的精度。

  6. 难样本挖掘:在训练过程中,可以通过挖掘难以分类的负样本(hard negative examples),即那些容易被模型误判为目标的背景区域,来进一步提升模型的分类性能。这种难样本挖掘技术可以帮助模型更好地学习区分目标和背景之间的微妙差异。

综上所述,背景样本在目标检测模型的训练中扮演着重要角色,它们不仅有助于降低误检测率和提高模型的泛化能力,还能帮助模型避免过拟合,并提高整体的检测精度。(以上来自Kimi大模型)

NanoDetPlus的损失函数

NanoDetPlus中的损失函数分为三部分,类别评价使用的是QualityFocalLoss,bbox评价使用的是GIoU(Generalized Intersection over Union),除此之外,nanodetplus的回归结果是采用离散化的方法,将检测框距离中心点的四个距离(left,top,right,bottom)分别分成特征图尺度上的reg_max+1份,并计算落在0,1,…,reg_max上的概率,该部分使用DistributionFocalLoss。具体如下

self.loss_qfl = QualityFocalLoss(
    beta=self.loss_cfg.loss_qfl.beta,
    loss_weight=self.loss_cfg.loss_qfl.loss_weight,
)
self.loss_dfl = DistributionFocalLoss(
    loss_weight=self.loss_cfg.loss_dfl.loss_weight
)
self.loss_bbox = GIoULoss(loss_weight=self.loss_cfg.loss_bbox.loss_weight)

在训练时,对于无目标负样本,只对类别计算损失。对于检测框的损失计算,会从batch中剔除掉无目标样本所对应的数据和结果。所以,本节只关注QualityFocalLoss的计算过程。

以下来自https://zhuanlan.zhihu.com/p/681445323
Quality Focal Loss (QFL)是一种用于目标检测的改进损失函数。它的主要创新是将目标的定位质量(如边界框与真实对象的重叠度量,例如IoU得分)直接融合到分类损失中,形成一个联合表示。这种方法能够解决传统目标检测中分类与定位任务之间存在的不一致性问题。QFL通过为每个类别的得分赋予根据定位质量调整的权重,使得检测模型在训练过程中能够更加关注那些难以定位或分类的样本。
>
Quality Focal Loss(QFL)的基本原理可以分为以下几个要点:

  1. 联合表示法: QFL将定位质量(如IoU分数)与分类得分融合为一个联合表示,这种表示在训练和推理过程中保持一致性,有助于解决在训练和测试阶段对质量估计和分类得分使用不一致的问题。

  2. 连续标签支持: 传统的Focal Loss仅支持离散的{0, 1}标签,而QFL扩展了这一概念,支持连续的标签(如IoU分数),从0到1的浮点数,更好地反映了实际数据中的情况。

  3. 动态调整难度: QFL通过动态调整损失函数,使得模型在训练过程中更多地关注难以分类或定位的样本,从而提高模型的整体性能。

nanodetplus中该部分的代码如下

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

在我训练的网络中,输入尺寸为[128,128],为了便于分析,训练batch设为1。原始图像经过倍数8、16、32的下采样后,特征图大小分别为16×16、8×8、4×4,也就是说,对应原图上256+64+16=336个anchor center。同时,网络的分类输出pred的维度为[336,num_class],也就是每一个center point对应一个one_hot编码。在代码中,

  • line 21:label和score的维度为[336,1],该部分为gt的值。label的初始值为num_class(因为类别编号是0到num_class-1,所以初始值为num_class表示不属于任何一个类),根据gt
    box和anchor center的包含关系,对label中被gt box包含的center point所对应的位置设为gt label
    id,同时score中相应的位置设为质量分数(质量分数有专门的计算方法DynamicSoftLabelAssigner,此处暂不讲解)。
  • line 27:此处使用pred和zerolabel做BCE损失,暂时将所有gt label设为0(此处指当作负样本)计算loss
  • line 28-38:找到正样本(在gt box中的center point)对应的位置,单独计算loss
  • line 40-41:对所有位置的loss求和作为分类损失

无目标图像在训练时怎么计算loss

对于无目标样本来说,上一节代码中的line 27等同于对无目标样本做了损失,line 32 得到的pos为空,自然最后返回的损失值就是line 27的值。

总结

换句话说,在有目标样本的训练过程中,把非gt box的其他位置都当作负样本进行了损失计算,无目标样本无非就是全图位置都是负样本罢了,因此理论和实践上来讲,都会对网络训练有所提升。

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾系桉宁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值