目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss

目标检测 回归损失函数

  • 1、Smooth L1 Loss
  • 2、 IoU Loss
  • 3、 GIoU Loss (Generalized-IoU Loss)
  • 4、 DIoU Loss (Distance-IoU Loss)
  • 5、 CIoU Loss (Complete-IoU Loss)
  • 6、总结
  • 7、代码

目标检测任务的损失函数由 Classificition Loss 和 Bounding Box Regeression Loss 两部分构成。

本文介绍目标检测任务中近几年来Bounding Box Regression Loss Function的演进过程,其演进路线是:
Smooth L1 Loss → \rightarrow IoU Loss → \rightarrow GIoU Loss → \rightarrow DIoU Loss → \rightarrow CIoU Loss

本文亦按照此路线进行讲解。


1、Smooth L1 Loss

由微软rgb大神提出,Fast RCNN论文提出该方法

1) x x x 表示模型的预测值, y y y 表示真实值, z = x − y z = x - y z=xy 表示预测值与真实值之间的差异

常用的 L1 lossL2 Losssmooth L1 loss 定义分别为:
\quad
\quad \quad L L 1 ( x , y ) = ∣ x − y ∣ = ∣ z ∣ L_{L1}(x,y) = |x - y| = |z| LL1(x,y)=xy=z
\quad
\quad \quad L L 2 ( x , y ) = 0.5 ( x − y ) 2 = 0.5 z 2 L_{L2}(x,y) = 0.5(x - y)^2 =0.5z^2 LL2(x,y)=0.5(xy)2=0.5z2
\quad
\quad \quad L s m o o t h L 1 ( x , y ) = { 0.5 ( x − y ) 2 = 0.5 z 2 , if  ∣ x − y ∣ < 1 ∣ x − y ∣ − 0.5 = ∣ z ∣ − 0.5 , otherwise L_{smoothL1}(x,y)=\begin{cases} 0.5(x-y)^2 = 0.5z^2, & \text{if } |x-y|<1 \\ |x-y|-0.5= |z|-0.5, & \text{otherwise} \end{cases} LsmoothL1(x,y)={0.5(xy)2=0.5z2,xy0.5=z0.5,if xy<1otherwise

\quad
目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第1张图片

\quad
上述的 3个损失函数对 z 的导数分别为:
\quad
\quad \quad ∂ L L 1 ( x , y ) ∂ z = { 1 , if  z ≥ 0 − 1 , otherwise \frac{\partial{L_{L1}(x,y)}}{\partial z} = \begin{cases} 1, & \text{if } z \geq0 \\ -1, & \text{otherwise} \end{cases} zLL1(x,y)={1,1,if z0otherwise
\quad
\quad \quad ∂ L L 2 ( x , y ) ∂ z = z \frac{\partial L_{L2}(x,y)}{\partial z} =z zLL2(x,y)=z
\quad
\quad \quad ∂ L s m o o t h L 1 ( x , y ) ∂ z = { z , if  ∣ x − y ∣ < 1 ± 1 , otherwise \frac{\partial L_{smoothL1}(x,y)}{\partial z} =\begin{cases} z, & \text{if } |x-y|<1 \\ \pm1, & \text{otherwise} \end{cases} zLsmoothL1(x,y)={z,±1,if xy<1otherwise

从损失函数对x的导数可知:

  • L 1 L1 L1 损失函数对 z z z 的导数为常数,在训练后期, z z z很小时,如果 learning rate 不变,损失函数会在稳定值附近波动,很难收敛到更高的精度。
  • L 2 L2 L2 损失函数对 z z z 的导数等于 z z z,在训练初期, z z z 值很大时,使得导数也非常大,在训练初期不稳定。
  • s m o o t h L 1 smooth_{L1} smoothL1 完美的避开了 L 1 L1 L1 L 2 L2 L2损失的缺点。

2)实际目标检测框回归任务中的损失 loss 为: L l o c ( t , v ) = ∑ i ∈ ( x , y , w , h ) s m o o t h L 1 ( t i − v i ) L_{loc(t, v)} = \sum_{i \in (x, y, w, h)}smooth_{L1}(t_i - v_i) Lloc(t,v)=i(x,y,w,h)smoothL1(tivi)
即, 分别求 x, y, w, h 的 loss,然后相加作为 Bounding Box Regression Loss

  • v = ( v x , v y , v w , v h ) v = (v_x, v_y,v_w, v_h) v=(vx,vy,vw,vh) :表示 gt_bbox 的坐标,
  • t = ( t x , t y , t w , t h ) t = (t_x, t_y, t_w, t_h) t=(tx,ty,tw,th):表示 predict_bbox 的坐标

3)缺点

上面的三种Loss用于计算目标检测的Bounding Box Loss时,独立的求出x, y, w, h 的 Loss,然后进行相加得到最终的Bounding Box Loss,这种做法的假设是 x, y, w, h 是相互独立的,实际是有一定相关性的

这就引出了以下的解决方案,使用 IoU 来计算 loss 。


2、 IoU Loss

由旷视提出,发表于2016 ACM 论文 《UnitBox: An Advanced Object Detection Network》

  • 若在回归 bbox坐标时,使用4个坐标点的loss之和,而评价模型时,使用 IoU,会导致不一致性。因为 L1或者L2 Loss相同的框,IoU 很可能不一样。 如下图所示 , 图a. L2 loss 相同,IoU不相同; 图b. L1 loss 相同,IoU不相同
  • 通过4个点回归坐标框的方式是假设4个坐标点是相互独立的,没有考虑其相关性,实际4个坐标点具有一定的相关性
  • 基于L1和L2的距离的loss对于尺度不具有不变性

目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第2张图片
2)基于此提出IoU Loss, 其将4个点构成的box看成一个整体进行回归:

目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第3张图片


3、 GIoU Loss (Generalized-IoU Loss)

由斯坦福学者提出,发表于CVPR2019

1) IoU Loss 有2个缺点:

  • 当预测框和目标框不相交时, I o U ( A , B ) = 0 IoU(A,B)=0 IoU(A,B)=0 时,不能反映 A, B 距离的远近,此时损失函数不可导,IoU Loss 无法优化两个框不相交的情况。 L o s s = − l n I o U , ∂ l o s s ∂ I o U = ( − l n I o U ) ′ = − 1 I o U Loss=-ln^{IoU}, \quad\quad \frac{\partial loss}{\partial IoU} = (-ln^{IoU})' = -\frac{1}{IoU} Loss=lnIoU,IoUloss=(lnIoU)=IoU1
  • IoU值不能反映两个框是如何相交的:即使两个框的 I o U IoU IoU 值是相同的,其相交方式也可能很不一样。

目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第4张图片

2) GIoU :Generalized-IoU Loss
目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第5张图片

最后,损失可以用下面的公式来计算: L G I o U = 1 − G I o U L_{GIoU} = 1 - GIoU LGIoU=1GIoU

\quad

3)C 的面积的求解
假设有两个任意的 bbox A和B,我们要找到一个最小的封闭形状C,让C可以将A和B包围在里面。

