Alpha-IoU Loss:

论文的名字很好,反映了本文的核心想法。作者将现有的基于IoU Loss推广到一个新的Power IoU系列 Loss,该系列具有一个Power IoU项和一个附加的Power正则项,具有单个Power参数α,称这种新的损失系列为α-IoU Loss。

前言

  • 总所周知,目标检测通过Bounding box回归来预测来定位图像中的目标,早期的目标检测工作使用IoU作为定位损失。然而,当预测框与Ground truth不重叠时,IoU损失会出现梯度消失问题,导致收敛速度减慢,导致检测器不准确。这激发了几种改进的基于IoU的损失设计,包括GIoU、DIoU、CIoU。GIoU在IoU损失中引入惩罚项以缓解梯度消失问题,而DIoU和CIoU在惩罚项中考虑了预测框与Ground truth 之间的中心点距离和宽高比。

  • 在本文中,作者通过在现有的IoU Loss中引入power 变换,提出了一个新的IoU损失函数。首先将Box-Cox变换应用于IoU损失,并将其推广为power IoU loss:αααα,记为α。这里进一步简化α为αα,并将其推广到更一般的形式通过加上额外的power正则化项。这使本文所提损失函数能够概括现有的基于IoU的损失,包括GIoU、DIoU和CIoU,到一个新的power IoU损失函数以获得更准确的边界框回归和目标检测。

本文贡献

  • 提出了一种新的power IoU损失函数,称为α-IoU,用于精确的bbox回归和目标检测。α-IoU是基于IoU的现有损失的统一幂化;
  • 分析了α-IoU的一系列性质,包括顺序保留和损失/梯度重加权,表明适当选择α(即α > 1)有助于提高High IoU目标的损失和梯度自适应加权的bbox回归精度;
  • 经验表明,在多个目标检测数据集和模型上,α-IoU损失优于现有的基于IoU的损失,并为小数据集和噪声Box提供更强的鲁棒性。

α-IoU家族表达式

  • 大家可以看到α-IoU其实非常简单,在IOU及惩罚项表达式中进行了幂的运算

α-CIoU代码

  • 原文中作者提到当α=3时,训练会取得比较好的效果,因此在IOU及惩罚项上使用paddle.pow(x,3)进行幂的运算就可以实现,iou_loss.py在ppdet/modeling/losses/iou_loss.py这个位置,通过修改iou_loss.py一行代码即可开始训练,代码如下:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np

import paddle

from ppdet.core.workspace import register, serializable
from ..bbox_utils import bbox_iou

__all__ = ['DIouLoss']

