Introduction to the

In the target detection task, classification and regression of detection frame are the core problems. The selection of loss function has a great influence on the performance of the model. This paper introduces the commonly used loss function IoU, GIoU, DIou and CIoU.

IoU

IoU is the most widely used detection frame loss function, and most detection algorithms use this method. IoU is also called Intersection over Union. It is the ratio of Intersection area and merging area of prediction box and real box. The calculation formula is as follows

IoU code implementation

import numpy as np def Iou(box1, box2, wh=False): if wh == False: xmin1, ymin1, xmax1, ymax1 = box1 xmin2, ymin2, xmax2, ymax2 = box2 else: Xmin1, ymin1 = int (box1 [0] - box1 [2] / 2.0), int (box1 [1] - box1 [3] / 2.0) xmax1, ymax1 = int (box1 box1 [0] + [2] / 2.0), Int (box1 box1 [1] + [3] / 2.0) xmin2, ymin2 = int (box2 [0] - box2 [2] / 2.0), int (box2 [1] - box2 [3] / 2.0) xmax2, Ymax2 = int(box2[0]+box2[2]/2.0), int(box2[1]+box2[3]/2.0) # xx1 = np.max([xmin1, xmin2]) yy1 = np.max([ymin1, ymin2]) xx2 = np.min([xmax1, xmax2]) yy2 = np.min([ymax1, Area1 = (xmax1-xmin1) * (ymax1-ymin1) Area2 = (xmax2-xmin2) * (ymax2-ymin2) # Calculate the intersection area inter_area = (np.max([0, xx2-xx1])) * (np.max([0, yy2-YY1])) # calculate iou = inter_area/(AreA1 + AreA2-inter_area + 1E-6) return iouCopy the code

Disadvantages of IoU:

If the two boxes don’t overlap, then IoU is equal to zero, there’s no gradient back, there’s no learning

GIoU

In 2019 CVPR, GIoU was proposed in the paper Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression

The meaning of the above formula: calculate the minimum closure area of the two boxes first(it also includes the area of the smallest box of the prediction box and the real box), then calculates the proportion of the region that does not belong to the two boxes in the closure region to the closure region, and finally usesIoUSubtract this specific gravity and you getGIoU.

GIoU code implementation

def Giou(rec1,rec2): X3,x4,y3,y4 = rec2 iou = iou (rec1,rec2) area_C = (max(x1,x2,x3,x4)-min(x1,x2,x3,x4))*(max(y1,y2,y3,y4)-min(y1,y2,y3,y4)) area_1 = (x2-x1)*(y1-y2) area_2 = (x4-x3)*(y3-y4) sum_area = area_1 + area_2 # Width of the first rectangle w1 = x2 - x1 # width of the second rectangle w2 = x4-x3 h1 = y1-y2 h2 = y3-y4 # H = min(y1,y2,y3,y4)+h1+h2-max(y1,y2,y3,y4) +h1+h2-max(y1,y2,y3,y4 W*H # Area of the union of two rectangles add_area = sum_area-area - Area # Percentage of the closure Area that does not belong to the two boxes end_area = (area_c-add_area)/area_C giou = iou - end_area return giouCopy the code

GIoU considers that when there is no overlap between the detection frame and the real frame, but when there is inclusion between the detection frame and the real frame, GIoU and IoU have the same effect.

DIoU

DIoU, namely distance-IOU, is calculated by the following formula

Among them,b.Respectively represent the center point of the prediction box and the real box, andStands for calculating the Euclidean distance between two central points.cRepresents the diagonal distance of the smallest closure region that can contain both the prediction box and the real box.

DIoU considering GIoU shortcomings, but also increased the minimum two box closures, forecast real boxes and boxes are included in, but instead of the box DIoU calculation between occurring simultaneously, but calculating Euclidean distance between each test box, so that it can solve the problems when GIoU contains, at the same time, DIoU minimize forecast box, the center of the distance between So fast convergence can be achieved.

DIoU code implementation