A = ( x m i n A , x m a x A , y m i n A , y m a x A ) A = (x_{min}^A, x_{max}^A, y_{min}^A, y_{max}^A) A=(xminA,xmaxA,yminA,ymaxA)

B = ( x m i n B , x m a x B , y m i n B , y m a x B ) B = (x_{min}^B, x_{max}^B, y_{min}^B, y_{max}^B) B=(xminB,xmaxB,yminB,ymaxB)

则, C 的坐标为:

x m i n C = m i n ( x m i n A , x m i n B ) , x m a x C = m a x ( x m a x A , x m a x B ) x_{min}^C = min(x_{min}^A, x_{min}^B), \quad x_{max}^C = max(x_{max}^A, x_{max}^B) xminC=min(xminA,xminB),xmaxC=max(xmaxA,xmaxB)

y m i n C = m i n ( y m i n A , y m i n B ) , y m a x C = m a x ( y m a x A , y m a x B ) y_{min}^C = min(y_{min}^A, y_{min}^B), \quad y_{max}^C = max(y_{max}^A, y_{max}^B) yminC=min(yminA,yminB),ymaxC=max(ymaxA,ymaxB)

C 的面积为:
A r e a C = ( x m a x C − x m i n C ) ∗ ( y m a x C − y m i n C ) Area^C = (x_{max}^C - x_{min}^C) * (y_{max}^C - y_{min}^C) AreaC=(xmaxCxminC)(ymaxCyminC)

