in criterion.py [0:0]
def forward(self, outputs, targets):
batchsize = outputs["sem_cls_prob"].shape[0]
nqueries = outputs["sem_cls_prob"].shape[1]
ngt = targets["gt_box_sem_cls_label"].shape[1]
nactual_gt = targets["nactual_gt"]
# classification cost: batch x nqueries x ngt matrix
pred_cls_prob = outputs["sem_cls_prob"]
gt_box_sem_cls_labels = (
targets["gt_box_sem_cls_label"]
.unsqueeze(1)
.expand(batchsize, nqueries, ngt)
)
class_mat = -torch.gather(pred_cls_prob, 2, gt_box_sem_cls_labels)
# objectness cost: batch x nqueries x 1
objectness_mat = -outputs["objectness_prob"].unsqueeze(-1)
# center cost: batch x nqueries x ngt
center_mat = outputs["center_dist"].detach()
# giou cost: batch x nqueries x ngt
giou_mat = -outputs["gious"].detach()
final_cost = (
self.cost_class * class_mat
+ self.cost_objectness * objectness_mat
+ self.cost_center * center_mat
+ self.cost_giou * giou_mat
)
final_cost = final_cost.detach().cpu().numpy()
assignments = []
# auxiliary variables useful for batched loss computation
batch_size, nprop = final_cost.shape[0], final_cost.shape[1]
per_prop_gt_inds = torch.zeros(
[batch_size, nprop], dtype=torch.int64, device=pred_cls_prob.device
)
proposal_matched_mask = torch.zeros(
[batch_size, nprop], dtype=torch.float32, device=pred_cls_prob.device
)
for b in range(batchsize):
assign = []
if nactual_gt[b] > 0:
assign = linear_sum_assignment(final_cost[b, :, : nactual_gt[b]])
assign = [
torch.from_numpy(x).long().to(device=pred_cls_prob.device)
for x in assign
]
per_prop_gt_inds[b, assign[0]] = assign[1]
proposal_matched_mask[b, assign[0]] = 1
assignments.append(assign)
return {
"assignments": assignments,
"per_prop_gt_inds": per_prop_gt_inds,
"proposal_matched_mask": proposal_matched_mask,
}