GIOU loss+DIOU loss+CIOU loss
一.IOU?
1.GIOU解決沒有交集的框,IOU為0,其損失函數導數為0,無法優化的問題。
圖1?GIOU,IOU,l2范數差異
a)可看出 l2值一樣,IOU值是不一樣的,說明L1,L2這些Loss用于回歸任務時,不能等價于最后用于評測檢測的IoU.
b)可看出當框有包含關系,GIOU就退化為IOU
其是找到一個最小的封閉形狀C,讓C可以將A和B包圍在里面,然后我們計算C中沒有覆蓋A和B的面積占C總面積的比例S.
GIOU = IOU?- S
可看出,GIOU<=IOU
當A==B,GIOU=1,當A B兩框離得很遠,GIOU趨近于-1.
圖2 GIOU 計算公式
GIOU loss:
?
GIOU的損失函數算法:
1.代碼?
import numpy as np def Giou(box1, box2):xmin1, ymin1, xmax1, ymax1 = box1xmin2, ymin2, xmax2, ymax2 = box2xx1 = np.max([xmin1, xmin2])yy1 = np.max([ymin1, ymin2])xx2 = np.min([xmax1, xmax2])yy2 = np.min([ymax1, ymax2])# 計算兩個矩形框面積area1 = (xmax1-xmin1) * (ymax1-ymin1)area2 = (xmax2-xmin2) * (ymax2-ymin2)inter_area = (np.max([0, xx2-xx1])) * (np.max([0, yy2-yy1]))#計算交集面積iou = inter_area / (area1+area2-inter_area+1e-6)#計算交并比print('===inter_area:', inter_area)print('===iou:', iou)#兩個框的包圍面積area_C = (max(xmin1, xmax1, xmin2, xmax2) - min(xmin1, xmax1, xmin2, xmax2)) *\(max(ymin1, ymax1, ymin2, ymax2) - min(ymin1, ymax1, ymin2, ymax2))print('==area_C:', area_C)end_area = (area_C - (area1+area2-inter_area)) / area_C #閉包區域中不屬于兩個框的區域占閉包區域的比重giou = iou - end_areaprint('===giou:', giou)return gioubox1 = [0, 0, 2, 2] box2 = [1, 1, 3, 3] # box2 = [5, 5, 7, 7] Giou(box1, box2)優點:
相比于IOU,優化無IOU情況。
相比于L1,L2loss,更能直觀表示框與框之間關系。
二.DIOU
基于IoU和GIoU存在的問題:
1. 直接最小化anchor框與目標框之間的歸一化距離是否可行,以達到更快的收斂速度?
2. 如何使回歸在與目標框有重疊甚至包含時更準確、更快?
3.當目標框完全包裹預測框的時候,IoU和GIoU的值都一樣,此時GIoU退化為IoU, 無法區分其相對位置關系.
其中,b,bgt分別代表了預測框和真實框的中心點,p2代表計算兩個中心點間的歐式距離。 c2代表的是能夠同時包含預測框和真實框的最小閉包區域的對角線距離。
DIoU loss可以直接最小化兩個目標框的距離,因此比GIoU loss收斂快得多。
1.DIOU代碼
import torch def Diou(bboxes1, bboxes2):rows = bboxes1.shape[0]cols = bboxes2.shape[0]dious = torch.zeros((rows, cols))if rows * cols == 0:#return diousexchange = Falseif bboxes1.shape[0] > bboxes2.shape[0]:bboxes1, bboxes2 = bboxes2, bboxes1dious = torch.zeros((cols, rows))exchange = True# #xmin,ymin,xmax,ymax->[:,0],[:,1],[:,2],[:,3]w1 = bboxes1[:, 2] - bboxes1[:, 0]h1 = bboxes1[:, 3] - bboxes1[:, 1]w2 = bboxes2[:, 2] - bboxes2[:, 0]h2 = bboxes2[:, 3] - bboxes2[:, 1]area1 = w1 * h1area2 = w2 * h2center_x1 = (bboxes1[:, 2] + bboxes1[:, 0]) / 2center_y1 = (bboxes1[:, 3] + bboxes1[:, 1]) / 2center_x2 = (bboxes2[:, 2] + bboxes2[:, 0]) / 2center_y2 = (bboxes2[:, 3] + bboxes2[:, 1]) / 2inter_max_xy = torch.min(bboxes1[:, 2:], bboxes2[:, 2:])inter_min_xy = torch.max(bboxes1[:, :2], bboxes2[:, :2])print('==inter_min_xy:', inter_min_xy)print('==inter_max_xy:', inter_max_xy)out_max_xy = torch.max(bboxes1[:, 2:], bboxes2[:, 2:])out_min_xy = torch.min(bboxes1[:, :2], bboxes2[:, :2])print('==out_min_xy:', out_min_xy)print('==out_max_xy:', out_max_xy)inter = torch.clamp((inter_max_xy - inter_min_xy), min=0)inter_area = inter[:, 0] * inter[:, 1]inter_diag = (center_x2 - center_x1)**2 + (center_y2 - center_y1)**2outer = torch.clamp((out_max_xy - out_min_xy), min=0)outer_diag = (outer[:, 0] ** 2) + (outer[:, 1] ** 2)union = area1+area2-inter_areadious = inter_area / union - (inter_diag) / outer_diagdious = torch.clamp(dious,min=-1.0, max = 1.0)if exchange:dious = dious.Treturn diousbox1 = torch.from_numpy(np.array([[0, 0, 2, 2]])) box2 = torch.from_numpy(np.array([[1, 1, 3, 3]])) Diou(box1, box2)DIOUloss:
優點:
相比于GIOU,優化距離替換優化面積,收斂速度更快。
解決GIOU的缺點:完全包裹預測框時loss一樣的情況。
三.CIOU
DIOU沒有考慮到檢測框的長寬比。長寬比更接近的邊框應當有更低的loss。
?
參考:
https://github.com/Zzh-tju/DIoU-darknet
https://arxiv.org/abs/1911.08287
總結
以上是生活随笔為你收集整理的GIOU loss+DIOU loss+CIOU loss的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PyTorch框架学习十八——Layer
- 下一篇: python(c++)刷题+剑指offe