class_docstr: Agent of Atari env.
  
  Args:
      algorithm (`parl.Algorithm`): algorithm to be used in this agent.
      act_dim (int): action space dimension
      total_step (int): total epsilon decay steps
      start_lr (float): initial learning rate
      update_target_step (int): target network update frequency
docstr: Update model with an episode data
  
  Args:
      obs (np.float32): shape of (batch_size, obs_dim)
      act (np.int32): shape of (batch_size)
      reward (np.float32): shape of (batch_size)
      next_obs (np.float32): shape of (batch_size, obs_dim)
      terminal (np.float32): shape of (batch_size)
  
  Returns:
      loss (float)
docstr_tok: ["Update","model","with","an","episode","data","Args",":","obs","(","np.float32",")",":","shape","of","(","batch_size",",","obs_dim",")","act","(","np.int32",")",":","shape","of","(","batch_size",")","reward","(","np.float32",")",":","shape","of","(","batch_size",")","next_obs","(","np.float32",")",":","shape","of","(","batch_size",",","obs_dim",")","terminal","(","np.float32",")",":","shape","of","(","batch_size",")","Returns",":","loss","(","float",")"]
code: def learn(self, obs, act, reward, next_obs, terminal):
      """Update model with an episode data
  
      Args:
          obs (np.float32): shape of (batch_size, obs_dim)
          act (np.int32): shape of (batch_size)
          reward (np.float32): shape of (batch_size)
          next_obs (np.float32): shape of (batch_size, obs_dim)
          terminal (np.float32): shape of (batch_size)
  
      Returns:
          loss (float)
      """
      if self.global_update_step % self.update_target_step == 0:
          self.alg.sync_target()
  
      self.global_update_step += 1
  
      reward = np.clip(reward, -1, 1)
      act = np.expand_dims(act, axis=-1)
      reward = np.expand_dims(reward, axis=-1)
      terminal = np.expand_dims(terminal, axis=-1)
  
      obs = torch.tensor(obs, dtype=torch.float, device=self.device)
      next_obs = torch.tensor(
          next_obs, dtype=torch.float, device=self.device
      )
      act = torch.tensor(act, dtype=torch.long, device=self.device)
      reward = torch.tensor(
          reward, dtype=torch.float, device=self.device
      )
      terminal = torch.tensor(
          terminal, dtype=torch.float, device=self.device
      )
  
      loss = self.alg.learn(obs, act, reward, next_obs, terminal)
  
      # learning rate decay
      for param_group in self.alg.optimizer.param_groups:
          param_group["lr"] = max(
              self.lr_scheduler.step(1), self.lr_end
          )
  
      return loss
  
file_path: PARL/benchmark/torch/dqn/agent.py
imports: import parl
  import numpy
  import torch
  from parl.utils.scheduler import LinearDecayScheduler
label_desc: Use image node_id 4 for calling the AtariAgent obj's underlying member method code with example usage: obj.learn(obs, act, reward, next_obs, terminal) and returns: loss