\quad

4)GIoU 相比于 IoU 有如下性质:

  • 和原始的 loU 类似,GIoU具有尺度不变性 ( GloU 对物体的尺度大小不敏感,因为使用的是比值的原因)
  • 0 ≤ = I o U < = 1 , 0 < = C − ( A ∪ B ) C < 1 0≤= IoU <=1,0 <= \frac{C - (A \cup B)}{C} <1 0≤=IoU<=10<=CC(AB)<1 L G I o U = 1 − G I o U L_{GIoU} = 1 - GIoU LGIoU=1GIoU, 所以 − 1 < G I O U < = 1 -1 < GIOU <= 1 1<GIOU<=1
    • 当 A 和 B 完全重合时:IoU = GIoU = 1
    • 当 A,B 不重合时, I o U = 0 , G I o U IoU=0, GIoU IoU=0GIoU 趋近于 -1, 或者说 当A,B 不重合且 距离无限远时, G I o U = − 1 GIoU = -1 GIoU=1

GIoU Loss 仍然存在不足:当目标框 完全包裹 预测框的时候,IoU 和 GIoU 的值一样,此情况下 GIoU 退化为 IoU, 无法区分其相对位置关系。
目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第6张图片
基于IoU和GIoU存在的问题,有两个方向 值得思考:

  • 第一:直接最小化预测框与目标框之间的归一化距离是否可行,以达到更快的收敛速度。
  • 第二:如何使回归在与目标框有重叠甚至包含时更准确、更快。

好的目标框回归损失应该考虑三个重要的几何因素:重叠面积,中心点距离,长宽比

  • DIoU Loss:考虑了重叠面积和中心点距离,相对于GIoU Loss收敛速度更快,但没有考虑到长宽比;
  • CIoU Loss,以上三个因素都考虑到了, 其收敛的精度更高。

4、 DIoU Loss (Distance-IoU Loss)

发表在AAAI 2020

  • 通常基于 IoU-based 的 loss 可以定义为 L = 1 − I o U + R ( B , B g t ) L =1- IoU + R(B, B^{gt}) L=1IoU+R(B,Bgt),其中 R ( B , B g t ) R(B, B^{gt}) R(B,Bgt) 定义为预测框 B B B 和目标框 B g t B^{gt} Bgt 的惩罚项。
  • D I o U DIoU DIoU 中的惩罚项表示为 R D I o U = ρ 2 ( b , b g t ) c 2 R_{DIoU} = \frac{\rho ^2(b, b^{gt})}{c^2} RDIoU=c2ρ2(b,bgt),其中 b b b b g t b^{gt} bgt分别表示 B B B B g t B^{gt} Bgt 的中心点, ρ \rho ρ 表示欧式距离,C表示 B B B B g t B^{gt} Bgt 的最小外界矩形的对角线距离,如下图所示。可以将DIoU替换 IoU 用于 NMS算法当中,也即论文提出的DIoU-NMS,实验结果表明有一定的提升。
    • DloU Loss function 定义为: L D I o U = 1 − I o U + ρ 2 ( b , b g t ) c 2 L_{DIoU} = 1- IoU + \frac{\rho ^2(b, b^{gt})}{c^2} LDIoU=1IoU+c2ρ2(b,bgt)

目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第7张图片
DIoU的性质:

  • 尺度不变性
  • 当两个框完全重合时, L I o U = L G I o U = L D I o U = 0 L_{IoU} = L_{GIoU} = L_{DIoU} = 0 LIoU=LGIoU=LDIoU=0
    当两个框不相交时
  • DIoU Loss 可以直接优化 2个框直接的距离,比 GIoU Loss 收敛速度更快
  • 对于目标框包裹预测框的这种情况,DIoU Loss 可以收敛的很快,而 GIoU Loss此时退化为IoU Loss收敛速度较慢

5、 CIoU Loss (Complete-IoU Loss)

1)CIoU的惩罚项是在DIoU的惩罚项基础上加了一个影响因子 α v \alpha v αv, 这个因子把预测框长宽比拟合目标框的长宽比考虑进去。

