如今一些目标检测算法如YOLO v3已经都在用GIOU代替IOU进行损失计算并取得不错的效果,GIOU的思路简单而有效,今天我们就来解读一下CVPR19的这篇Generalized Intersection over Union: A Metric and A Loss for Bounding Box
Regression提出的广义IoU-GIoU
目录
- 背景及介绍
- 算法流程及代码
- 实验结果
- 论文地址
背景及介绍
背景
The dominant trend for improving performance of applications utilizing deep neural networks is to propose either a better architecture backbone or a better strategy to extract reliable local features
正如作者论文中的这一句,如今许多人都专注如何设计一个更好的backbone
或者更好地提取特征来提高检测模型的性能,但是他们却忽略了可以直接用IoU/GIoU
来代替L范数损失函数
,而作者也是以此为出发点提出了GIOU——generalized IoU
- 如果在目标检测中使用
L范数
来作为度量标准,将会存在两个检测框L范数的绝对值相同而效果却大不相同的情况,而且L范数对物体的scale比较敏感,而IoU
或者GIoU
则可以比较好地度量检测框的“精准”,具体见下图(绿色框为真实物体,黑色框为检测框):
- 既然
IoU
和GIoU
效果都那么好,为什么要舍弃IoU
而选择GIoU
呢,我们先来回顾一下IoU
的定义:
,
也就是预测框与真实框的交集除以并集,那这会有什么缺点呢?
- 预测的检测框如果和真实物体的检测框没有重叠(没有交集)的话,我们从IoU的公式可以看出,IoU始终为0且无法优化,也就是如果算法一开始检测出来的框很离谱,根本没有和真实物体发生交集的话,算法无法优化。
-
对于两个IoU相同的物体,他们的对齐方式IoU并不敏感,如下图:
GIoU介绍
- 因此,作者提出了
GIoU
,假设现在有两个任意性质 A,B,我们找到一个最小的封闭形状C(最小凸集),让C可以刚好把A,B包含在内,然后我们计算C中没有覆盖A和B的面积占C总面积的比值,然后用A与B的IoU
减去这个比值,GIoU的公式定义如下:
- GIoU的性质有以下几个:
- GIoU具有作为一个度量标准的优良性质。包括非负性,同一性,对称性,以及三角不等式的性质
- 与
IoU
类似,GIoU
也可以作为一个距离,loss
可以这样来计算:。 -
GIoU
总是小于等于IoU
,IoU
的范围是,GIoU
的范围是。 - 在A,B没有很好地对齐时,会导致C的面积增大,从而使
GIoU
的值变小,而两个矩形框不重合时,也可以计算GIoU
,这样也就解决了IoU
的两个缺点。
算法流程及代码
算法流程
我们具体地来讲一下GIoU的损失计算流程,假设我们现在Bounding box和ground truth的坐标分别是,
,我们规定,:
1.我们先计算的面积:
2.然后我们计算的面积:
3.计算两个的重叠面积(先计算出重叠部分的四个坐标再算面积):
,
,
4.找到可以包含,的最小box的坐标
,
,
5.计算的面积:
6.计算IoU:
7.计算GIoU:
8.最终损失:
代码
我们再结合代码彻底理解一下GIoU的计算过程,这里的代码出自YOLO v3,这里原始boxes(x,y,w,h):
def bbox_giou(self, boxes1, boxes2):
#通过中心坐标分别加减宽高的一半计算bboxex的左上角坐标右下角坐标并拼接在一起
boxes1 = tf.concat([boxes1[..., :2] - boxes1[..., 2:] * 0.5,
boxes1[..., :2] + boxes1[..., 2:] * 0.5], axis=-1)
boxes2 = tf.concat([boxes2[..., :2] - boxes2[..., 2:] * 0.5,
boxes2[..., :2] + boxes2[..., 2:] * 0.5], axis=-1)
boxes1 = tf.concat([tf.minimum(boxes1[..., :2], boxes1[..., 2:]),
tf.maximum(boxes1[..., :2], boxes1[..., 2:])], axis=-1)
boxes2 = tf.concat([tf.minimum(boxes2[..., :2], boxes2[..., 2:]),
tf.maximum(boxes2[..., :2], boxes2[..., 2:])], axis=-1)
#分别计算两个boxes的面积
boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * (boxes1[..., 3] - boxes1[..., 1])
boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * (boxes2[..., 3] - boxes2[..., 1])
#计算交集的左上角以及右下角的坐标
left_up = tf.maximum(boxes1[..., :2], boxes2[..., :2])
right_down = tf.minimum(boxes1[..., 2:], boxes2[..., 2:])
#计算交集的宽高,如果right_down - left_up < 0,则没有交集,宽高设置为0
inter_section = tf.maximum(right_down - left_up, 0.0)
#计算交集面积
inter_area = inter_section[..., 0] * inter_section[..., 1]
#计算并集面积
union_area = boxes1_area + boxes2_area - inter_area
#计算IoU
iou = inter_area / union_area
#计算最小并集的坐标
enclose_left_up = tf.minimum(boxes1[..., :2], boxes2[..., :2])
enclose_right_down = tf.maximum(boxes1[..., 2:], boxes2[..., 2:])
#计算最小并集的宽高,如果enclose_right_down - enclose_left_up < 0,则宽高设置为0
enclose = tf.maximum(enclose_right_down - enclose_left_up, 0.0)
#计算最小并集的面积
enclose_area = enclose[..., 0] * enclose[..., 1]
#计算GIoU
giou = iou - 1.0 * (enclose_area - union_area) / enclose_area
return giou
实验结果
作者做了一系列的实验,结果是 IoU loss 可以轻微提升使用 MSE 作为 loss 的表现,而 GIoU 的提升幅度更大,这个结论在 YOLO 算法和 faster R-CNN 系列上都是成立的:
YOLO v3在 PASCAL VOC 2007上的提升
YOLO v3在COCO上的提升
Faster R-CNN在COCO上的提升
论文地址
Generalized Intersection over Union: A Metric and A Loss for Bounding Box
Regression
网友评论