yolox|YoloX算法学习(1)

SimOTA
① 通过anchor中心在GT内部以及GT中心点周围2.5个像素范围内的anchor,首先粗筛确定一批候选框
② 对这批候选框执行SimOTA 分配策略,为每个GT动态分配dynamic个候选框 ,M个GT,N个候选框,类似一个MxN的矩阵,矩阵内部元素是对应位置下的Iou_loss 以及cls_loss
步骤
1、计算预测框与目标框之间的Iou_loss

pair_wise_ious = bboxes_iou(gt_bboxes_per_image, bboxes_preds_per_image, False)gt_cls_per_image = ( F.one_hot(gt_classes.to(torch.int64), self.num_classes) .float() .unsqueeze(1) .repeat(1, num_in_boxes_anchor, 1) ) pair_wise_ious_loss = -torch.log(pair_wise_ious + 1e-8)

2 、类别与前背景损失
cls_preds_ = ( cls_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() * obj_preds_.unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() ) pair_wise_cls_loss = F.binary_cross_entropy( cls_preds_.sqrt_(), gt_cls_per_image, reduction="none" ).sum(-1)

3 、cost计算
cost = ( pair_wise_cls_loss + 3.0 * pair_wise_ious_loss + 100000.0 * (~is_in_boxes_and_center) )

其中100000.0*(~is_in_boxes_and_center )指 正样本取反,剩下的都是负样本,一方面需要最小和正样本的损失,同时意味着需要最大化负样本的损失。
4、simota动态分配候选框
( num_fg, gt_matched_classes, pred_ious_this_matching, matched_gt_inds, ) = self.dynamic_k_matching(cost, pair_wise_ious, gt_classes, num_gt, fg_mask)

这里又分了好几步
one、 初始化一个与cost矩阵一样的匹配矩阵(matching_matrix)
matching_matrix = torch.zeros_like(cost)

【yolox|YoloX算法学习(1)】two、 得到iou矩阵,设定10个候选框,从iou_in_boxes_matrix矩阵中找到最大iou的前n_candidate_k取出来,求和作为每个GT需要分配的候选框个数
ious_in_boxes_matrix = pair_wise_ious n_candidate_k = min(10, ious_in_boxes_matrix.size(1)) topk_ious, _ = torch.topk(ious_in_boxes_matrix, n_candidate_k, dim=1) dynamic_ks = torch.clamp(topk_ious.sum(1).int(), min=1)

three 、在matching_matrix矩阵的指定位置设置为1,表明该位置是对应GT的一个候选框
遍历GT,每个GT动态分配
在指定GT的矩阵中基于dynamic_ks中指定索引位置所计算出的候选框数记为xi,找到前xi个最小的位置,将该位置设置为1
for gt_idx in range(num_gt): _, pos_idx = torch.topk( cost[gt_idx], k=dynamic_ks[gt_idx].item(), largest=False ) matching_matrix[gt_idx][pos_idx] = 1.0

four 、存在多个候选框关联同一个GT的情况,进行判断筛选
anchor_matching_gt求和,(最好的情况是1,若出现大于1的情况,证明上述情况发生)
找到这个大于1的gt的位置,判断在cost矩阵中这个位置对应的loss值哪个更小,记录最小的位置,首先将这个大于1的这一列置零,后将最小位置至1,确定这个候选框跟哪个GT相连
anchor_matching_gt = matching_matrix.sum(0) if (anchor_matching_gt > 1).sum() > 0: _, cost_argmin = torch.min(cost[:, anchor_matching_gt > 1], dim=0) matching_matrix[:, anchor_matching_gt > 1] *= 0.0 matching_matrix[cost_argmin, anchor_matching_gt > 1] = 1.0 fg_mask_inboxes = matching_matrix.sum(0) > 0.0 num_fg = fg_mask_inboxes.sum().item()

之后是损失的计算
mosaic和mixup等技术读懂了再更新

    推荐阅读