code: def pretty_print(self):
      if not self.config.training.log_detailed_config:
          return
  
      logger.info("=====  Training Parameters    =====")
      logger.info(self._convert_node_to_json(self.config.training))
  
      logger.info("======  Dataset Attributes  ======")
      datasets = self.config.datasets.split(",")
  
      for dataset in datasets:
          if dataset in self.config.dataset_config:
              logger.info(f"======== {dataset} =======")
              dataset_config = self.config.dataset_config[dataset]
              logger.info(self._convert_node_to_json(dataset_config))
          else:
              logger.warning(
                  f"No dataset named '{dataset}' in config. Skipping"
              )
  
      logger.info("======  Optimizer Attributes  ======")
      logger.info(self._convert_node_to_json(self.config.optimizer))
  
      if self.config.model not in self.config.model_config:
          raise ValueError(
              f"{self.config.model} not present in model attributes"
          )
  
      logger.info(
          f"======  Model ({self.config.model}) Attributes  ======"
      )
      logger.info(
          self._convert_node_to_json(
              self.config.model_config[self.config.model]
          )
      )
  
imports: import collections
  import json
  import logging
  import os
  import warnings
  from ast import literal_eval
  from typing import List
  import torch
  from mmf.common.registry import registry
  from mmf.utils.env import import_user_module
  from mmf.utils.file_io import PathManager
  from mmf.utils.general import get_absolute_path, get_mmf_root
  from omegaconf import DictConfig, errors, OmegaConf
label_desc: Use image node_id 16 for calling the Configuration obj's underlying member method code with example usage: obj.pretty_print() without return types