class_docstr: HardNegativeSampler is used to suppress false positive rate in classification tasks.
  During training, it selects negative samples with high prediction scores.
  
  The training workflow is described as the follows:
  1) forward network and get prediction scores (classification prob/logits) for all the samples;
  2) use hard negative sampler to choose negative samples with high prediction scores and some positive samples;
  3) compute classification loss for the selected samples;
  4) do back propagation.
  
  Args:
      batch_size_per_image: number of training samples to be randomly selected per image
      positive_fraction: percentage of positive elements in the selected samples
      min_neg: minimum number of negative samples to select if possible.
      pool_size: when we need ``num_neg`` hard negative samples, they will be randomly selected from
          ``num_neg * pool_size`` negative samples with the highest prediction scores.
          Larger ``pool_size`` gives more randomness, yet selects negative samples that are less 'hard',
          i.e., negative samples with lower prediction scores.
class_docstr_tok: ["HardNegativeSampler","is","used","to","suppress","false","positive","rate","in","classification","tasks",".","During","training",",","it","selects","negative","samples","with","high","prediction","scores",".","The","training","workflow","is","described","as","the","follows",":","1",")","forward","network","and","get","prediction","scores","(","classification","prob\/logits",")","for","all","the","samples",";","2",")","use","hard","negative","sampler","to","choose","negative","samples","with","high","prediction","scores","and","some","positive","samples",";","3",")","compute","classification","loss","for","the","selected","samples",";","4",")","do","back","propagation",".","Args",":","batch_size_per_image",":","number","of","training","samples","to","be","randomly","selected","per","image","positive_fraction",":","percentage","of","positive","elements","in","the","selected","samples","min_neg",":","minimum","number","of","negative","samples","to","select","if","possible",".","pool_size",":","when","we","need","``","num_neg","``","hard","negative","samples",",","they","will","be","randomly","selected","from","``","num_neg","*","pool_size","``","negative","samples","with","the","highest","prediction","scores",".","Larger","``","pool_size","``","gives","more","randomness",",","yet","selects","negative","samples","that","are","less","'hard","'",",","i.e.",",","negative","samples","with","lower","prediction","scores","."]
docstr: Select positives and hard negatives from list samples per image.
  Hard negative sampler will be applied to each image independently.
  
  Args:
      target_labels: list of labels per image.
          For image i in the batch, target_labels[i] is a Tensor sized (A_i,),
          where A_i is the number of samples in image i.
          Positive samples have positive labels, negative samples have label 0.
      concat_fg_probs: concatenated maximum foreground probability for all the images, sized (R,),
          where R is the sum of all samples inside one batch, i.e., R = A_0 + A_1 + ...
  
  Returns:
      - list of binary mask for positive samples
      - list of binary mask for negative samples
  
  Example:
      .. code-block:: python
  
          sampler = HardNegativeSampler(
              batch_size_per_image=6, positive_fraction=0.5, min_neg=1, pool_size=2
          )
          # two images with different number of samples
          target_labels = [ torch.tensor([0,1]), torch.tensor([1,0,2,1])]
          concat_fg_probs = torch.rand(6)
          pos_idx_list, neg_idx_list = sampler(target_labels, concat_fg_probs)
docstr_tok: ["Select","positives","and","hard","negatives","from","list","samples","per","image",".","Hard","negative","sampler","will","be","applied","to","each","image","independently",".","Args",":","target_labels",":","list","of","labels","per","image",".","For","image","i","in","the","batch",",","target_labels","[","i","]","is","a","Tensor","sized","(","A_i",",",")",",","where","A_i","is","the","number","of","samples","in","image","i",".","Positive","samples","have","positive","labels",",","negative","samples","have","label","0.","concat_fg_probs",":","concatenated","maximum","foreground","probability","for","all","the","images",",","sized","(","R",",",")",",","where","R","is","the","sum","of","all","samples","inside","one","batch",",","i.e.",",","R","=","A_0","+","A_1","+","...","Returns",":","-","list","of","binary","mask","for","positive","samples","-","list","of","binary","mask","for","negative","samples","Example",":","..","code-block",":",":","python","sampler","=","HardNegativeSampler","(","batch_size_per_image=6",",","positive_fraction=0.5",",","min_neg=1",",","pool_size=2",")","#","two","images","with","different","number","of","samples","target_labels","=","[","torch.tensor","(","[","0,1","]",")",",","torch.tensor","(","[","1,0,2,1","]",")","]","concat_fg_probs","=","torch.rand","(","6",")","pos_idx_list",",","neg_idx_list","=","sampler","(","target_labels",",","concat_fg_probs",")"]
code: def __call__(
      self, target_labels: list[Tensor], concat_fg_probs: Tensor
  ) -> tuple[list[Tensor], list[Tensor]]:
      """
      Select positives and hard negatives from list samples per image.
      Hard negative sampler will be applied to each image independently.
  
      Args:
          target_labels: list of labels per image.
              For image i in the batch, target_labels[i] is a Tensor sized (A_i,),
              where A_i is the number of samples in image i.
              Positive samples have positive labels, negative samples have label 0.
          concat_fg_probs: concatenated maximum foreground probability for all the images, sized (R,),
              where R is the sum of all samples inside one batch, i.e., R = A_0 + A_1 + ...
  
      Returns:
          - list of binary mask for positive samples
          - list of binary mask for negative samples
  
      Example:
          .. code-block:: python
  
              sampler = HardNegativeSampler(
                  batch_size_per_image=6, positive_fraction=0.5, min_neg=1, pool_size=2
              )
              # two images with different number of samples
              target_labels = [ torch.tensor([0,1]), torch.tensor([1,0,2,1])]
              concat_fg_probs = torch.rand(6)
              pos_idx_list, neg_idx_list = sampler(target_labels, concat_fg_probs)
      """
      samples_per_image = [
          samples_in_image.shape[0]
          for samples_in_image in target_labels
      ]
      fg_probs = concat_fg_probs.split(samples_per_image, 0)
      return self.select_samples_img_list(target_labels, fg_probs)
  
file_path: MONAI/monai/apps/detection/utils/hard_negative_sampler.py
imports: from __future__ import annotations
  import logging
  import torch
  from torch import Tensor
label_desc: Use image node_id 2 for calling the HardNegativeSampler obj's underlying member method code with example usage: obj.__call__(target_labels, concat_fg_probs) and returns: self