docstr: train method (also used for validation monitoring). wrapper around forward pass of network. prepares input data
  for processing, computes losses, and stores outputs in a dictionary.
  :param batch: dictionary containing 'data', 'seg', etc.
  :param kwargs:
  :return: results_dict: dictionary with keys:
          'boxes': list over batch elements. each batch element is a list of boxes. each box is a dictionary:
                  [[{box_0}, ... {box_n}], [{box_0}, ... {box_n}], ...]
          'seg_preds': pixel-wise class predictions (b, 1, y, x, (z)) with values [0, n_classes]
          'monitor_values': dict of values to be monitored.
docstr_tok: ["train","method","(","also","used","for","validation","monitoring",")",".","wrapper","around","forward","pass","of","network",".","prepares","input","data","for","processing",",","computes","losses",",","and","stores","outputs","in","a","dictionary",".",":","param","batch",":","dictionary","containing","'data","'",",","'seg","'",",","etc",".",":","param","kwargs",":",":","return",":","results_dict",":","dictionary","with","keys",":","'boxes","'",":","list","over","batch","elements",".","each","batch","element","is","a","list","of","boxes",".","each","box","is","a","dictionary",":","[","[","{","box_0","}",",","...","{","box_n","}","]",",","[","{","box_0","}",",","...","{","box_n","}","]",",","...","]","'seg_preds","'",":","pixel-wise","class","predictions","(","b",",","1",",","y",",","x",",","(","z",")",")","with","values","[","0",",","n_classes","]","'monitor_values","'",":","dict","of","values","to","be","monitored","."]
code: def train_forward(self, batch, **kwargs):
      """
      train method (also used for validation monitoring). wrapper around forward pass of network. prepares input data
      for processing, computes losses, and stores outputs in a dictionary.
      :param batch: dictionary containing 'data', 'seg', etc.
      :param kwargs:
      :return: results_dict: dictionary with keys:
              'boxes': list over batch elements. each batch element is a list of boxes. each box is a dictionary:
                      [[{box_0}, ... {box_n}], [{box_0}, ... {box_n}], ...]
              'seg_preds': pixel-wise class predictions (b, 1, y, x, (z)) with values [0, n_classes]
              'monitor_values': dict of values to be monitored.
      """
      img = batch["data"]
      seg = batch["seg"]
      var_img = torch.FloatTensor(img).cuda()
      var_seg = torch.FloatTensor(seg).cuda().long()
      var_seg_ohe = torch.FloatTensor(
          mutils.get_one_hot_encoding(seg, self.cf.num_seg_classes)
      ).cuda()
      results_dict = {}
      seg_logits, box_coords, max_scores = self.forward(var_img)
  
      results_dict["boxes"] = [[] for _ in range(img.shape[0])]
      for cix in range(len(self.cf.class_dict.keys())):
          for bix in range(img.shape[0]):
              for rix in range(len(max_scores[cix][bix])):
                  if (
                      max_scores[cix][bix][rix]
                      > self.cf.detection_min_confidence
                  ):
                      results_dict["boxes"][bix].append(
                          {
                              "box_coords": np.copy(
                                  box_coords[cix][bix][rix]
                              ),
                              "box_score": max_scores[cix][bix][rix],
                              "box_pred_class_id": cix
                              + 1,  # add 0 for background.
                              "box_type": "det",
                          }
                      )
  
      for bix in range(img.shape[0]):
          for tix in range(len(batch["bb_target"][bix])):
              results_dict["boxes"][bix].append(
                  {
                      "box_coords": batch["bb_target"][bix][tix],
                      "box_label": batch["roi_labels"][bix][tix],
                      "box_type": "gt",
                  }
              )
  
      # compute segmentation loss as either weighted cross entropy, dice loss, or the sum of both.
      loss = torch.FloatTensor([0]).cuda()
      if (
          self.cf.seg_loss_mode == "dice"
          or self.cf.seg_loss_mode == "dice_wce"
      ):
          loss += 1 - mutils.batch_dice(
              F.softmax(seg_logits, dim=1),
              var_seg_ohe,
              false_positive_weight=float(self.cf.fp_dice_weight),
          )
  
      if (
          self.cf.seg_loss_mode == "wce"
          or self.cf.seg_loss_mode == "dice_wce"
      ):
          loss += F.cross_entropy(
              seg_logits,
              var_seg[:, 0],
              weight=torch.tensor(self.cf.wce_weights).float().cuda(),
          )
  
      results_dict["seg_preds"] = np.argmax(
          F.softmax(seg_logits, 1).cpu().data.numpy(), 1
      )[:, np.newaxis]
      results_dict["torch_loss"] = loss
      results_dict["monitor_values"] = {"loss": loss.item()}
      results_dict["logger_string"] = "loss: {0:.2f}".format(
          loss.item()
      )
  
      return results_dict
  
file_path: medicaldetectiontoolkit/models/detection_unet.py
imports: import torch
  import torch.nn
  import torch.nn.functional
  from scipy.ndimage.measurements import label
  import numpy
  import utils.exp_utils
  import utils.model_utils
label_desc: Use image node_id 3 for calling the net obj's underlying member method code with example usage: obj.train_forward(batch) and returns: results_dict