class_docstr: This class computes an assignment between the targets and the predictions of the network
  
  For efficiency reasons, the targets don't include the no_object. Because of this, in general,
  there are more predictions than targets. In this case, we do a 1-to-1 matching of the best predictions,
  while the others are un-matched (and thus treated as non-objects).
class_docstr_tok: ["This","class","computes","an","assignment","between","the","targets","and","the","predictions","of","the","network","For","efficiency","reasons",",","the","targets","do","n't","include","the","no_object",".","Because","of","this",",","in","general",",","there","are","more","predictions","than","targets",".","In","this","case",",","we","do","a","1-to-1","matching","of","the","best","predictions",",","while","the","others","are","un-matched","(","and","thus","treated","as","non-objects",")","."]
docstr: More memory-friendly matching
docstr_tok: ["More","memory-friendly","matching"]
code: def memory_efficient_forward(self, sample_dict, net_out_dict):
      """More memory-friendly matching"""
      bs, num_queries = net_out_dict["logits"].shape[:2]
  
      indices = []
  
      # Iterate through batch size
      for b in range(bs):
          out_prob = F.softmax(
              net_out_dict["logits"][b], axis=-1
          )  # [num_queries, num_classes]
          tgt_ids = sample_dict["gt_ids"][b]
  
          # Compute the classification cost. Contrary to the loss, we don't use the NLL,
          # but approximate it in 1 - proba[target class].
          # The 1 is a constant that doesn't change the matching, it can be ommitted.
          cost_class = -paddle.index_select(out_prob, tgt_ids, axis=1)
  
          out_mask = net_out_dict["masks"][
              b
          ]  # [num_queries, H_pred, W_pred]
          # GT masks are already padded when preparing target
          tgt_mask = sample_dict["gt_masks"][b]
  
          out_mask = out_mask[:, None]
          tgt_mask = tgt_mask[:, None]
          # All masks share the same set of points for efficient matching!
          point_coords = paddle.rand((1, self.num_points, 2))
          # Get GT labels
          tgt_mask = point_sample(
              tgt_mask,
              paddle.tile(point_coords, (tgt_mask.shape[0], 1, 1)),
              align_corners=False,
          ).squeeze(1)
          out_mask = point_sample(
              out_mask,
              paddle.tile(point_coords, (out_mask.shape[0], 1, 1)),
              align_corners=False,
          ).squeeze(1)
  
          # Disable mixed-precision
          with paddle.amp.auto_cast(enable=False):
              out_mask = out_mask.astype("float32")
              tgt_mask = tgt_mask.astype("float32")
  
              # Compute the focal loss between masks
              cost_mask = batch_sigmoid_ce_loss(out_mask, tgt_mask)
  
              # Compute the dice loss betwen masks
              cost_dice = batch_dice_loss(out_mask, tgt_mask)
  
          # Final cost matrix
          C = (
              self.cost_mask * cost_mask
              + self.cost_class * cost_class
              + self.cost_dice * cost_dice
          )
          # Reshape and convert to numpy array
          C = C.reshape((num_queries, -1)).numpy()
  
          indices.append(linear_sum_assignment(C))
  
      return [
          (
              paddle.to_tensor(i, dtype="int64"),
              paddle.to_tensor(j, dtype="int64"),
          )
          for i, j in indices
      ]
  
imports: import paddle
  import paddle.nn
  import paddle.nn.functional
  from scipy.optimize import linear_sum_assignment
  from paddlepanseg.cvlibs import manager, build_info_dict
  from paddlepanseg.core.runner import PanSegRunner
label_desc: Use image node_id 2 for calling the HungarianMatcher obj's underlying member method code with example usage: obj.memory_efficient_forward(sample_dict, net_out_dict) and returns: unknown