code: def add_mrcnn_configs(self):
      # learning rate is a list with one entry per epoch.
      self.learning_rate = (
          [1e-4] * (self.num_epochs // 2)
          + [5 * 1e-5] * (self.num_epochs // 4)
          + [1e-5] * (self.num_epochs // 4)
      )
      assert len(self.learning_rate) == self.num_epochs, [
          len(self.learning_rate),
          self.num_epochs,
      ]
  
      # disable the re-sampling of mask proposals to original size for speed-up.
      # since evaluation is detection-driven (box-matching) and not instance segmentation-driven (iou-matching),
      # mask-outputs are optional.
      self.return_masks_in_val = True
      self.return_masks_in_test = False
  
      # set number of proposal boxes to plot after each epoch.
      self.n_plot_rpn_props = 5 if self.dim == 2 else 30
  
      # number of classes for head networks: n_foreground_classes + 1 (background)
      self.head_classes = 2
  
      # seg_classes hier refers to the first stage classifier (RPN)
      self.num_seg_classes = 2  # foreground vs. background
  
      # feature map strides per pyramid level are inferred from architecture.
      self.backbone_strides = {"xy": [4, 8, 16, 32], "z": [1, 2, 4, 8]}
  
      # anchor scales are chosen according to expected object sizes in data set. Default uses only one anchor scale
      # per pyramid level. (outer list are pyramid levels (corresponding to BACKBONE_STRIDES), inner list are scales per level.)
      self.rpn_anchor_scales = {
          "xy": [[8], [16], [32], [64]],
          "z": [[2], [4], [8], [16]],
      }
  
      # choose which pyramid levels to extract features from: P2: 0, P3: 1, P4: 2, P5: 3.
      self.pyramid_levels = [0, 1, 2, 3]
  
      # number of feature maps in rpn. typically lowered in 3D to save gpu-memory.
      self.n_rpn_features = 512 if self.dim == 2 else 128
  
      # anchor ratios and strides per position in feature maps.
      self.rpn_anchor_ratios = [0.5, 1, 2]
      self.rpn_anchor_stride = 1
  
      # Threshold for first stage (RPN) non-maximum suppression (NMS):  LOWER == HARDER SELECTION
      self.rpn_nms_threshold = 0.7 if self.dim == 2 else 0.7
  
      # loss sampling settings.
      self.rpn_train_anchors_per_image = 6  # per batch element
      self.train_rois_per_image = 6  # per batch element
      self.roi_positive_ratio = 0.5
      self.anchor_matching_iou = 0.7
  
      # factor of top-k candidates to draw from  per negative sample (stochastic-hard-example-mining).
      # poolsize to draw top-k candidates from will be shem_poolsize * n_negative_samples.
      self.shem_poolsize = 10
  
      self.pool_size = (7, 7) if self.dim == 2 else (7, 7, 3)
      self.mask_pool_size = (14, 14) if self.dim == 2 else (14, 14, 5)
      self.mask_shape = (28, 28) if self.dim == 2 else (28, 28, 10)
  
      self.rpn_bbox_std_dev = np.array([0.1, 0.1, 0.1, 0.2, 0.2, 0.2])
      self.bbox_std_dev = np.array([0.1, 0.1, 0.1, 0.2, 0.2, 0.2])
      self.window = np.array(
          [
              0,
              0,
              self.patch_size[0],
              self.patch_size[1],
              0,
              self.patch_size_3D[2],
          ]
      )
      self.scale = np.array(
          [
              self.patch_size[0],
              self.patch_size[1],
              self.patch_size[0],
              self.patch_size[1],
              self.patch_size_3D[2],
              self.patch_size_3D[2],
          ]
      )
      if self.dim == 2:
          self.rpn_bbox_std_dev = self.rpn_bbox_std_dev[:4]
          self.bbox_std_dev = self.bbox_std_dev[:4]
          self.window = self.window[:4]
          self.scale = self.scale[:4]
  
      # pre-selection in proposal-layer (stage 1) for NMS-speedup. applied per batch element.
      self.pre_nms_limit = 3000 if self.dim == 2 else 6000
  
      # n_proposals to be selected after NMS per batch element. too high numbers blow up memory if "detect_while_training" is True,
      # since proposals of the entire batch are forwarded through second stage in as one "batch".
      self.roi_chunk_size = 2500 if self.dim == 2 else 600
      self.post_nms_rois_training = 500 if self.dim == 2 else 75
      self.post_nms_rois_inference = 500
  
      # Final selection of detections (refine_detections)
      self.model_max_instances_per_batch_element = (
          10 if self.dim == 2 else 30
      )  # per batch element and class.
      self.detection_nms_threshold = 1e-5  # needs to be > 0, otherwise all predictions are one cluster.
      self.model_min_confidence = 0.1
  
      if self.dim == 2:
          self.backbone_shapes = np.array(
              [
                  [
                      int(np.ceil(self.patch_size[0] / stride)),
                      int(np.ceil(self.patch_size[1] / stride)),
                  ]
                  for stride in self.backbone_strides["xy"]
              ]
          )
      else:
          self.backbone_shapes = np.array(
              [
                  [
                      int(np.ceil(self.patch_size[0] / stride)),
                      int(np.ceil(self.patch_size[1] / stride)),
                      int(np.ceil(self.patch_size[2] / stride_z)),
                  ]
                  for stride, stride_z in zip(
                      self.backbone_strides["xy"],
                      self.backbone_strides["z"],
                  )
              ]
          )
  
      if (
          self.model == "retina_net"
          or self.model == "retina_unet"
          or self.model == "prob_detector"
      ):
          # implement extra anchor-scales according to retina-net publication.
          self.rpn_anchor_scales["xy"] = [
              [ii[0], ii[0] * (2 ** (1 / 3)), ii[0] * (2 ** (2 / 3))]
              for ii in self.rpn_anchor_scales["xy"]
          ]
          self.rpn_anchor_scales["z"] = [
              [ii[0], ii[0] * (2 ** (1 / 3)), ii[0] * (2 ** (2 / 3))]
              for ii in self.rpn_anchor_scales["z"]
          ]
          self.n_anchors_per_pos = len(self.rpn_anchor_ratios) * 3
  
          self.n_rpn_features = 256 if self.dim == 2 else 64
  
          # pre-selection of detections for NMS-speedup. per entire batch.
          self.pre_nms_limit = 10000 if self.dim == 2 else 50000
  
          # anchor matching iou is lower than in Mask R-CNN according to https://arxiv.org/abs/1708.02002
          self.anchor_matching_iou = 0.5
  
          if self.model == "retina_unet":
              self.operate_stride1 = True
  
          if self.model == "prob_detector":
              self.monitor_extra_values = [
                  "kl_loss",
                  "mu_prior",
                  "mu_post",
                  "sigma_prior",
                  "sigma_post",
              ]
              self.box_color_palette["sample"] = "w"
              self.n_latent_dims = 6
              self.class_specific_seg_flag = True
              self.n_probabilistic_samples = 4
  
          # if 'True', seg loss distinguishes all classes, else only foreground vs. background (class agnostic).
          self.num_seg_classes = (
              2 if self.class_specific_seg_flag else 2
          )
  
file_path: medicaldetectiontoolkit/experiments/pet_ct_tnm_classification/configs.py
imports: import sys
  import os
  import numpy
  from default_configs import DefaultConfigs
label_desc: Use image node_id 3 for calling the configs obj's underlying member method code with example usage: obj.add_mrcnn_configs() without return types