class_docstr: Population Based Training (PBT) comes from `Population Based Training of Neural Networks <https://arxiv.org/abs/1711.09846v1>`__.
  It's a simple asynchronous optimization algorithm which effectively utilizes a fixed computational budget to jointly optimize
  a population of models and their hyperparameters to maximize performance.
  Importantly, PBT discovers a schedule of hyperparameter settings rather than following the generally sub-optimal strategy of
  trying to find a single fixed set to use for the whole course of training.
  
  .. image:: ../../img/pbt.jpg
  
  PBT tuner initializes a population with several trials (i.e., ``population_size``).
  There are four steps in the above figure, each trial only runs by one step. How long is one step is controlled by trial code,
  e.g., one epoch. When a trial starts, it loads a checkpoint specified by PBT tuner and continues to run one step,
  then saves checkpoint to a directory specified by PBT tuner and exits.
  The trials in a population run steps synchronously, that is, after all the trials finish the ``i``-th step,
  the ``(i+1)``-th step can be started. Exploitation and exploration of PBT are executed between two consecutive steps.
  
  Two important steps to follow if you are trying to use PBT tuner:
  
  1. **Provide checkpoint directory**. Since some trials need to load other trial's checkpoint,
     users should provide a directory (i.e., ``all_checkpoint_dir``) which is accessible by every trial.
     It is easy for local mode, users could directly use the default directory or specify any directory on the local machine.
     For other training services, users should follow
     :doc:`the document of those training services </experiment/training_service/shared_storage>`
     to provide a directory in a shared storage, such as NFS, Azure storage.
  
  2. **Modify your trial code**. Before running a step, a trial needs to load a checkpoint,
     the checkpoint directory is specified in hyper-parameter configuration generated by PBT tuner,
     i.e., ``params['load_checkpoint_dir']``. Similarly, the directory for saving checkpoint is also included in the configuration,
     i.e., ``params['save_checkpoint_dir']``. Here, ``all_checkpoint_dir`` is base folder of ``load_checkpoint_dir``
     and ``save_checkpoint_dir`` whose format is ``all_checkpoint_dir/<population-id>/<step>``.
  
     .. code-block:: python
  
      params = nni.get_next_parameter()
      # the path of the checkpoint to load
      load_path = os.path.join(params['load_checkpoint_dir'], 'model.pth')
      # load checkpoint from `load_path`
      ...
      # run one step
      ...
      # the path for saving a checkpoint
      save_path = os.path.join(params['save_checkpoint_dir'], 'model.pth')
      # save checkpoint to `save_path`
      ...
  
  The complete example code can be found :githublink:`here <examples/trials/mnist-pbt-tuner-pytorch>`.
  
  Parameters
  ----------
  optimize_mode : ``maximize`` or ``minimize``, default: ``maximize``
      If ``maximize``, the tuner will target to maximize metrics. If ``minimize``, the tuner will target to minimize metrics.
  all_checkpoint_dir : str
      Directory for trials to load and save checkpoint.
      If not specified, the directory would be ``~/nni/checkpoint/``.
      Note that if the experiment is not local mode,
      users should provide a path in a shared storage which can be accessed by all the trials.
  population_size : int, default = 10
      Number of trials in a population. Each step has this number of trials.
      In our implementation, one step is running each trial by specific training epochs set by users.
  factor : float, default = (1.2, 0.8)
      Factors for perturbation of hyperparameters.
  resample_probability : float, default = 0.25
      Probability for resampling.
  fraction : float, default = 0.2
      Fraction for selecting bottom and top trials.
  
  Examples
  --------
  Below is an example of PBT tuner configuration in experiment config file.
  
  .. code-block:: yaml
  
      tuner:
        name: PBT
        classArgs:
          optimize_mode: maximize
          all_checkpoint_dir: /the/path/to/store/checkpoints
          population_size: 10
  
  Notes
  -----
  Assessor is not allowed if PBT tuner is used.
code: def __init__(
      self,
      optimize_mode="maximize",
      all_checkpoint_dir=None,
      population_size=10,
      factor=0.2,
      resample_probability=0.25,
      fraction=0.2,
  ):
      self.optimize_mode = OptimizeMode(optimize_mode)
      if all_checkpoint_dir is None:
          all_checkpoint_dir = os.getenv("NNI_CHECKPOINT_DIRECTORY")
          logger.info(
              "Checkpoint dir is set to %s by default.",
              all_checkpoint_dir,
          )
      self.all_checkpoint_dir = all_checkpoint_dir
      self.population_size = population_size
      self.factor = factor
      self.resample_probability = resample_probability
      self.fraction = fraction
      # defined in trial code
      # self.perturbation_interval = perturbation_interval
  
      self.population = None
      self.pos = -1
      self.param_ids = []
      self.running = {}
      self.finished = []
      self.credit = 0
      self.finished_trials = 0
      self.epoch = 0
  
      self.searchspace_json = None
      self.space = None
  
      self.send_trial_callback = None
  
      logger.info("PBT tuner initialization")
  
imports: import copy
  import logging
  import os
  import random
  import numpy
  from schema import Schema, Optional
  import nni
  from nni import ClassArgsValidator
  import nni.parameter_expressions
  from nni.tuner import Tuner
  from nni.utils import OptimizeMode, extract_scalar_reward, split_index, json2parameter, json2space
label_desc: Use image node_id 1 to create a new PBTTuner object from inherited base classes: Tuner with example: obj = PBTTuner(optimize_mode, all_checkpoint_dir, population_size, factor, resample_probability, fraction)