docstr: Run a learning step of the model
  
  :return:
      - observations: (np.ndarray) the observations
      - rewards: (np.ndarray) the rewards
      - masks: (numpy bool) whether an episode is over or not
      - actions: (np.ndarray) the actions
      - values: (np.ndarray) the value function output
      - negative log probabilities: (np.ndarray)
      - states: (np.ndarray) the internal states of the recurrent policies
      - infos: (dict) the extra information of the model
docstr_tok: ["Run","a","learning","step","of","the","model",":","return",":","-","observations",":","(","np.ndarray",")","the","observations","-","rewards",":","(","np.ndarray",")","the","rewards","-","masks",":","(","numpy","bool",")","whether","an","episode","is","over","or","not","-","actions",":","(","np.ndarray",")","the","actions","-","values",":","(","np.ndarray",")","the","value","function","output","-","negative","log","probabilities",":","(","np.ndarray",")","-","states",":","(","np.ndarray",")","the","internal","states","of","the","recurrent","policies","-","infos",":","(","dict",")","the","extra","information","of","the","model"]
code: def _run(self):
      """
      Run a learning step of the model
  
      :return:
          - observations: (np.ndarray) the observations
          - rewards: (np.ndarray) the rewards
          - masks: (numpy bool) whether an episode is over or not
          - actions: (np.ndarray) the actions
          - values: (np.ndarray) the value function output
          - negative log probabilities: (np.ndarray)
          - states: (np.ndarray) the internal states of the recurrent policies
          - infos: (dict) the extra information of the model
      """
      # mb stands for minibatch
      (
          mb_obs,
          mb_rewards,
          mb_actions,
          mb_values,
          mb_dones,
          mb_neglogpacs,
      ) = ([], [], [], [], [], [])
      mb_states = self.states
      ep_infos = []
      for _ in range(self.n_steps):
          actions, values, self.states, neglogpacs = self.model.step(
              self.obs, self.states, self.dones
          )  # pytype: disable=attribute-error
          mb_obs.append(self.obs.copy())
          mb_actions.append(actions)
          mb_values.append(values)
          mb_neglogpacs.append(neglogpacs)
          mb_dones.append(self.dones)
          clipped_actions = actions
          # Clip the actions to avoid out of bound error
          if isinstance(self.env.action_space, gym.spaces.Box):
              clipped_actions = np.clip(
                  actions,
                  self.env.action_space.low,
                  self.env.action_space.high,
              )
          self.obs[:], rewards, self.dones, infos = self.env.step(
              clipped_actions
          )
  
          self.model.num_timesteps += self.n_envs
  
          if self.callback is not None:
              # Abort training early
              self.callback.update_locals(locals())
              if self.callback.on_step() is False:
                  self.continue_training = False
                  # Return dummy values
                  return [None] * 9
  
          for info in infos:
              maybe_ep_info = info.get("episode")
              if maybe_ep_info is not None:
                  ep_infos.append(maybe_ep_info)
          mb_rewards.append(rewards)
      # batch of steps to batch of rollouts
      mb_obs = np.asarray(mb_obs, dtype=self.obs.dtype)
      mb_rewards = np.asarray(mb_rewards, dtype=np.float32)
      mb_actions = np.asarray(mb_actions)
      mb_values = np.asarray(mb_values, dtype=np.float32)
      mb_neglogpacs = np.asarray(mb_neglogpacs, dtype=np.float32)
      mb_dones = np.asarray(mb_dones, dtype=np.bool)
      last_values = self.model.value(
          self.obs, self.states, self.dones
      )  # pytype: disable=attribute-error
      # discount/bootstrap off value fn
      mb_advs = np.zeros_like(mb_rewards)
      true_reward = np.copy(mb_rewards)
      last_gae_lam = 0
      for step in reversed(range(self.n_steps)):
          if step == self.n_steps - 1:
              nextnonterminal = 1.0 - self.dones
              nextvalues = last_values
          else:
              nextnonterminal = 1.0 - mb_dones[step + 1]
              nextvalues = mb_values[step + 1]
          delta = (
              mb_rewards[step]
              + self.gamma * nextvalues * nextnonterminal
              - mb_values[step]
          )
          mb_advs[step] = last_gae_lam = (
              delta
              + self.gamma * self.lam * nextnonterminal * last_gae_lam
          )
      mb_returns = mb_advs + mb_values
  
      (
          mb_obs,
          mb_returns,
          mb_dones,
          mb_actions,
          mb_values,
          mb_neglogpacs,
          true_reward,
      ) = map(
          swap_and_flatten,
          (
              mb_obs,
              mb_returns,
              mb_dones,
              mb_actions,
              mb_values,
              mb_neglogpacs,
              true_reward,
          ),
      )
  
      return (
          mb_obs,
          mb_returns,
          mb_dones,
          mb_actions,
          mb_values,
          mb_neglogpacs,
          mb_states,
          ep_infos,
          true_reward,
      )
  
imports: import time
  import gym
  import numpy
  import tensorflow
  from stable_baselines import logger
  from stable_baselines.common import explained_variance, ActorCriticRLModel, tf_util, SetVerbosity, TensorboardWriter
  from stable_baselines.common.runners import AbstractEnvRunner
  from stable_baselines.common.policies import ActorCriticPolicy, RecurrentActorCriticPolicy
  from stable_baselines.common.schedules import get_schedule_fn
  from stable_baselines.common.tf_util import total_episode_reward_logger
  from stable_baselines.common.math_util import safe_mean
label_desc: Use image node_id 2 for calling the Runner obj's underlying member method code with example usage: obj._run() and returns: mb_obs,  mb_returns,  mb_dones,  mb_actions,  mb_values,  mb_neglogpacs,  mb_states,  ep_infos,  true_reward, unknown