class_docstr: Cascade roi head including one bbox head and one mask head.
  
  https://arxiv.org/abs/1712.00726
docstr: Perform forward propagation and loss calculation of the detection
  roi on the features of the upstream network.
  
  Args:
      x (tuple[Tensor]): List of multi-level img features.
      rpn_results_list (list[:obj:`InstanceData`]): List of region
          proposals.
      batch_data_samples (list[:obj:`DetDataSample`]): The batch
          data samples. It usually includes information such
          as `gt_instance` or `gt_panoptic_seg` or `gt_sem_seg`.
  
  Returns:
      dict[str, Tensor]: A dictionary of loss components
docstr_tok: ["Perform","forward","propagation","and","loss","calculation","of","the","detection","roi","on","the","features","of","the","upstream","network",".","Args",":","x","(","tuple","[","Tensor","]",")",":","List","of","multi-level","img","features",".","rpn_results_list","(","list","[",":","obj",":","`","InstanceData","`","]",")",":","List","of","region","proposals",".","batch_data_samples","(","list","[",":","obj",":","`","DetDataSample","`","]",")",":","The","batch","data","samples",".","It","usually","includes","information","such","as","`","gt_instance","`","or","`","gt_panoptic_seg","`","or","`","gt_sem_seg","`",".","Returns",":","dict","[","str",",","Tensor","]",":","A","dictionary","of","loss","components"]
code: def loss(
      self,
      x: Tuple[Tensor],
      rpn_results_list: InstanceList,
      batch_data_samples: SampleList,
  ) -> dict:
      """Perform forward propagation and loss calculation of the detection
      roi on the features of the upstream network.
  
      Args:
          x (tuple[Tensor]): List of multi-level img features.
          rpn_results_list (list[:obj:`InstanceData`]): List of region
              proposals.
          batch_data_samples (list[:obj:`DetDataSample`]): The batch
              data samples. It usually includes information such
              as `gt_instance` or `gt_panoptic_seg` or `gt_sem_seg`.
  
      Returns:
          dict[str, Tensor]: A dictionary of loss components
      """
      # TODO: May add a new function in baseroihead
      assert len(rpn_results_list) == len(batch_data_samples)
      outputs = unpack_gt_instances(batch_data_samples)
      (
          batch_gt_instances,
          batch_gt_instances_ignore,
          batch_img_metas,
      ) = outputs
  
      num_imgs = len(batch_data_samples)
      losses = dict()
      results_list = rpn_results_list
      for stage in range(self.num_stages):
          self.current_stage = stage
  
          stage_loss_weight = self.stage_loss_weights[stage]
  
          # assign gts and sample proposals
          sampling_results = []
          if self.with_bbox or self.with_mask:
              bbox_assigner = self.bbox_assigner[stage]
              bbox_sampler = self.bbox_sampler[stage]
  
              for i in range(num_imgs):
                  results = results_list[i]
                  # rename rpn_results.bboxes to rpn_results.priors
                  results.priors = results.pop("bboxes")
  
                  assign_result = bbox_assigner.assign(
                      results,
                      batch_gt_instances[i],
                      batch_gt_instances_ignore[i],
                  )
  
                  sampling_result = bbox_sampler.sample(
                      assign_result,
                      results,
                      batch_gt_instances[i],
                      feats=[lvl_feat[i][None] for lvl_feat in x],
                  )
                  sampling_results.append(sampling_result)
  
          # bbox head forward and loss
          bbox_results = self.bbox_loss(stage, x, sampling_results)
  
          for name, value in bbox_results["loss_bbox"].items():
              losses[f"s{stage}.{name}"] = (
                  value * stage_loss_weight if "loss" in name else value
              )
  
          # mask head forward and loss
          if self.with_mask:
              mask_results = self.mask_loss(
                  stage, x, sampling_results, batch_gt_instances
              )
              for name, value in mask_results["loss_mask"].items():
                  losses[f"s{stage}.{name}"] = (
                      value * stage_loss_weight
                      if "loss" in name
                      else value
                  )
  
          # refine bboxes
          if stage < self.num_stages - 1:
              bbox_head = self.bbox_head[stage]
              with torch.no_grad():
                  results_list = bbox_head.refine_bboxes(
                      sampling_results, bbox_results, batch_img_metas
                  )
                  # Empty proposal
                  if results_list is None:
                      break
      return losses
  
imports: from typing import List, Sequence, Tuple, Union
  import torch
  import torch.nn
  from mmengine.model import ModuleList
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.models.task_modules.samplers import SamplingResult
  from mmdet.models.test_time_augs import merge_aug_masks
  from mmdet.registry import MODELS, TASK_UTILS
  from mmdet.structures import SampleList
  from mmdet.structures.bbox import bbox2roi, get_box_tensor
  from mmdet.utils import ConfigType, InstanceList, MultiConfig, OptConfigType, OptMultiConfig
  from ..utils.misc import empty_instances, unpack_gt_instances
  from .base_roi_head import BaseRoIHead
label_desc: Use image node_id 9 for calling the CascadeRoIHead obj's underlying member method code with example usage: obj.loss(x, rpn_results_list, batch_data_samples) and returns: losses