docstr: input:
  batch: dict(o, s, u, r, u_onehot, avail_u, padded, isover)
  epsilon: e-greedy discount
docstr_tok: ["input",":","batch",":","dict","(","o",",","s",",","u",",","r",",","u_onehot",",","avail_u",",","padded",",","isover",")","epsilon",":","e-greedy","discount"]
code: def learn(self, batch, epsilon=None):
      """input:
      batch: dict(o, s, u, r, u_onehot, avail_u, padded, isover)
      epsilon: e-greedy discount
      """
      # different episode has different avail transition length
      tr_num = self._get_avail_transitions_num(batch["isover"])
      for key in batch.keys():
          # cut batch data's episode length
          batch[key] = batch[key][:, :tr_num]
  
      # get actor input and critic input
      batch["actor_inputs"] = self._get_actor_inputs(batch)
      (
          batch["critic_inputs"],
          batch["critic_inputs_next"],
      ) = self._get_critic_inputs(batch)
  
      # change batch data to torch tensor
      for key in batch.keys():
          if key == "u":
              batch[key] = torch.tensor(
                  batch[key], dtype=torch.long
              ).to(device)
          else:
              batch[key] = torch.tensor(
                  batch[key], dtype=torch.float32
              ).to(device)
  
      self.alg.learn(batch, epsilon)
  
      if (
          self.train_steps > 0
          and self.train_steps % self.config["target_update_cycle"] == 0
      ):
          self.alg.sync_target()
      self.train_steps += 1
  
file_path: PARL/benchmark/torch/coma/sc2_agent.py
imports: import numpy
  import parl
  import torch
  from torch.distributions import Categorical
label_desc: Use image node_id 8 for calling the Agents obj's underlying member method code with example usage: obj.learn(batch, epsilon) without return types