docstr: 划分正负样本，统计对应gt的标签以及边界框回归信息
  list元素个数为batch_size
  Args:
      proposals: rpn预测的boxes
      targets:
  
  Returns:
docstr_tok: ["\u5212\u5206\u6b63\u8d1f\u6837\u672c\uff0c\u7edf\u8ba1\u5bf9\u5e94gt\u7684\u6807\u7b7e\u4ee5\u53ca\u8fb9\u754c\u6846\u56de\u5f52\u4fe1\u606f","list\u5143\u7d20\u4e2a\u6570\u4e3abatch_size","Args",":","proposals",":","rpn\u9884\u6d4b\u7684boxes","targets",":","Returns",":"]
code: def select_training_samples(
      self,
      proposals,  # type: List[Tensor]
      targets,  # type: Optional[List[Dict[str, Tensor]]]
  ):
      # type: (...) -> Tuple[List[Tensor], List[Tensor], List[Tensor], List[Tensor]]
      """
      划分正负样本，统计对应gt的标签以及边界框回归信息
      list元素个数为batch_size
      Args:
          proposals: rpn预测的boxes
          targets:
  
      Returns:
  
      """
  
      # 检查target数据是否为空
      self.check_targets(targets)
      if targets is None:
          raise ValueError("target should not be None.")
  
      dtype = proposals[0].dtype
      device = proposals[0].device
  
      # 获取标注好的boxes以及labels信息
      gt_boxes = [t["boxes"].to(dtype) for t in targets]
      gt_labels = [t["labels"] for t in targets]
  
      # append ground-truth bboxes to proposal
      # 将gt_boxes拼接到proposal后面
      proposals = self.add_gt_proposals(proposals, gt_boxes)
  
      # get matching gt indices for each proposal
      # 为每个proposal匹配对应的gt_box，并划分到正负样本中
      matched_idxs, labels = self.assign_targets_to_proposals(
          proposals, gt_boxes, gt_labels
      )
      # sample a fixed proportion of positive-negative proposals
      # 按给定数量和比例采样正负样本
      sampled_inds = self.subsample(labels)
      matched_gt_boxes = []
      num_images = len(proposals)
  
      # 遍历每张图像
      for img_id in range(num_images):
          # 获取每张图像的正负样本索引
          img_sampled_inds = sampled_inds[img_id]
          # 获取对应正负样本的proposals信息
          proposals[img_id] = proposals[img_id][img_sampled_inds]
          # 获取对应正负样本的真实类别信息
          labels[img_id] = labels[img_id][img_sampled_inds]
          # 获取对应正负样本的gt索引信息
          matched_idxs[img_id] = matched_idxs[img_id][img_sampled_inds]
  
          gt_boxes_in_image = gt_boxes[img_id]
          if gt_boxes_in_image.numel() == 0:
              gt_boxes_in_image = torch.zeros(
                  (1, 4), dtype=dtype, device=device
              )
          # 获取对应正负样本的gt box信息
          matched_gt_boxes.append(
              gt_boxes_in_image[matched_idxs[img_id]]
          )
  
      # 根据gt和proposal计算边框回归参数（针对gt的）
      regression_targets = self.box_coder.encode(
          matched_gt_boxes, proposals
      )
      return proposals, matched_idxs, labels, regression_targets
  
imports: from typing import Optional, List, Dict, Tuple
  import torch
  from torch import Tensor
  import torch.nn.functional
  from torchvision.ops import roi_align
  from .None import det_utils
  from .None import boxes
label_desc: Use image node_id 7 for calling the RoIHeads obj's underlying member method code with example usage: obj.select_training_samples(proposals, targets) and returns: proposals,  matched_idxs,  labels,  regression_targets