class_docstr: DiceLoss normalized on each instance.
  Input:
      pred: (N, 1, H, W)
      gt: (N, 1, H, W)
      mask: (N, H, W)
  Note: This class assume that input tensors are on gpu,
      while cput computation is required to find union areas.
class_docstr_tok: ["DiceLoss","normalized","on","each","instance",".","Input",":","pred",":","(","N",",","1",",","H",",","W",")","gt",":","(","N",",","1",",","H",",","W",")","mask",":","(","N",",","H",",","W",")","Note",":","This","class","assume","that","input","tensors","are","on","gpu",",","while","cput","computation","is","required","to","find","union","areas","."]
code: def forward(self, pred, gt, mask):
      # pred_label_maps: N, P, H, W, where P is the number of regions.
      torch.cuda.synchronize()
      pred_label_maps, _ = self.label(pred > self.threshold)
      gt_label_maps, _ = self.label(gt)
  
      losses = []
      for batch_index, gt_instance_maps in enumerate(gt_label_maps):
          pred_instance_maps = pred_label_maps[batch_index]
          if gt_instance_maps is None or pred_instance_maps is None:
              continue
  
          single_loss = None  # loss on a single image in a batch
          mask_not_matched = set(range(len(pred_instance_maps)))
          for gt_instance_map in gt_instance_maps:
              instance_loss = None  # loss on a specific gt region
              for instance_index, pred_instance_map in enumerate(
                  pred_instance_maps
              ):
                  if (
                      self.iou(pred_instance_map, gt_instance_map)
                      > self.iou_thresh
                  ):
                      match_loss = self._compute(
                          pred[batch_index][0],
                          gt[batch_index][0],
                          mask[batch_index]
                          * (
                              pred_instance_map + gt_instance_map > 0
                          ).type(torch.float32),
                      )
                      instance_loss = self.replace_or_add(
                          instance_loss, match_loss
                      )
                      if instance_index in mask_not_matched:
                          mask_not_matched.remove(instance_index)
              if instance_loss is None:
                  instance_loss = self._compute(
                      pred[batch_index][0],
                      gt[batch_index][0],
                      mask[batch_index] * gt_instance_map,
                  )
              single_loss = self.replace_or_add(
                  single_loss, instance_loss
              )
  
          """Whether to compute single loss on instances which contrain no positive sample.
              if single_loss is None:
                  single_loss = self._compute(
                          pred[batch_index][0], gt[batch_index][0],
                          mask[batch_index])
              """
  
          for instance_index in mask_not_matched:
              single_loss = self.replace_or_add(
                  single_loss,
                  self._compute(
                      pred[batch_index][0],
                      gt[batch_index][0],
                      mask[batch_index]
                      * pred_instance_maps[instance_index],
                  ),
              )
  
          if single_loss is not None:
              losses.append(single_loss)
  
      if self.reduction == "none":
          loss = losses
      else:
          assert self.reduction in ["sum", "mean"]
          count = len(losses)
          loss = sum(losses)
          if self.reduction == "mean":
              loss = loss / count
      return loss
  
imports: import torch
  import torch.nn
  import numpy
  import cv2
  from scipy import ndimage
label_desc: Use image node_id 5 for calling the InstanceDiceLoss obj's underlying member method code with example usage: obj.forward(pred, gt, mask) and returns: loss