class_docstr: ## Trainer
class_docstr_tok: ["#","#","Trainer"]
code: def __init__(
      self,
      *,
      updates: int,
      epochs: IntDynamicHyperParam,
      n_workers: int,
      worker_steps: int,
      batches: int,
      value_loss_coef: FloatDynamicHyperParam,
      entropy_bonus_coef: FloatDynamicHyperParam,
      clip_range: FloatDynamicHyperParam,
      learning_rate: FloatDynamicHyperParam,
  ):
      # #### Configurations
  
      # number of updates
      self.updates = updates
      # number of epochs to train the model with sampled data
      self.epochs = epochs
      # number of worker processes
      self.n_workers = n_workers
      # number of steps to run on each process for a single update
      self.worker_steps = worker_steps
      # number of mini batches
      self.batches = batches
      # total number of samples for a single update
      self.batch_size = self.n_workers * self.worker_steps
      # size of a mini batch
      self.mini_batch_size = self.batch_size // self.batches
      assert self.batch_size % self.batches == 0
  
      # Value loss coefficient
      self.value_loss_coef = value_loss_coef
      # Entropy bonus coefficient
      self.entropy_bonus_coef = entropy_bonus_coef
  
      # Clipping range
      self.clip_range = clip_range
      # Learning rate
      self.learning_rate = learning_rate
  
      # #### Initialize
  
      # create workers
      self.workers = [Worker(47 + i) for i in range(self.n_workers)]
  
      # initialize tensors for observations
      self.obs = np.zeros((self.n_workers, 4, 84, 84), dtype=np.uint8)
      for worker in self.workers:
          worker.child.send(("reset", None))
      for i, worker in enumerate(self.workers):
          self.obs[i] = worker.child.recv()
  
      # model
      self.model = Model().to(device)
  
      # optimizer
      self.optimizer = optim.Adam(self.model.parameters(), lr=2.5e-4)
  
      # GAE with $\gamma = 0.99$ and $\lambda = 0.95$
      self.gae = GAE(self.n_workers, self.worker_steps, 0.99, 0.95)
  
      # PPO Loss
      self.ppo_loss = ClippedPPOLoss()
  
      # Value Loss
      self.value_loss = ClippedValueFunctionLoss()
  
imports: from typing import Dict
  import numpy
  import torch
  from torch import nn
  from torch import optim
  from torch.distributions import Categorical
  from labml import monit, tracker, logger, experiment
  from labml.configs import FloatDynamicHyperParam, IntDynamicHyperParam
  from labml_helpers.module import Module
  from labml_nn.rl.game import Worker
  from labml_nn.rl.ppo import ClippedPPOLoss, ClippedValueFunctionLoss
  from labml_nn.rl.ppo.gae import GAE
label_desc: Use image node_id 1 to create a new Trainer object  with example: obj = Trainer()