问题:yolox里计算gt框的和预测框的iou值,其中使用torch.prod算框交集会出现inf,导致simota的结果会出现nan值。

在尝试做simota的标签分配时,发现会出现nan值,仔细对head部分的代码跟踪,发现出现在计算iou的函数里,以下是发现的过程。

下图是sim-ota分配出的正样本点。

首先,自己选取一张图片,用cv2去读取,并根据图片名字,拿coco的api去查找对应的注释(做循环,找到该图片id,在get注释,拿到标签框gt)。

然后,加载训练好的权重,以及初始化模型,就可以model.train().  然后我们在对应的head里就可以做可视化了。取消掉如下代码的注释,就可以画出上图。

    import cv2
        import random
        import numpy as np
        img = (imgs[batch_idx].cpu().numpy().transpose(1,2,0))   #我们的批是1,B=1
        img = img.astype(np.uint8)
        img = np.clip(img.copy(),0,255)
        coords = np.stack([(x_shifts*expanded_strides)[0][fg_mask].cpu().numpy(),(y_shifts*expanded_strides)[0][fg_mask].cpu().numpy()], 1)
        coords[:,0] = (x_shifts*expanded_strides+0.5*expanded_strides)[0][fg_mask].cpu().numpy()
        coords[:,1] = (y_shifts*expanded_strides+0.5*expanded_strides)[0][fg_mask].cpu().numpy()
        for coord in coords:
            cv2.circle(img, (int(coord[0]), int(coord[1])), 3, (255,0,0), -1)
        for bbox in gt_bboxes_per_image:
            cv2.rectangle(img, (int(bbox[0]-bbox[2]/2),int(bbox[1]-bbox[3]/2)),(int(bbox[0]+bbox[2]/2),int(bbox[1]+bbox[3]/2)),  (0,255,0),2)
        cv2.imwrite('/data/debug_vis/'+str(random.randint(0,1000))+'.png', img[:,:,::-1])

但我们可以打印相关变量,得到如下信息:

最后的那一串张量就是所有尺度point拉直后,每个点是否被分配为正样本的bool值。大部分都不是,只有36个值应该为True。但是我们查看标签分配get_assignment的返回值:

会发现其中有nan。然后我们进一步去查看,发现nan最开始出现在计算预测框和GT框的iou的函数中,该函数为bboxes_iou:

def bboxes_iou(bboxes_a, bboxes_b, xyxy=True):   # 批量计算GT框们和预测框们的IOU,最后得到一个矩阵,代表每一个gt和每一个预测的IOU
    if bboxes_a.shape[1] != 4 or bboxes_b.shape[1] != 4:
        raise IndexError

    if xyxy:
        tl = torch.max(bboxes_a[:, None, :2], bboxes_b[:, :2])
        br = torch.min(bboxes_a[:, None, 2:], bboxes_b[:, 2:])
        area_a = torch.prod(bboxes_a[:, 2:] - bboxes_a[:, :2], 1)
        area_b = torch.prod(bboxes_b[:, 2:] - bboxes_b[:, :2], 1)
    else:
        tl = torch.max(
            (bboxes_a[:, None, :2] - bboxes_a[:, None, 2:] / 2),
            (bboxes_b[:, :2] - bboxes_b[:, 2:] / 2),
        )
        br = torch.min(
            (bboxes_a[:, None, :2] + bboxes_a[:, None, 2:] / 2),
            (bboxes_b[:, :2] + bboxes_b[:, 2:] / 2),
        )

        area_a = torch.prod(bboxes_a[:, 2:], 1)
        area_b = torch.prod(bboxes_b[:, 2:], 1)
    en = (tl < br).type(tl.type()).prod(dim=2)
    area_i = torch.prod(br - tl, 2) * en  # * ((tl < br).all())
    return area_i / (area_a[:, None] + area_b - area_i)

进一步查看,我们发现,在计算交集的area_i=torch.prod() 这行,会第一次出现inf,导致后面的计算出现nan。如下:   

    print(torch.prod(br - tl, 2))

但查看该br-tl的值,我们发现仅仅只是一个40*8的数,为什么会出现inf?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值