code: def detection_target_layer(
      batch_proposals,
      batch_mrcnn_class_scores,
      batch_gt_class_ids,
      batch_gt_boxes,
      batch_gt_masks,
      cf,
  ):
      """
      Subsamples proposals for mrcnn losses and generates targets. Sampling is done per batch element, seems to have positive
      effects on training, as opposed to sampling over entire batch. Negatives are sampled via stochastic-hard-example-mining
      (SHEM), where a number of negative proposals are drawn from larger pool of highest scoring proposals for stochasticity.
      Scoring is obtained here as the max over all foreground probabilities as returned by mrcnn_classifier (worked better than
      loss-based class balancing methods like "online-hard-example-mining" or "focal loss".)
  
      :param batch_proposals: (n_proposals, (y1, x1, y2, x2, (z1), (z2), batch_ixs).
      boxes as proposed by RPN. n_proposals here is determined by batch_size * POST_NMS_ROIS.
      :param batch_mrcnn_class_scores: (n_proposals, n_classes)
      :param batch_gt_class_ids: list over batch elements. Each element is a list over the corresponding roi target labels.
      :param batch_gt_boxes: list over batch elements. Each element is a list over the corresponding roi target coordinates.
      :param batch_gt_masks: list over batch elements. Each element is binary mask of shape (n_gt_rois, y, x, (z), c)
      :return: sample_indices: (n_sampled_rois) indices of sampled proposals to be used for loss functions.
      :return: target_class_ids: (n_sampled_rois)containing target class labels of sampled proposals.
      :return: target_deltas: (n_sampled_rois, 2 * dim) containing target deltas of sampled proposals for box refinement.
      :return: target_masks: (n_sampled_rois, y, x, (z)) containing target masks of sampled proposals.
      """
      # normalization of target coordinates
      if cf.dim == 2:
          h, w = cf.patch_size
          scale = (
              torch.from_numpy(np.array([h, w, h, w])).float().cuda()
          )
      else:
          h, w, z = cf.patch_size
          scale = (
              torch.from_numpy(np.array([h, w, h, w, z, z]))
              .float()
              .cuda()
          )
  
      positive_count = 0
      negative_count = 0
      sample_positive_indices = []
      sample_negative_indices = []
      sample_deltas = []
      sample_masks = []
      sample_class_ids = []
  
      # loop over batch and get positive and negative sample rois.
      for b in range(len(batch_gt_class_ids)):
          gt_class_ids = (
              torch.from_numpy(batch_gt_class_ids[b]).int().cuda()
          )
          gt_masks = torch.from_numpy(batch_gt_masks[b]).float().cuda()
          if np.any(
              batch_gt_class_ids[b] > 0
          ):  # skip roi selection for no gt images.
              gt_boxes = (
                  torch.from_numpy(batch_gt_boxes[b]).float().cuda()
                  / scale
              )
          else:
              gt_boxes = torch.FloatTensor().cuda()
  
          # get proposals and indices of current batch element.
          proposals = batch_proposals[batch_proposals[:, -1] == b][
              :, :-1
          ]
          batch_element_indices = torch.nonzero(
              batch_proposals[:, -1] == b
          ).squeeze(1)
  
          # Compute overlaps matrix [proposals, gt_boxes]
          if 0 not in gt_boxes.size():
              if gt_boxes.shape[1] == 4:
                  overlaps = mutils.bbox_overlaps_2D(
                      proposals, gt_boxes
                  )
              else:
                  overlaps = mutils.bbox_overlaps_3D(
                      proposals, gt_boxes
                  )
  
              # Determine postive and negative ROIs
              roi_iou_max = torch.max(overlaps, dim=1)[0]
              # 1. Positive ROIs are those with >= 0.5 IoU with a GT box
              positive_roi_bool = roi_iou_max >= (
                  0.5 if cf.dim == 2 else 0.3
              )
              # 2. Negative ROIs are those with < 0.1 with every GT box.
              negative_roi_bool = roi_iou_max < (
                  0.1 if cf.dim == 2 else 0.01
              )
          else:
              positive_roi_bool = torch.FloatTensor().cuda()
              negative_roi_bool = torch.from_numpy(
                  np.array([1] * proposals.shape[0])
              ).cuda()
  
          # Sample Positive ROIs
          if 0 not in torch.nonzero(positive_roi_bool).size():
              positive_indices = torch.nonzero(
                  positive_roi_bool
              ).squeeze(1)
              positive_samples = int(
                  cf.train_rois_per_image * cf.roi_positive_ratio
              )
              rand_idx = torch.randperm(positive_indices.size()[0])
              rand_idx = rand_idx[:positive_samples].cuda()
              positive_indices = positive_indices[rand_idx]
              positive_samples = positive_indices.size()[0]
              positive_rois = proposals[positive_indices, :]
              # Assign positive ROIs to GT boxes.
              positive_overlaps = overlaps[positive_indices, :]
              roi_gt_box_assignment = torch.max(
                  positive_overlaps, dim=1
              )[1]
              roi_gt_boxes = gt_boxes[roi_gt_box_assignment, :]
              roi_gt_class_ids = gt_class_ids[roi_gt_box_assignment]
  
              # Compute bbox refinement targets for positive ROIs
              deltas = mutils.box_refinement(
                  positive_rois, roi_gt_boxes
              )
              std_dev = torch.from_numpy(cf.bbox_std_dev).float().cuda()
              deltas /= std_dev
  
              # Assign positive ROIs to GT masks
              roi_masks = gt_masks[roi_gt_box_assignment, :, :]
  
              # Compute mask targets
              boxes = positive_rois
              box_ids = torch.arange(roi_masks.size()[0]).int().cuda()
  
              if len(cf.mask_shape) == 2:
                  masks = ra2D(cf.mask_shape[0], cf.mask_shape[1], 0)(
                      roi_masks.unsqueeze(1), boxes, box_ids
                  )
              else:
                  masks = ra3D(
                      cf.mask_shape[0],
                      cf.mask_shape[1],
                      cf.mask_shape[2],
                      0,
                  )(roi_masks.unsqueeze(1), boxes, box_ids)
  
              masks = masks.squeeze(1)
              # Threshold mask pixels at 0.5 to have GT masks be 0 or 1 to use with
              # binary cross entropy loss.
              masks = torch.round(masks)
  
              sample_positive_indices.append(
                  batch_element_indices[positive_indices]
              )
              sample_deltas.append(deltas)
              sample_masks.append(masks)
              sample_class_ids.append(roi_gt_class_ids)
              positive_count += positive_samples
          else:
              positive_samples = 0
  
          # Negative ROIs. Add enough to maintain positive:negative ratio, but at least 1. Sample via SHEM.
          if 0 not in torch.nonzero(negative_roi_bool).size():
              negative_indices = torch.nonzero(
                  negative_roi_bool
              ).squeeze(1)
              r = 1.0 / cf.roi_positive_ratio
              b_neg_count = np.max(
                  (int(r * positive_samples - positive_samples), 1)
              )
              roi_probs_neg = batch_mrcnn_class_scores[
                  batch_element_indices[negative_indices]
              ]
              raw_sampled_indices = mutils.shem(
                  roi_probs_neg, b_neg_count, cf.shem_poolsize
              )
              sample_negative_indices.append(
                  batch_element_indices[
                      negative_indices[raw_sampled_indices]
                  ]
              )
              negative_count += raw_sampled_indices.size()[0]
  
      if len(sample_positive_indices) > 0:
          target_deltas = torch.cat(sample_deltas)
          target_masks = torch.cat(sample_masks)
          target_class_ids = torch.cat(sample_class_ids)
  
      # Pad target information with zeros for negative ROIs.
      if positive_count > 0 and negative_count > 0:
          sample_indices = torch.cat(
              (
                  torch.cat(sample_positive_indices),
                  torch.cat(sample_negative_indices),
              ),
              dim=0,
          )
          zeros = torch.zeros(negative_count).int().cuda()
          target_class_ids = torch.cat([target_class_ids, zeros], dim=0)
          zeros = torch.zeros(negative_count, cf.dim * 2).cuda()
          target_deltas = torch.cat([target_deltas, zeros], dim=0)
          zeros = torch.zeros(negative_count, *cf.mask_shape).cuda()
          target_masks = torch.cat([target_masks, zeros], dim=0)
      elif positive_count > 0:
          sample_indices = torch.cat(sample_positive_indices)
      elif negative_count > 0:
          sample_indices = torch.cat(sample_negative_indices)
          zeros = torch.zeros(negative_count).int().cuda()
          target_class_ids = zeros
          zeros = torch.zeros(negative_count, cf.dim * 2).cuda()
          target_deltas = zeros
          zeros = torch.zeros(negative_count, *cf.mask_shape).cuda()
          target_masks = zeros
      else:
          sample_indices = torch.LongTensor().cuda()
          target_class_ids = torch.IntTensor().cuda()
          target_deltas = torch.FloatTensor().cuda()
          target_masks = torch.FloatTensor().cuda()
  
      return (
          sample_indices,
          target_class_ids,
          target_deltas,
          target_masks,
      )
  
imports: import utils.model_utils
  import utils.exp_utils
  from cuda_functions.nms_2D.pth_nms import nms_gpu
  from cuda_functions.nms_3D.pth_nms import nms_gpu
  from cuda_functions.roi_align_2D.roi_align.crop_and_resize import CropAndResizeFunction
  from cuda_functions.roi_align_3D.roi_align.crop_and_resize import CropAndResizeFunction
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  import torch.utils
label_desc: Use image node_id 8 for calling a global function with example usage: detection_target_layer(batch_proposals, batch_mrcnn_class_scores, batch_gt_class_ids, batch_gt_boxes, batch_gt_masks, cf) and returns: sample_indices,  target_class_ids,  target_deltas,  target_masks