class_docstr: PPO Model
class_docstr_tok: ["PPO","Model"]
docstr: Train the policy/value network using trials_info
  
  Parameters
  ----------
  trials_info : TrialsInfo
      Complete info of the generated trials from the previous inference
  nenvs : int
      The batch size of the (previous) inference
docstr_tok: ["Train","the","policy\/value","network","using","trials_info","Parameters","--","--","--","--","--","trials_info",":","TrialsInfo","Complete","info","of","the","generated","trials","from","the","previous","inference","nenvs",":","int","The","batch","size","of","the","(","previous",")","inference"]
code: def train(self, trials_info, nenvs):
      """
      Train the policy/value network using trials_info
  
      Parameters
      ----------
      trials_info : TrialsInfo
          Complete info of the generated trials from the previous inference
      nenvs : int
          The batch size of the (previous) inference
      """
      # keep frac decay for future optimization
      if self.cur_update <= self.nupdates:
          frac = 1.0 - (self.cur_update - 1.0) / self.nupdates
      else:
          logger.warning(
              "current update (self.cur_update) %d has exceeded total updates (self.nupdates) %d",
              self.cur_update,
              self.nupdates,
          )
          frac = 1.0 - (self.nupdates - 1.0) / self.nupdates
      lrnow = self.lr(frac)
      cliprangenow = self.cliprange(frac)
      self.cur_update += 1
  
      states = self.states
  
      assert states is not None  # recurrent version
      assert nenvs % self.model_config.nminibatches == 0
      envsperbatch = nenvs // self.model_config.nminibatches
      envinds = np.arange(nenvs)
      flatinds = np.arange(nenvs * self.model_config.nsteps).reshape(
          nenvs, self.model_config.nsteps
      )
      for _ in range(self.model_config.noptepochs):
          np.random.shuffle(envinds)
          for start in range(0, nenvs, envsperbatch):
              end = start + envsperbatch
              mbenvinds = envinds[start:end]
              mbflatinds = flatinds[mbenvinds].ravel()
              slices = (
                  arr[mbflatinds]
                  for arr in (
                      trials_info.obs,
                      trials_info.returns,
                      trials_info.dones,
                      trials_info.actions,
                      trials_info.values,
                      trials_info.neglogpacs,
                  )
              )
              mbstates = states[mbenvinds]
              self.model.train(lrnow, cliprangenow, *slices, mbstates)
  
imports: import copy
  import logging
  import numpy
  from gym import spaces
  from schema import Schema, Optional
  import nni
  from nni import ClassArgsValidator
  from nni.tuner import Tuner
  from nni.utils import OptimizeMode, extract_scalar_reward
  from .model import Model
  from .util import set_global_seeds
  from .policy import build_lstm_policy
label_desc: Use image node_id 4 for calling the PPOModel obj's underlying member method code with example usage: obj.train(trials_info, nenvs) without return types