code: def train_agent_batch(
      agent,
      env,
      steps,
      outdir,
      checkpoint_freq=None,
      log_interval=None,
      max_episode_len=None,
      eval_interval=None,
      step_offset=0,
      evaluator=None,
      successful_score=None,
      step_hooks=(),
      return_window_size=100,
      logger=None,
  ):
      """Train an agent in a batch environment.
  
      Args:
          agent: Agent to train.
          env: Environment to train the agent against.
          steps (int): Number of total time steps for training.
          eval_interval (int): Interval of evaluation.
          outdir (str): Path to the directory to output things.
          checkpoint_freq (int): frequency at which agents are stored.
          log_interval (int): Interval of logging.
          max_episode_len (int): Maximum episode length.
          step_offset (int): Time step from which training starts.
          return_window_size (int): Number of training episodes used to estimate
              the average returns of the current agent.
          successful_score (float): Finish training if the mean score is greater
              or equal to thisvalue if not None
          step_hooks (Sequence): Sequence of callable objects that accepts
              (env, agent, step) as arguments. They are called every step.
              See chainerrl.experiments.hooks.
          logger (logging.Logger): Logger used in this function.
      """
  
      logger = logger or logging.getLogger(__name__)
      recent_returns = deque(maxlen=return_window_size)
  
      num_envs = env.num_envs
      episode_r = np.zeros(num_envs, dtype=np.float64)
      episode_idx = np.zeros(num_envs, dtype="i")
      episode_len = np.zeros(num_envs, dtype="i")
  
      # o_0, r_0
      obss = env.reset()
      rs = np.zeros(num_envs, dtype="f")
  
      t = step_offset
      if hasattr(agent, "t"):
          agent.t = step_offset
  
      try:
          while True:
              # a_t
              actions = agent.batch_act_and_train(obss)
              # o_{t+1}, r_{t+1}
              obss, rs, dones, infos = env.step(actions)
              episode_r += rs
              episode_len += 1
  
              # Compute mask for done and reset
              if max_episode_len is None:
                  resets = np.zeros(num_envs, dtype=bool)
              else:
                  resets = episode_len == max_episode_len
              resets = np.logical_or(
                  resets,
                  [info.get("needs_reset", False) for info in infos],
              )
              # Agent observes the consequences
              agent.batch_observe_and_train(obss, rs, dones, resets)
  
              # Make mask. 0 if done/reset, 1 if pass
              end = np.logical_or(resets, dones)
              not_end = np.logical_not(end)
  
              # For episodes that ends, do the following:
              #   1. increment the episode count
              #   2. record the return
              #   3. clear the record of rewards
              #   4. clear the record of the number of steps
              #   5. reset the env to start a new episode
              # 3-5 are skipped when training is already finished.
              episode_idx += end
              recent_returns.extend(episode_r[end])
  
              for _ in range(num_envs):
                  t += 1
                  if checkpoint_freq and t % checkpoint_freq == 0:
                      save_agent(
                          agent, t, outdir, logger, suffix="_checkpoint"
                      )
  
                  for hook in step_hooks:
                      hook(env, agent, t)
  
              if (
                  log_interval is not None
                  and t >= log_interval
                  and t % log_interval < num_envs
              ):
                  logger.info(
                      "outdir:{} step:{} episode:{} last_R: {} average_R:{}".format(  # NOQA
                          outdir,
                          t,
                          np.sum(episode_idx),
                          recent_returns[-1]
                          if recent_returns
                          else np.nan,
                          np.mean(recent_returns)
                          if recent_returns
                          else np.nan,
                      )
                  )
                  logger.info(
                      "statistics: {}".format(agent.get_statistics())
                  )
              if evaluator:
                  if evaluator.evaluate_if_necessary(
                      t=t, episodes=np.sum(episode_idx)
                  ):
                      if (
                          successful_score is not None
                          and evaluator.max_score >= successful_score
                      ):
                          break
  
              if t >= steps:
                  break
  
              # Start new episodes if needed
              episode_r[end] = 0
              episode_len[end] = 0
              obss = env.reset(not_end)
  
      except (Exception, KeyboardInterrupt):
          # Save the current model before being killed
          save_agent(agent, t, outdir, logger, suffix="_except")
          env.close()
          if evaluator:
              evaluator.env.close()
          raise
      else:
          # Save the final model
          save_agent(agent, t, outdir, logger, suffix="_finish")
  
file_path: chainerrl/chainerrl/experiments/train_agent_batch.py
imports: from collections import deque
  import logging
  import os
  import numpy
  from chainerrl.experiments.evaluator import Evaluator
  from chainerrl.experiments.evaluator import save_agent
label_desc: Use image node_id 1 for calling a global function with example usage: train_agent_batch(agent, env, steps, outdir, checkpoint_freq, log_interval, max_episode_len, eval_interval, step_offset, evaluator, successful_score, step_hooks, return_window_size, logger) without return types