class_docstr: Base class of hard negative sampler.
  
  Hard negative sampler is used to suppress false positive rate in classification tasks.
  During training, it select 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:
      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: ["Base","class","of","hard","negative","sampler",".","Hard","negative","sampler","is","used","to","suppress","false","positive","rate","in","classification","tasks",".","During","training",",","it","select","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",":","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 hard negative samples.
  
  Args:
      negative: indices of all the negative samples, sized (P,),
          where P is the number of negative samples
      num_neg: number of negative samples to sample
      fg_probs: maximum foreground prediction scores (probability) across all the classes
          for each sample, sized (A,), where A is the number of samples.
  
  Returns:
      binary mask of negative samples to choose, sized (A,),
          where A is the number of samples in one image
docstr_tok: ["Select","hard","negative","samples",".","Args",":","negative",":","indices","of","all","the","negative","samples",",","sized","(","P",",",")",",","where","P","is","the","number","of","negative","samples","num_neg",":","number","of","negative","samples","to","sample","fg_probs",":","maximum","foreground","prediction","scores","(","probability",")","across","all","the","classes","for","each","sample",",","sized","(","A",",",")",",","where","A","is","the","number","of","samples",".","Returns",":","binary","mask","of","negative","samples","to","choose",",","sized","(","A",",",")",",","where","A","is","the","number","of","samples","in","one","image"]
code: def select_negatives(
      self, negative: Tensor, num_neg: int, fg_probs: Tensor
  ) -> Tensor:
      """
      Select hard negative samples.
  
      Args:
          negative: indices of all the negative samples, sized (P,),
              where P is the number of negative samples
          num_neg: number of negative samples to sample
          fg_probs: maximum foreground prediction scores (probability) across all the classes
              for each sample, sized (A,), where A is the number of samples.
  
      Returns:
          binary mask of negative samples to choose, sized (A,),
              where A is the number of samples in one image
      """
      if negative.numel() > fg_probs.numel():
          raise ValueError(
              "The number of negative samples should not be larger than the number of all samples."
          )
  
      # sample pool size is ``num_neg * self.pool_size``
      pool = int(num_neg * self.pool_size)
      pool = min(
          negative.numel(), pool
      )  # protect against not enough negatives
  
      # create a sample pool of highest scoring negative samples
      _, negative_idx_pool = (
          fg_probs[negative]
          .to(torch.float32)
          .topk(pool, dim=0, sorted=True)
      )
      hard_negative = negative[negative_idx_pool]
  
      # select negatives from pool
      perm2 = torch.randperm(
          hard_negative.numel(), device=hard_negative.device
      )[:num_neg]
      selected_neg_idx = hard_negative[perm2]
  
      # output a binary mask with same size of fg_probs that indicates selected negative samples.
      neg_mask = torch.zeros_like(fg_probs, dtype=torch.uint8)
      neg_mask[selected_neg_idx] = 1
      return neg_mask
  
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 HardNegativeSamplerBase obj's underlying member method code with example usage: obj.select_negatives(negative, num_neg, fg_probs) and returns: neg_mask