如今一些目標(biāo)檢測(cè)算法如YOLO v3已經(jīng)都在用GIOU代替IOU進(jìn)行損失計(jì)算并取得不錯(cuò)的效果,GIOU的思路簡(jiǎn)單而有效,今天我們就來解讀一下CVPR19的這篇Generalized Intersection over Union: A Metric and A Loss for Bounding Box
Regression提出的廣義IoU-GIoU
目錄
- 背景及介紹
- 算法流程及代碼
- 實(shí)驗(yàn)結(jié)果
- 論文地址
背景及介紹
背景
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
正如作者論文中的這一句,如今許多人都專注如何設(shè)計(jì)一個(gè)更好的backbone或者更好地提取特征來提高檢測(cè)模型的性能,但是他們卻忽略了可以直接用IoU/GIoU來代替L范數(shù)損失函數(shù),而作者也是以此為出發(fā)點(diǎn)提出了GIOU——generalized IoU
- 如果在目標(biāo)檢測(cè)中使用
L范數(shù)來作為度量標(biāo)準(zhǔn),將會(huì)存在兩個(gè)檢測(cè)框L范數(shù)的絕對(duì)值相同而效果卻大不相同的情況,而且L范數(shù)對(duì)物體的scale比較敏感,而IoU或者GIoU則可以比較好地度量檢測(cè)框的“精準(zhǔn)”,具體見下圖(綠色框?yàn)檎鎸?shí)物體,黑色框?yàn)闄z測(cè)框):
- 既然
IoU和GIoU效果都那么好,為什么要舍棄IoU而選擇GIoU呢,我們先來回顧一下IoU的定義:
,
也就是預(yù)測(cè)框與真實(shí)框的交集除以并集,那這會(huì)有什么缺點(diǎn)呢?
- 預(yù)測(cè)的檢測(cè)框如果和真實(shí)物體的檢測(cè)框沒有重疊(沒有交集)的話,我們從IoU的公式可以看出,IoU始終為0且無法優(yōu)化,也就是如果算法一開始檢測(cè)出來的框很離譜,根本沒有和真實(shí)物體發(fā)生交集的話,算法無法優(yōu)化。
-
對(duì)于兩個(gè)IoU相同的物體,他們的對(duì)齊方式IoU并不敏感,如下圖:
GIoU介紹
- 因此,作者提出了
GIoU,假設(shè)現(xiàn)在有兩個(gè)任意性質(zhì) A,B,我們找到一個(gè)最小的封閉形狀C(最小凸集),讓C可以剛好把A,B包含在內(nèi),然后我們計(jì)算C中沒有覆蓋A和B的面積占C總面積的比值,然后用A與B的IoU減去這個(gè)比值,GIoU的公式定義如下:
- GIoU的性質(zhì)有以下幾個(gè):
- GIoU具有作為一個(gè)度量標(biāo)準(zhǔn)的優(yōu)良性質(zhì)。包括非負(fù)性,同一性,對(duì)稱性,以及三角不等式的性質(zhì)
- 與
IoU類似,GIoU也可以作為一個(gè)距離,loss可以這樣來計(jì)算:。
-
GIoU總是小于等于IoU,IoU的范圍是,
GIoU的范圍是。
- 在A,B沒有很好地對(duì)齊時(shí),會(huì)導(dǎo)致C的面積增大,從而使
GIoU的值變小,而兩個(gè)矩形框不重合時(shí),也可以計(jì)算GIoU,這樣也就解決了IoU的兩個(gè)缺點(diǎn)。
算法流程及代碼
算法流程

我們具體地來講一下GIoU的損失計(jì)算流程,假設(shè)我們現(xiàn)在Bounding box和ground truth的坐標(biāo)分別是,
,我們規(guī)定,:
1.我們先計(jì)算的面積:
2.然后我們計(jì)算的面積:
3.計(jì)算兩個(gè)的重疊面積(先計(jì)算出重疊部分的四個(gè)坐標(biāo)再算面積):
,
,
4.找到可以包含,的最小box的坐標(biāo)
,
,
5.計(jì)算的面積:
6.計(jì)算IoU:
7.計(jì)算GIoU:
8.最終損失:
代碼
我們?cè)俳Y(jié)合代碼徹底理解一下GIoU的計(jì)算過程,這里的代碼出自YOLO v3,這里原始boxes(x,y,w,h):
def bbox_giou(self, boxes1, boxes2):
#通過中心坐標(biāo)分別加減寬高的一半計(jì)算bboxex的左上角坐標(biāo)右下角坐標(biāo)并拼接在一起
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)
#分別計(jì)算兩個(gè)boxes的面積
boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * (boxes1[..., 3] - boxes1[..., 1])
boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * (boxes2[..., 3] - boxes2[..., 1])
#計(jì)算交集的左上角以及右下角的坐標(biāo)
left_up = tf.maximum(boxes1[..., :2], boxes2[..., :2])
right_down = tf.minimum(boxes1[..., 2:], boxes2[..., 2:])
#計(jì)算交集的寬高,如果right_down - left_up < 0,則沒有交集,寬高設(shè)置為0
inter_section = tf.maximum(right_down - left_up, 0.0)
#計(jì)算交集面積
inter_area = inter_section[..., 0] * inter_section[..., 1]
#計(jì)算并集面積
union_area = boxes1_area + boxes2_area - inter_area
#計(jì)算IoU
iou = inter_area / union_area
#計(jì)算最小并集的坐標(biāo)
enclose_left_up = tf.minimum(boxes1[..., :2], boxes2[..., :2])
enclose_right_down = tf.maximum(boxes1[..., 2:], boxes2[..., 2:])
#計(jì)算最小并集的寬高,如果enclose_right_down - enclose_left_up < 0,則寬高設(shè)置為0
enclose = tf.maximum(enclose_right_down - enclose_left_up, 0.0)
#計(jì)算最小并集的面積
enclose_area = enclose[..., 0] * enclose[..., 1]
#計(jì)算GIoU
giou = iou - 1.0 * (enclose_area - union_area) / enclose_area
return giou
實(shí)驗(yàn)結(jié)果
作者做了一系列的實(shí)驗(yàn),結(jié)果是 IoU loss 可以輕微提升使用 MSE 作為 loss 的表現(xiàn),而 GIoU 的提升幅度更大,這個(gè)結(jié)論在 YOLO 算法和 faster R-CNN 系列上都是成立的:



論文地址
Generalized Intersection over Union: A Metric and A Loss for Bounding Box
Regression

