open-mmlab / mmdetection

OpenMMLab Detection Toolbox and Benchmark
https://mmdetection.readthedocs.io
Apache License 2.0
29.55k stars 9.46k forks source link

Using the same pred and target boxes, but the reason of the EIoU loss isn't 0 #11647

Open xingchenshanyao opened 6 months ago

xingchenshanyao commented 6 months ago

Here is my test code:

def fcos_iou_loss(pred, target, eps=1e-6, alpha=1,gamma=0.5,loss_type='iou',smooth_point=0.1):
    pred_left, pred_top, pred_right, pred_bottom = pred.chunk(4, -1)
    target_left, target_top, target_right, target_bottom = target.chunk(4, -1)

    target_area = (target_left + target_right + 1) * (target_top + target_bottom + 1) # 1
    pred_area = (pred_left + pred_right + 1) * (pred_top + pred_bottom + 1) # 1

    w_inter = torch.min(pred_left, target_left) + torch.min(pred_right, target_right) + 1 # 1
    g_w_inter = torch.max(pred_left, target_left) + torch.max(pred_right, target_right) + 1 # 1

    h_inter = torch.min(pred_bottom, target_bottom) + torch.min(pred_top, target_top) + 1 # 1
    g_h_inter = torch.max(pred_bottom, target_bottom) + torch.max(pred_top, target_top) + 1 # 1``

    ac_uion = g_w_inter * g_h_inter + eps # 1
    area_inter = w_inter * h_inter # 1
    area_union = target_area + pred_area - area_inter # 1
    ious = area_inter / area_union # 1

    gious = ious - (ac_uion - area_union) / ac_uion # 1

    iou1 = -ious.log() # iou # 0

    linear_iou = 1 - ious # linear_iou # 0

    giou = 1 - gious # giou # 9.5e-7

    #! eiou code

    px1, py1, px2, py2 = pred_left, pred_top, pred_right, pred_bottom
    tx1, ty1, tx2, ty2 = target_left, target_top, target_right, target_bottom

    # extent top left
    ex1 = torch.min(px1, tx1)
    ey1 = torch.min(py1, ty1)

    # intersection coordinates
    ix1 = torch.max(px1, tx1)
    iy1 = torch.max(py1, ty1)
    ix2 = torch.min(px2, tx2)
    iy2 = torch.min(py2, ty2)

    # extra
    xmin = torch.min(ix1, ix2)
    ymin = torch.min(iy1, iy2)
    xmax = torch.max(ix1, ix2)
    ymax = torch.max(iy1, iy2)

    # Intersection
    intersection = (ix2 - ex1) * (iy2 - ey1) + (xmin - ex1) * (ymin - ey1) - (
        ix1 - ex1) * (ymax - ey1) - (xmax - ex1) * (
            iy1 - ey1) # 0
    # Union
    union = (px2 - px1) * (py2 - py1) + (tx2 - tx1) * (
        ty2 - ty1) - intersection + eps # 1e-6
    # IoU
    ious1 = 1 - (intersection / union) # 0

    # Smooth-EIoU
    smooth_sign = (ious1 < smooth_point).detach().float() # 0

    eiou = 0.5 * smooth_sign * (ious**2) / smooth_point + (1 - smooth_sign) * (
        ious - 0.5 * smooth_point) # 0.95

    print("\n")
    print("iou =",iou1)
    print("linear_iou =",linear_iou)
    print("giou =",giou)
    print("eiou =",eiou)

pred = torch.tensor([
                    [50, 50, 100, 100],
                    [250, 250, 300, 300],
                    [0, 0, 100, 100],
                    [0, 0, 100, 100]], device='cuda:0'))

target = torch.tensor([
                        [50, 50, 100, 100],
                        [0, 0, 50, 50],
                        [50, 50, 150, 150],
                        [50, 50, 200, 200]], device='cuda:0')

fcos_iou_loss(pred, target)

The result is:

iou = tensor([[-0.0000],
        [4.7598],
        [1.3764],
        [1.8207]], device='cuda:0')
linear_iou = tensor([[0.0000],
        [0.9914],
        [0.7475],
        [0.8381]], device='cuda:0')
giou = tensor([[0.0000],
        [0.9914],
        [0.7475],
        [0.8381]], device='cuda:0')
eiou = tensor([[ 5.0000],
        [-0.0414],
        [ 0.2025],
        [ 0.1119]], device='cuda:0')
xingchenshanyao commented 6 months ago

Input: pred = target = [50, 50, 100, 100] Output: iou = linear_iou = giou = 0, but eiou = 5 ? Appreciate it if you could get back to me.