class_docstr: This class computes the loss for SparseRCNN.
  The process happens in two steps:
      1) we compute hungarian assignment between ground truth boxes and the outputs of the model
      2) we supervise each pair of matched ground-truth / prediction (supervise class and box)
class_docstr_tok: ["This","class","computes","the","loss","for","SparseRCNN",".","The","process","happens","in","two","steps",":","1",")","we","compute","hungarian","assignment","between","ground","truth","boxes","and","the","outputs","of","the","model","2",")","we","supervise","each","pair","of","matched","ground-truth","\/","prediction","(","supervise","class","and","box",")"]
docstr: Classification loss (NLL)
  targets dicts must contain the key "labels" containing a tensor of dim [nb_target_boxes]
docstr_tok: ["Classification","loss","(","NLL",")","targets","dicts","must","contain","the","key","``","labels","''","containing","a","tensor","of","dim","[","nb_target_boxes","]"]
code: def loss_labels(self, outputs, targets, indices, num_boxes, log=True):
      """Classification loss (NLL)
      targets dicts must contain the key "labels" containing a tensor of dim [nb_target_boxes]
      """
      assert "pred_logits" in outputs
      src_logits = outputs["pred_logits"]
  
      idx = self._get_src_permutation_idx(indices)
      target_classes_o = paddle.concat(
          [
              paddle.gather(t["labels"], J, axis=0)
              for t, (_, J) in zip(targets, indices)
          ]
      )
      target_classes = paddle.full(
          src_logits.shape[:2], self.num_classes, dtype="int32"
      )
      for i, ind in enumerate(zip(idx[0], idx[1])):
          target_classes[int(ind[0]), int(ind[1])] = target_classes_o[i]
      target_classes.stop_gradient = True
  
      src_logits = src_logits.flatten(start_axis=0, stop_axis=1)
  
      # prepare one_hot target.
      target_classes = target_classes.flatten(start_axis=0, stop_axis=1)
      class_ids = paddle.arange(0, self.num_classes)
      labels = (target_classes.unsqueeze(-1) == class_ids).astype(
          "float32"
      )
      labels.stop_gradient = True
  
      # comp focal loss.
      class_loss = (
          sigmoid_focal_loss(
              src_logits,
              labels,
              alpha=self.focal_loss_alpha,
              gamma=self.focal_loss_gamma,
              reduction="sum",
          )
          / num_boxes
      )
      losses = {"loss_ce": class_loss}
  
      if log:
          label_acc = target_classes_o.unsqueeze(-1)
          src_idx = [src for (src, _) in indices]
  
          pred_list = []
          for i in range(outputs["pred_logits"].shape[0]):
              pred_list.append(
                  paddle.gather(
                      outputs["pred_logits"][i], src_idx[i], axis=0
                  )
              )
  
          pred = F.sigmoid(paddle.concat(pred_list, axis=0))
          acc = accuracy(pred, label_acc.astype("int64"))
          losses["acc"] = acc
  
      return losses
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from scipy.optimize import linear_sum_assignment
  import paddle
  import paddle.nn
  import paddle.nn.functional
  from paddle.metric import accuracy
  from ppdet.core.workspace import register
  from ppdet.modeling.losses.iou_loss import GIoULoss
label_desc: Use image node_id 2 for calling the SparseRCNNLoss obj's underlying member method code with example usage: obj.loss_labels(outputs, targets, indices, num_boxes, log) and returns: losses