code: def build_pose_train_loader(cfg, mapper=None):
      """
      A data loader is created by the following steps:
  
      1. Use the dataset names in config to query :class:`DatasetCatalog`, and obtain a list of dicts.
      2. Coordinate a random shuffle order shared among all processes (all GPUs)
      3. Each process spawn another few workers to process the dicts. Each worker will:
         * Map each metadata dict into another format to be consumed by the model.
         * Batch them by simply putting dicts into a list.
  
      The batched ``list[mapped_dict]`` is what this dataloader will yield.
  
      Args:
          cfg (CfgNode): the config
          mapper (callable): a callable which takes a sample (dict) from dataset and
              returns the format to be consumed by the model.
              By default it will be `DatasetMapper(cfg, True)`.
  
      Returns:
          an infinite iterator of training data
      """
      dataset_dicts = get_pose_dataset_dicts(
          cfg.CONFIG.DATA.DATASET.TRAIN,
          filter_empty=cfg.CONFIG.DATA.DETECTION.FILTER_EMPTY_ANNOTATIONS,
          min_keypoints=cfg.CONFIG.MODEL.ROI_KEYPOINT_HEAD.MIN_KEYPOINTS_PER_IMAGE
          if cfg.CONFIG.DATA.KEYPOINT_ON
          else 0,
          compute_pseudo_bbox=cfg.CONFIG.DATA.DETECTION.COMPUTE_PSEUDO_BBOX,
          proposal_files=cfg.CONFIG.DATA.DATASET.PROPOSAL_FILES_TRAIN
          if cfg.CONFIG.DATA.LOAD_PROPOSALS
          else None,
      )
      dataset = DatasetFromList(dataset_dicts, copy=False)
  
      if mapper is None:
          mapper = DatasetMapperWithBasis(cfg, True)
      dataset = MapDataset(dataset, mapper)
  
      sampler_name = cfg.CONFIG.DATA.DETECTION.SAMPLER_TRAIN
      logger = logging.getLogger(__name__)
      logger.info("Using training sampler {}".format(sampler_name))
      # TODO avoid if-else?
      if sampler_name == "TrainingSampler":
          sampler = TrainingSampler(len(dataset))
      elif sampler_name == "RepeatFactorTrainingSampler":
          repeat_factors = RepeatFactorTrainingSampler.repeat_factors_from_category_frequency(
              dataset_dicts, cfg.CONFIG.DATA.DETECTION.REPEAT_THRESHOLD
          )
          sampler = RepeatFactorTrainingSampler(repeat_factors)
      else:
          raise ValueError(
              "Unknown training sampler: {}".format(sampler_name)
          )
      return build_batch_data_loader(
          dataset,
          sampler,
          cfg.CONFIG.TRAIN.BATCH_SIZE,
          aspect_ratio_grouping=cfg.CONFIG.DATA.DETECTION.ASPECT_RATIO_GROUPING,
          num_workers=cfg.CONFIG.DATA.NUM_WORKERS,
      )
  
imports: import itertools
  import copy
  import logging
  import numpy
  import torch
  from ..registry.catalog import DatasetCatalog, MetadataCatalog
  from ..detection.detection_dataset import load_proposals_into_dataset, filter_images_with_few_keypoints, filter_images_with_only_crowd_annotations, get_detection_dataset_dicts
  from ..detection.detection_dataset import print_instances_class_histogram, build_batch_data_loader, trivial_batch_collator
  from ..detection.detection_utils import check_metadata_consistency, read_image, filter_empty_instances, annotations_to_instances
  from ..detection.detection_utils import check_image_size, build_augmentation_ranged_clip, transform_instance_annotations
  from ..detection.detection_dataset import DatasetFromList, MapDataset, DatasetMapper
  from ..detection.samplers import RepeatFactorTrainingSampler, TrainingSampler, InferenceSampler
  from ..transforms import instance_transforms
  from ..transforms.instance_transforms import RandomCropWithInstance
  from ..structures import BoxMode
label_desc: Use image node_id 3 for calling a global function with example usage: build_pose_train_loader(cfg, mapper) and returns: build_batch_data_loader