Jacobi93 / Alpha-IoU

[NeurIPS 2021] Alpha-IoU: A Family of Power Intersection over Union Losses for Bounding Box Regression
GNU General Public License v3.0
154 stars 21 forks source link

How should EIOU be combined with Alpha-IOU? #14

Closed OYsJcHar closed 2 years ago

OYsJcHar commented 2 years ago

Hi, I have applied alpha IOU to yolov5, but I also applied EIOU to the algorithm. It seems that the function in your file named "general.py" code does not contain EIOU. Would you like to know how to modify the code if you want to add it? The following is the code written by a blogger I saw on CSDN, but when I train the model, the effect is not as good as the alpha IOU or eiou provided by you. The training effect is reduced by combining these two items. I think it may be a code problem, (Maybe it is the problem of dataset that I used.) so I want to ask you how you can combine eiou and alpha IOU?

# 参考:https://mp.weixin.qq.com/s/l22GJtA7Vd11dpY9QG4k2A
def bbox_alpha_iou(box1, box2, x1y1x2y2=False, GIoU=False, DIoU=False, CIoU=False, EIoU=False, alpha=3, eps=1e-9):
    # Returns tsqrt_he IoU of box1 to box2. box1 is 4, box2 is nx4
    box2 = box2.T

    # Get the coordinates of bounding boxes
    if x1y1x2y2:  # x1, y1, x2, y2 = box1
        b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]
        b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]
    else:  # transform from xywh to xyxy
        b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2
        b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2
        b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2
        b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2

    # Intersection area
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)

    # Union Area
    w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps
    w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps
    union = w1 * h1 + w2 * h2 - inter + eps

    # change iou into pow(iou+eps) 加入α次幂
    # alpha iou
    iou = torch.pow(inter / union + eps, alpha)
    beta = 2 * alpha
    if GIoU or DIoU or CIoU or EIoU:
        # 两个框的最小闭包区域的width和height
        cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # convex (smallest enclosing box) width
        ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # convex height

        if CIoU or DIoU or EIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1
            # 最小外接矩形 对角线的长度平方
            c2 = cw ** beta + ch ** beta + eps  # convex diagonal
            rho_x = torch.abs(b2_x1 + b2_x2 - b1_x1 - b1_x2)
            rho_y = torch.abs(b2_y1 + b2_y2 - b1_y1 - b1_y2)
            # 两个框中心点之间距离的平方
            rho2 = (rho_x ** beta + rho_y ** beta) / (2 ** beta)  # center distance
            if DIoU:
                return iou - rho2 / c2  # DIoU

            elif CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47
                v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)
                with torch.no_grad():
                    alpha_ciou = v / ((1 + eps) - inter / union + v)
                # return iou - (rho2 / c2 + v * alpha_ciou)  # CIoU
                return iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha))  # CIoU

            # EIoU 在CIoU的基础上
            # 将预测框宽高的纵横比损失项 拆分成预测框的宽高分别与最小外接框宽高的差值
            # 加速了收敛提高了回归精度
            elif EIoU:
                rho_w2 = ((b2_x2 - b2_x1) - (b1_x2 - b1_x1)) ** beta
                rho_h2 = ((b2_y2 - b2_y1) - (b1_y2 - b1_y1)) ** beta
                cw2 = cw ** beta + eps
                ch2 = ch ** beta + eps
                return iou - (rho2 / c2 + rho_w2 / cw2 + rho_h2 / ch2)

            # GIoU https://arxiv.org/pdf/1902.09630.pdf
            c_area = torch.max(cw * ch + eps, union)  # convex area
            return iou - torch.pow((c_area - union) / c_area + eps, alpha)  # GIoU
    else:
        return iou  # torch.log(iou+eps) or iou

Hope to get your reply as soon as possible. Thank you so much!!!

Jacobi93 commented 2 years ago

Thx for the interest. As formulated in equ 7 in the paper of EIoU, EIoU loss = DIoU loss + aspect loss. So you should generalize it in a similar way for DIoU (or CIoU), with examples available in equ 4 in our paper. We should add the power parameter alpha for each term in the equ. Thx.

OYsJcHar commented 2 years ago

Thx for the interest. As formulated in equ 7 in the paper of EIoU, EIoU loss = DIoU loss + aspect loss. So you should generalize it in a similar way for DIoU (or CIoU), with examples available in equ 4 in our paper. We should add the power parameter alpha for each term in the equ. Thx.

Thank you very much for your quick reply! According to what you said, I read the formula in the paper again. I think the the part of EIoU in the code provided by CSDN blog above is the method you said, so it should be correct in theory. However, the effect on the dataset I use is not as good as the CIoU combined with alpha-IoU provided by your code. I think it may be the problem of the dataset I use that makes the results different. In the future, I will see the effect through training with other dataset. Thank you again for your reply!