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)
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等技术读懂了再更新