R C I o U = ρ 2 ( b , b g t ) c 2 + α v R_{CIoU} = \frac{\rho ^2(b, b^{gt})}{c^2} +\alpha v RCIoU=c2ρ2(b,bgt)+αv, 其中:

  • α \alpha α 是用于做 trade-off 的参数, α = v ( 1 − I o U ) + v \alpha = \frac{v}{(1-IoU)+v} α=(1IoU)+vv

  • v v v是用来衡量长宽比一致性的参数, v = 4 π 2 ( a r c t a n w g t h g t − a r c t a n w h ) 2 v = \frac{4}{\pi^2}(arctan \frac{w^{gt}}{h^{gt}} - arctan \frac{w}{h})^2 v=π24(arctanhgtwgtarctanhw)2

CIoU Loss function的定义为: L D I o U = 1 − I o U + ρ 2 ( b , b g t ) c 2 + α v L_{DIoU} = 1- IoU + \frac{\rho ^2(b, b^{gt})}{c^2} +\alpha v LDIoU=1IoU+c2ρ2(b,bgt)+αv

2)DIoU和CIoU的提升效果

目标检测回归损失函数简介:SmoothL1/IoU/GIoU/DIoU/CIoU Loss_第8张图片


6、总结

(1)Smooth L1 Loss

L s m o o t h L 1 ( x , y ) = { 0.5 ( y ^ − y ) 2 , if  ∣ y ^ − y ∣ < 1 ∣ y ^ − y ∣ − 0.5 , otherwise \quad L_{smoothL1}(x,y)=\begin{cases} 0.5(\hat{y}-y)^2, & \text{if } |\hat{y}-y|<1 \\ |\hat{y}-y|-0.5, & \text{otherwise} \end{cases} LsmoothL1(x,y)={0.5(y^y)2,y^y0.5,if y^y<1otherwise

(2)loU Loss : L o s s = − l n I o U Loss=-ln^{IoU} Loss=lnIoU

(3)GloU Loss : L G I o U = 1 − I o U + C − ( A ∩ B ) ∣ C ∣ L_{GIoU} = 1 - IoU + \frac{C - (A \cap B)}{|C|} LGIoU=1IoU+CC(AB)

(4)DloU Loss: L D I o U = 1 − I o U + ρ 2 ( b , b g t ) c 2 L_{DIoU} = 1- IoU + \frac{\rho ^2(b, b^{gt})}{c^2} LDIoU=1IoU+c2ρ2(b,bgt)

(5)CIoU Loss : L D I o U = 1 − I o U + ρ 2 ( b , b g t ) c 2 + α v L_{DIoU} = 1- IoU + \frac{\rho ^2(b, b^{gt})}{c^2} +\alpha v LDIoU=1IoU+c2ρ2(b,bgt)+αv


7、代码

def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False):
    # Returns the IoU of box1 to box2. box1 is 4, box2 is nx4
    box2 = box2.t()

    # Get the coordinates of bounding boxes
    if x1y1x2y2:  # x1, y1, x2, y2 = box1
        b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]
        b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]
    else:  # transform from xywh to xyxy
        b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2
        b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2
        b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2
        b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2

    # Intersection area
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)

    # Union Area
    w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1
    w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1
    union = (w1 * h1 + 1e-16) + w2 * h2 - inter

    iou = inter / union  # iou
    if GIoU or DIoU or CIoU:
        cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # convex (smallest enclosing box) width
        ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # convex height
        if GIoU:  # Generalized IoU https://arxiv.org/pdf/1902.09630.pdf
            c_area = cw * ch + 1e-16  # convex area
            return iou - (c_area - union) / c_area  # GIoU
        if DIoU or CIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
            # convex diagonal squared
            c2 = cw ** 2 + ch ** 2 + 1e-16
            # centerpoint distance squared
            rho2 = ((b2_x1 + b2_x2) - (b1_x1 + b1_x2)) ** 2 / 4 + ((b2_y1 + b2_y2) - (b1_y1 + b1_y2)) ** 2 / 4
            if DIoU:
                return iou - rho2 / c2  # DIoU
            elif CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
                v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)
                with torch.no_grad():
                    alpha = v / (1 - iou + v)
                return iou - (rho2 / c2 + v * alpha)  # CIoU

    return iou


参考文章:
1、目标检测回归损失函数简介
2、目标检测算法之CVPR2019 GIoU Loss

你可能感兴趣的:(#,目标检测,#,损失函数,目标检测,深度学习,计算机视觉,损失函数)