@register
@serializable
class DIouLoss(GIoULoss):
    """
    Distance-IoU Loss, see https://arxiv.org/abs/1911.08287
    Args:
        loss_weight (float): giou loss weight, default as 1
        eps (float): epsilon to avoid divide by zero, default as 1e-10
        use_complete_iou_loss (bool): whether to use complete iou loss
    """

    def __init__(self, loss_weight=1., eps=1e-10, use_complete_iou_loss=True):
        super(DIouLoss, self).__init__(loss_weight=loss_weight, eps=eps)
        self.use_complete_iou_loss = use_complete_iou_loss

    def __call__(self, pbox, gbox, iou_weight=1.):
        x1, y1, x2, y2 = paddle.split(pbox, num_or_sections=4, axis=-1)
        x1g, y1g, x2g, y2g = paddle.split(gbox, num_or_sections=4, axis=-1)
        cx = (x1 + x2) / 2
        cy = (y1 + y2) / 2
        w = x2 - x1
        h = y2 - y1

        cxg = (x1g + x2g) / 2
        cyg = (y1g + y2g) / 2
        wg = x2g - x1g
        hg = y2g - y1g

        x2 = paddle.maximum(x1, x2)
        y2 = paddle.maximum(y1, y2)

        # A and B
        xkis1 = paddle.maximum(x1, x1g)
        ykis1 = paddle.maximum(y1, y1g)
        xkis2 = paddle.minimum(x2, x2g)
        ykis2 = paddle.minimum(y2, y2g)

        # A or B
        xc1 = paddle.minimum(x1, x1g)
        yc1 = paddle.minimum(y1, y1g)
        xc2 = paddle.maximum(x2, x2g)
        yc2 = paddle.maximum(y2, y2g)

        intsctk = (xkis2 - xkis1) * (ykis2 - ykis1)
        intsctk = intsctk * paddle.greater_than(
            xkis2, xkis1) * paddle.greater_than(ykis2, ykis1)
        unionk = (x2 - x1) * (y2 - y1) + (x2g - x1g) * (y2g - y1g
                                                        ) - intsctk + self.eps
        iouk = intsctk / unionk

        # DIOU term
        dist_intersection = (cx - cxg) * (cx - cxg) + (cy - cyg) * (cy - cyg)
        dist_union = (xc2 - xc1) * (xc2 - xc1) + (yc2 - yc1) * (yc2 - yc1)
        diou_term = (dist_intersection + self.eps) / (dist_union + self.eps)

        # CIOU term
        ciou_term = 0
        if self.use_complete_iou_loss:
            ar_gt = wg / hg
            ar_pred = w / h
            arctan = paddle.atan(ar_gt) - paddle.atan(ar_pred)
            ar_loss = 4. / np.pi / np.pi * arctan * arctan
            alpha = ar_loss / (1 - iouk + ar_loss + self.eps)
            alpha.stop_gradient = True
            ciou_term = alpha * ar_loss

        diou = paddle.mean((1 - paddle.pow(iouk,3) + paddle.pow(ciou_term,3) + paddle.pow(diou_term,3)) * iou_weight)

pow(iouk,3) + paddle.pow(ciou_term,3) + paddle.pow(diou_term,3)) * iou_weight)

        return diou * self.loss_weight

对 α-CIoU性能进行验证

  • (1)git PaddleDetection目标检测套件
!git clone https://gitee.com/gao-rui123/paddle-detection1125.git
  • (2)配置环境目录
%cd paddle-detection1125/
  • (3)安装依赖
!pip install -r requirements.txt -i https://mirror.baidu.com/pypi/simple
!pip install paddleslim==2.2.1
  • (4)本次实验使用了PaddleDetection套件提供的交通路标数据集,所使用的模型是PP-PicoDet模型中的picodet_m_320_coco进行实现,学习率均设置为0.01,优化器为Momentum,L2正则项为0.00004,加载与预训练参数,分别对比了GIOU、CIOU、α-CIOU.

  • (5)数据集可以按照以下进行配置:

  • (6)默认版本为GIOU,训练完成后分别修改configs/picodet/base/picodet_esnet.yml中loss_bbox的name为DIouLoss,以及按照上述修改iou_loss.py,完成CIOU、α-CIOU的对比训练。

      loss_bbox:
    
      	name: DIouLoss
    
      	loss_weight: 2.0
    
!python tools/train.py -c configs/picodet/picodet_m_320_coco.yml --eval --use_vdl=True --vdl_log_dir='./output_vdl'

GIOU、CIOU、α-CIOU训练mAP可视化

  • 绿色曲线为GIOU
  • 蓝色曲线为CIOU
  • 紫色曲线为α-CIOU

GIOU、CIOU、α-CIOU可视化细节

总结

实验结果表明:

  • α=3时增加了high IoU目标的损失和梯度,进而提高了bbox回归精度。

  • power参数α可作为调节α-IoU损失的超参数以满足不同水平的bbox回归精度,其中α >1通过更多地关注High IoU目标来获得高的回归精度(即High IoU阈值)。

  • 从经验上表明,α-IoU损失家族可以很容易地用于改进检测器的效果,在干净或嘈杂的环境下,不会引入额外的参数,也不增加训练/推理时间。

请点击此处查看本环境基本用法.

Please click here for more detailed instructions.

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