docstr: :param img: input images (b, c, y, x, (z)).
  :return: rpn_pred_logits: (b, n_anchors, 2)
  :return: rpn_pred_deltas: (b, n_anchors, (y, x, (z), log(h), log(w), (log(d))))
  :return: batch_proposal_boxes: (b, n_proposals, (y1, x1, y2, x2, (z1), (z2), batch_ix)) only for monitoring/plotting.
  :return: detections: (n_final_detections, (y1, x1, y2, x2, (z1), (z2), batch_ix, pred_class_id, pred_score)
  :return: detection_masks: (n_final_detections, n_classes, y, x, (z)) raw molded masks as returned by mask-head.
docstr_tok: [":","param","img",":","input","images","(","b",",","c",",","y",",","x",",","(","z",")",")",".",":","return",":","rpn_pred_logits",":","(","b",",","n_anchors",",","2",")",":","return",":","rpn_pred_deltas",":","(","b",",","n_anchors",",","(","y",",","x",",","(","z",")",",","log","(","h",")",",","log","(","w",")",",","(","log","(","d",")",")",")",")",":","return",":","batch_proposal_boxes",":","(","b",",","n_proposals",",","(","y1",",","x1",",","y2",",","x2",",","(","z1",")",",","(","z2",")",",","batch_ix",")",")","only","for","monitoring\/plotting",".",":","return",":","detections",":","(","n_final_detections",",","(","y1",",","x1",",","y2",",","x2",",","(","z1",")",",","(","z2",")",",","batch_ix",",","pred_class_id",",","pred_score",")",":","return",":","detection_masks",":","(","n_final_detections",",","n_classes",",","y",",","x",",","(","z",")",")","raw","molded","masks","as","returned","by","mask-head","."]
code: def forward(self, img, is_training=True):
      """
      :param img: input images (b, c, y, x, (z)).
      :return: rpn_pred_logits: (b, n_anchors, 2)
      :return: rpn_pred_deltas: (b, n_anchors, (y, x, (z), log(h), log(w), (log(d))))
      :return: batch_proposal_boxes: (b, n_proposals, (y1, x1, y2, x2, (z1), (z2), batch_ix)) only for monitoring/plotting.
      :return: detections: (n_final_detections, (y1, x1, y2, x2, (z1), (z2), batch_ix, pred_class_id, pred_score)
      :return: detection_masks: (n_final_detections, n_classes, y, x, (z)) raw molded masks as returned by mask-head.
      """
      # extract features.
      fpn_outs = self.fpn(img)
      seg_logits = self.final_conv(fpn_outs[0])
      rpn_feature_maps = [
          fpn_outs[i + 1] for i in self.cf.pyramid_levels
      ]
      self.mrcnn_feature_maps = rpn_feature_maps
  
      # loop through pyramid layers and apply RPN.
      layer_outputs = []  # list of lists
      for p in rpn_feature_maps:
          layer_outputs.append(self.rpn(p))
  
      # concatenate layer outputs.
      # convert from list of lists of level outputs to list of lists of outputs across levels.
      # e.g. [[a1, b1, c1], [a2, b2, c2]] => [[a1, a2], [b1, b2], [c1, c2]]
      outputs = list(zip(*layer_outputs))
      outputs = [torch.cat(list(o), dim=1) for o in outputs]
      rpn_pred_logits, rpn_pred_probs, rpn_pred_deltas = outputs
  
      # generate proposals: apply predicted deltas to anchors and filter by foreground scores from RPN classifier.
      proposal_count = (
          self.cf.post_nms_rois_training
          if is_training
          else self.cf.post_nms_rois_inference
      )
      batch_rpn_rois, batch_proposal_boxes = proposal_layer(
          rpn_pred_probs,
          rpn_pred_deltas,
          proposal_count,
          self.anchors,
          self.cf,
      )
  
      # merge batch dimension of proposals while storing allocation info in coordinate dimension.
      batch_ixs = (
          torch.from_numpy(
              np.repeat(
                  np.arange(batch_rpn_rois.shape[0]),
                  batch_rpn_rois.shape[1],
              )
          )
          .float()
          .cuda()
      )
      rpn_rois = batch_rpn_rois.view(-1, batch_rpn_rois.shape[2])
      self.rpn_rois_batch_info = torch.cat(
          (rpn_rois, batch_ixs.unsqueeze(1)), dim=1
      )
  
      # this is the first of two forward passes in the second stage, where no activations are stored for backprop.
      # here, all proposals are forwarded (with virtual_batch_size = batch_size * post_nms_rois.)
      # for inference/monitoring as well as sampling of rois for the loss functions.
      # processed in chunks of roi_chunk_size to re-adjust to gpu-memory.
      chunked_rpn_rois = self.rpn_rois_batch_info.split(
          self.cf.roi_chunk_size
      )
      class_logits_list, bboxes_list = [], []
      with torch.no_grad():
          for chunk in chunked_rpn_rois:
              chunk_class_logits, chunk_bboxes = self.classifier(
                  self.mrcnn_feature_maps, chunk
              )
              class_logits_list.append(chunk_class_logits)
              bboxes_list.append(chunk_bboxes)
      batch_mrcnn_class_logits = torch.cat(class_logits_list, 0)
      batch_mrcnn_bbox = torch.cat(bboxes_list, 0)
      self.batch_mrcnn_class_scores = F.softmax(
          batch_mrcnn_class_logits, dim=1
      )
  
      # refine classified proposals, filter and return final detections.
      detections = refine_detections(
          rpn_rois,
          self.batch_mrcnn_class_scores,
          batch_mrcnn_bbox,
          batch_ixs,
          self.cf,
      )
  
      return [
          rpn_pred_logits,
          rpn_pred_deltas,
          batch_proposal_boxes,
          detections,
          seg_logits,
      ]
  
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 5 for calling the net obj's underlying member method code with example usage: obj.forward(img, is_training) and returns: list