class_docstr: Trainer for behavioral cloning learning.
  
  Runs training on top of provided trajectory data and rolls out the policy using the provided evaluator.
  
  In structured (multi-step) envs, all policies are trained simultaneously based on the substep actions
  and observation present in the trajectory data.
class_docstr_tok: ["Trainer","for","behavioral","cloning","learning",".","Runs","training","on","top","of","provided","trajectory","data","and","rolls","out","the","policy","using","the","provided","evaluator",".","In","structured","(","multi-step",")","envs",",","all","policies","are","trained","simultaneously","based","on","the","substep","actions","and","observation","present","in","the","trajectory","data","."]
docstr: Run a single training iterations of the behavioural cloning.
  
  :param observations: A list (w.r.t. the substeps/agents) of batched observations.
  :param actions: A list (w.r.t. the substeps/agents) of batched actions.
  :param actor_ids: A list (w.r.t. the substeps/agents) of the corresponding batched actor_ids.
docstr_tok: ["Run","a","single","training","iterations","of","the","behavioural","cloning",".",":","param","observations",":","A","list","(","w.r.t",".","the","substeps\/agents",")","of","batched","observations",".",":","param","actions",":","A","list","(","w.r.t",".","the","substeps\/agents",")","of","batched","actions",".",":","param","actor_ids",":","A","list","(","w.r.t",".","the","substeps\/agents",")","of","the","corresponding","batched","actor_ids","."]
code: def _run_iteration(
      self,
      observations: List[Union[ObservationType, TorchObservationType]],
      actions: List[Union[ActionType, TorchActionType]],
      actor_ids: List[ActorID],
  ) -> None:
      """Run a single training iterations of the behavioural cloning.
  
      :param observations: A list (w.r.t. the substeps/agents) of batched observations.
      :param actions: A list (w.r.t. the substeps/agents) of batched actions.
      :param actor_ids: A list (w.r.t. the substeps/agents) of the corresponding batched actor_ids.
      """
      self.policy.train()
      self.optimizer.zero_grad()
  
      # The actor ids of a given batch should be all the same. Thus we can debatch them.
      actor_ids = debatch_actor_ids(actor_ids)
  
      # Convert only actions to torch, since observations are converted in policy.compute_substep_policy_output method
      actions = convert_to_torch(
          actions, device=self.policy.device, cast=None, in_place=True
      )
      total_loss = self.loss.calculate_loss(
          policy=self.policy,
          observations=observations,
          actions=actions,
          actor_ids=actor_ids,
          events=self.imitation_events,
          action_logits=None,
      )
      total_loss.backward()
      self.optimizer.step()
  
      # Report additional policy-related stats
      for actor_id in actor_ids:
          l2_norm = sum(
              [
                  param.norm()
                  for param in self.policy.network_for(
                      actor_id
                  ).parameters()
              ]
          )
          grad_norm = compute_gradient_norm(
              self.policy.network_for(actor_id).parameters()
          )
  
          self.imitation_events.policy_l2_norm(
              step_id=actor_id.step_key,
              agent_id=actor_id.agent_id,
              value=l2_norm.item(),
          )
          self.imitation_events.policy_grad_norm(
              step_id=actor_id.step_key,
              agent_id=actor_id.agent_id,
              value=grad_norm,
          )
  
imports: from dataclasses import dataclass
  from typing import Dict, Union, Optional, List
  import torch
  from torch.optim import Optimizer
  from torch.utils.data import DataLoader
  from typing.io import BinaryIO
  from maze.core.agent.torch_policy import TorchPolicy
  from maze.core.annotations import override
  from maze.core.env.action_conversion import ActionType, TorchActionType
  from maze.core.env.observation_conversion import ObservationType, TorchObservationType
  from maze.core.env.structured_env import ActorID
  from maze.core.log_stats.log_stats import LogStatsAggregator, LogStatsLevel, get_stats_logger, increment_log_step
  from maze.perception.perception_utils import convert_to_torch
  from maze.train.trainers.common.evaluators.evaluator import Evaluator
  from maze.train.trainers.common.trainer import Trainer
  from maze.train.trainers.imitation.bc_algorithm_config import BCAlgorithmConfig
  from maze.train.trainers.imitation.bc_loss import BCLoss
  from maze.train.trainers.imitation.imitation_events import ImitationEvents
  from maze.train.utils.train_utils import compute_gradient_norm, debatch_actor_ids
label_desc: Use image node_id 6 for calling the BCTrainer obj's underlying member method code with example usage: obj._run_iteration(observations, actions, actor_ids) without return types