class_docstr: Samples a mini-batch of indices for a balanced class batching
  
  Args:
      dataset_items(list): dataset items to sample from.
      classes (list): list of classes of dataset_items to sample from.
      batch_size (int): total number of samples to be sampled in a mini-batch.
      num_gpus (int): number of GPU in the data parallel mode.
      shuffle (bool): if True, samples randomly, otherwise samples sequentially.
      drop_last (bool): if True, drops last incomplete batch.
class_docstr_tok: ["Samples","a","mini-batch","of","indices","for","a","balanced","class","batching","Args",":","dataset_items","(","list",")",":","dataset","items","to","sample","from",".","classes","(","list",")",":","list","of","classes","of","dataset_items","to","sample","from",".","batch_size","(","int",")",":","total","number","of","samples","to","be","sampled","in","a","mini-batch",".","num_gpus","(","int",")",":","number","of","GPU","in","the","data","parallel","mode",".","shuffle","(","bool",")",":","if","True",",","samples","randomly",",","otherwise","samples","sequentially",".","drop_last","(","bool",")",":","if","True",",","drops","last","incomplete","batch","."]
code: def __init__(
      self,
      dataset_items,
      classes,
      batch_size,
      num_classes_in_batch,
      num_gpus=1,
      shuffle=True,
      drop_last=False,
      label_key="class_name",
  ):
      super().__init__(dataset_items)
      assert (
          batch_size % (num_classes_in_batch * num_gpus) == 0
      ), "Batch size must be divisible by number of classes times the number of data parallel devices (if enabled)."
  
      label_indices = {}
      for idx, item in enumerate(dataset_items):
          label = item[label_key]
          if label not in label_indices.keys():
              label_indices[label] = [idx]
          else:
              label_indices[label].append(idx)
  
      if shuffle:
          self._samplers = [
              SubsetRandomSampler(label_indices[key]) for key in classes
          ]
      else:
          self._samplers = [
              SubsetSampler(label_indices[key]) for key in classes
          ]
  
      self._batch_size = batch_size
      self._drop_last = drop_last
      self._dp_devices = num_gpus
      self._num_classes_in_batch = num_classes_in_batch
  
imports: import math
  import random
  from typing import Callable, List, Union
  from torch.utils.data.sampler import BatchSampler, Sampler, SubsetRandomSampler
label_desc: Use image node_id 1 to create a new PerfectBatchSampler object from inherited base classes: Sampler with example: obj = PerfectBatchSampler(dataset_items, classes, batch_size, num_classes_in_batch, num_gpus, shuffle, drop_last, label_key)