class_docstr: Trainer class for OpenAI Evolution Strategies.
  
  :param algorithm_config: Algorithm parameters.
  :param torch_policy: Multi-step policy encapsulating the policy networks
  :param shared_noise: The noise table, with the same content for every worker and the master.
  :param normalization_stats: Normalization statistics as calculated by the NormalizeObservationWrapper.
class_docstr_tok: ["Trainer","class","for","OpenAI","Evolution","Strategies",".",":","param","algorithm_config",":","Algorithm","parameters",".",":","param","torch_policy",":","Multi-step","policy","encapsulating","the","policy","networks",":","param","shared_noise",":","The","noise","table",",","with","the","same","content","for","every","worker","and","the","master",".",":","param","normalization_stats",":","Normalization","statistics","as","calculated","by","the","NormalizeObservationWrapper","."]
code: def __init__(
      self,
      algorithm_config: ESAlgorithmConfig,
      torch_policy: TorchPolicy,
      shared_noise: SharedNoiseTable,
      normalization_stats: Optional[
          Dict[str, Tuple[np.ndarray, np.ndarray]]
      ],
  ) -> None:
      super().__init__(algorithm_config)
  
      # --- training setup ---
      self.model_selection: Optional[ModelSelectionBase] = None
      self.policy: Union[Policy, TorchModel] = torch_policy
  
      self.shared_noise = shared_noise
      self.normalization_stats = normalization_stats
  
      # setup the optimizer, now that the policy is available
      self.optimizer = Factory(Optimizer).instantiate(
          algorithm_config.optimizer
      )
      self.optimizer.setup(self.policy)
  
      # prepare statistics collection
      self.eval_stats = LogStatsAggregator(
          LogStatsLevel.EPOCH, get_stats_logger("eval")
      )
      self.train_stats = LogStatsAggregator(
          LogStatsLevel.EPOCH, get_stats_logger("train")
      )
      # injection of ES-specific events
      self.es_events = self.train_stats.create_event_topic(ESEvents)
  
imports: import itertools
  import logging
  import time
  from typing import Optional, Iterable, Generator, Tuple, Union, Dict
  import numpy
  import torch
  from typing.io import BinaryIO
  from maze.core.agent.policy import Policy
  from maze.core.agent.torch_model import TorchModel
  from maze.core.agent.torch_policy import TorchPolicy
  from maze.core.annotations import override
  from maze.core.env.base_env_events import BaseEnvEvents
  from maze.core.log_stats.log_stats import LogStatsAggregator, LogStatsLevel, get_stats_logger, increment_log_step
  from maze.core.utils.factory import Factory
  from maze.train.trainers.common.model_selection.model_selection_base import ModelSelectionBase
  from maze.train.trainers.common.trainer import Trainer
  from maze.train.trainers.es.distributed.es_distributed_rollouts import ESDistributedRollouts, ESRolloutResult
  from maze.train.trainers.es.es_algorithm_config import ESAlgorithmConfig
  from maze.train.trainers.es.es_events import ESEvents
  from maze.train.trainers.es.es_shared_noise_table import SharedNoiseTable
  from maze.train.trainers.es.es_utils import get_flat_parameters
  from maze.train.trainers.es.optimizers.base_optimizer import Optimizer
label_desc: Use image node_id 1 to create a new ESTrainer object from inherited base classes: Trainer with example: obj = ESTrainer(algorithm_config, torch_policy, shared_noise, normalization_stats)