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

What is the loss weight of Faster R-CNN with alpha-iou? #13

Closed CCODING04 closed 2 years ago

CCODING04 commented 2 years ago

Hi, I have tried to train alpha-iou with the Faster R-CNN using mmdetection. And the results confused me, cuz I couldn't got the same result as you described in paper. And I guss it maybe the different of loss weight you defined. Can you share your loss weight of your alpha-iou pre-defined ? My config is as below:

_base_ = './faster_rcnn_r50_fpn_1x_coco.py'
model = dict(
    roi_head=dict(
        bbox_head=dict(
            reg_decoded_bbox=True,
            loss_bbox=dict(type='AlphaIoULoss', loss_weight=1.0)
        )
    )
)

Hope to get your reply as soon as possible :) Thanks a lot 🤖

Jacobi93 commented 2 years ago

Hi, thx for the interest. My loss weight is also 1 for alpha-iou. Please have a try again and you should be able to obtain comparable results. As we mentioned in the Appendix: We train Faster R-CNN with different losses following the original code’s training protocol at https://github.com/open-mmlab/mmdetection/tree/master/configs/faster_rcnn. The configuration is set following the file "faster_rcnn_r50_fpn.py" for Faster R-CNN with the backbone being ResNet-50-FPN. The file "schedule_1x.py" is set for models trained with 1x schedule and single scale. The checkpoint and logging configuration is set in "default_runtime.py". The batch size is 16, the initial learning rate is 0.02, and the number of training epochs is 12 in all experiments. The file "coco_detection.py" is set for models trained on MS COCO. Please check all details before training, thx.

CCODING04 commented 2 years ago

Thanks for you reply so quickly~! I have tried it many times, and tried ATSS and YOLOX as well. I thought may be something I missed in my relization ( but I change it all the same with your implementation) It's the relization of alpha-iou I wrapper your implementation in mmdetection alpha-iou loss in mmdetection models/iou_loss.py

def alphaiou_loss(pred, target, alpha=3, eps=1e-9, mode='iou'):
    # iou mode
    mode = mode.lower()
    assert mode in ('iou', 'ciou', 'giou', 'diou')

    b1_x1, b1_y1 = pred[:, 0], pred[:, 1]
    b1_x2, b1_y2 = pred[:, 2], pred[:, 3]
    b2_x1, b2_y1 = target[:, 0], target[:, 1]
    b2_x2, b2_y2 = target[:, 2], target[:, 3]

    # overlap
    overlap = (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

    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 - overlap + eps

    # change conventional iou to alpha pow
    ious = torch.pow(overlap / union + eps, alpha)

    # calculate alpha-iou according mode
    if mode == 'iou':
        loss = 1 - ious
        return loss

    # enclose area
    enclose_x1y1 = torch.min(pred[:, :2], target[:, :2])
    enclose_x2y2 = torch.max(pred[:, 2:], target[:, 2:])
    enclose_wh = (enclose_x2y2 - enclose_x1y1).clamp(min=0)

    cw = enclose_wh[:, 0]
    ch = enclose_wh[:, 1]

    if mode == 'giou':
        c_area = torch.max(cw * ch + eps, union)
        gious = ious - torch.pow((c_area - union) / c_area + eps, alpha)
        loss = 1 - gious
        return loss

    c2 = (cw**2 + ch**2)**alpha + eps

    left = ((b2_x1 + b2_x2) - (b1_x1 + b1_x2))**2 / 4
    right = ((b2_y1 + b2_y2) - (b1_y1 + b1_y2))**2 / 4
    rho2 = (left + right)**alpha

    # DIoU
    if mode == 'diou':
        dious = ious - rho2 / c2
        loss = 1 - dious
        return loss
    else:
        w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps
        w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps

        factor = 4 / math.pi**2
        v = factor * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)

        with torch.no_grad():
            alpha_ciou = (ious > 0.5).float() * v / (1 - ious + v)

        # CIoU
        cious = ious - (rho2 / c2 + torch.pow(alpha_ciou * v, alpha))
        loss = 1 - cious
        return loss

I thought it's the same as yours. And the results are as follows

{"mode": "val", "epoch": 12, "iter": 5000, "lr": 0.00015, "bbox_mAP": 0.352, "bbox_mAP_50": 0.575, "bbox_mAP_75": 0.374, "bbox_mAP_s": 0.208, "bbox_mAP_m": 0.392, "bbox_mAP_l": 0.451, "bbox_mAP_copypaste": "0.352 0.575 0.374 0.208 0.392 0.451"}

I trained it with batch_size is 16 and using 0.02 as initial learning rate, with 12 epochs and got bad results.

Sry to bother you, I'all check the code again. But I have tried it a month and tested many versions in my mmdetection repo , but couldn't expected result . Can't figure out what's wrong with my implementation.

Jacobi93 commented 2 years ago

I guess one possible answer is because of different versions of codes or models, but I am not sure. The reason is that your result is even lower than reproduced baselines. Thx.

CCODING04 commented 2 years ago

I guess one possible answer is because of different versions of codes or models, but I am not sure. The reason is that your result is even lower than reproduced baselines. Thx.

That's confused me a long time to figure out what's wrong with the implementation. I do many ablation exps and when I set loss weight to 10.0, it's turly the sanme result as baseline. Oh my laydygaga, I'm insane. I truly believe the result your paper presented, so I was insane. Thank for your reply and I will downgrade mmdet and test it.