def Diou(bboxes1, bboxes2): rows = bboxes1.shape[0] cols = bboxes2.shape[0] dious = torch.zeros((rows, cols)) if rows * cols == 0:# return dious exchange = False if bboxes1.shape[0] > bboxes2.shape[0]: bboxes1, bboxes2 = bboxes2, bboxes1 dious = 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 * h1 area2 = w2 * h2 center_x1 = (bboxes1[:, 2] + bboxes1[:, 0]) / 2 center_y1 = (bboxes1[:, 3] + bboxes1[:, 1]) / 2 center_x2 = (bboxes2[:, 2] + bboxes2[:, 0]) / 2 center_y2 = (bboxes2[:, 3] + bboxes2[:, 1]) / 2 inter_max_xy = torch.min(bboxes1[:, 2:],bboxes2[:, 2:]) inter_min_xy = torch.max(bboxes1[:, :2],bboxes2[:, :2]) out_max_xy = torch.max(bboxes1[:, 2:],bboxes2[:, 2:]) out_min_xy = torch.min(bboxes1[:, :2],bboxes2[:, :2]) 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)**2 outer = torch.clamp((out_max_xy - out_min_xy), min=0) outer_diag = (outer[:, 0] ** 2) + (outer[:, 1] ** 2) union = area1+area2-inter_area dious = inter_area / union - (inter_diag) / outer_diag dious = Torch. Clamp (dious,min=-1.0, Max = 1.0) if Exchange: dious =.T returnCopy the code

CIoU

CIoU is complete-IOU, which increases the loss of length and width on the basis of DIoU, and can further accelerate convergence and improve performance.

Among them,Is the weight function, andUsed to measure the similarity of aspect ratio

And the complete CIoU loss function is positioned as

CIoUThe gradient of theta is similar to thetaDIoUBut considerThe gradient of, in the case of length and width at [0, 1], will cause a gradient explosion.

CIoU code implementation

def bbox_overlaps_ciou(bboxes1, bboxes2): rows = bboxes1.shape[0] cols = bboxes2.shape[0] cious = torch.zeros((rows, cols)) if rows * cols == 0: return cious exchange = False if bboxes1.shape[0] > bboxes2.shape[0]: bboxes1, bboxes2 = bboxes2, bboxes1 cious = torch.zeros((cols, rows)) exchange = True w1 = bboxes1[:, 2] - bboxes1[:, 0] h1 = bboxes1[:, 3] - bboxes1[:, 1] w2 = bboxes2[:, 2] - bboxes2[:, 0] h2 = bboxes2[:, 3] - bboxes2[:, 1] area1 = w1 * h1 area2 = w2 * h2 center_x1 = (bboxes1[:, 2] + bboxes1[:, 0]) / 2 center_y1 = (bboxes1[:, 3] + bboxes1[:, 1]) / 2 center_x2 = (bboxes2[:, 2] + bboxes2[:, 0]) / 2 center_y2 = (bboxes2[:, 3] + bboxes2[:, 1]) / 2 inter_max_xy = torch.min(bboxes1[:, 2:],bboxes2[:, 2:]) inter_min_xy = torch.max(bboxes1[:, :2],bboxes2[:, :2]) out_max_xy = torch.max(bboxes1[:, 2:],bboxes2[:, 2:]) out_min_xy = torch.min(bboxes1[:, :2],bboxes2[:, :2]) 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)**2 outer = torch.clamp((out_max_xy - out_min_xy), min=0) outer_diag = (outer[:, 0] ** 2) + (outer[:, 1] ** 2) union = area1+area2-inter_area u = (inter_diag) / outer_diag iou = inter_area / union with torch.no_grad(): arctan = torch.atan(w2 / h2) - torch.atan(w1 / h1) v = (4 / (math.pi ** 2)) * torch.pow((torch.atan(w2 / h2) - torch.atan(w1 / h1)), 2) S = 1 - iou alpha = v / (S + v) w_temp = 2 * w1 ar = (8 / (math.pi ** 2)) * arctan * ((w1 - w_temp) * h1) cious = iou - (u + alpha * ar) cious = torch. Clamp (cious,min=-1.0, Max = 1.0) if exchange: cious = ciousCopy the code

The resources

  • Arxiv.org/abs/1902.09…
  • Arxiv.org/pdf/1911.08…
  • Arxiv.org/abs/1911.08…
  • Github.com/Zzh-tju/DIo…