docstr: use the policy model to sample actions
  
  Args:
      obs (torch tensor): observation, shape([B] + shape of obs_n[agent_index])
      use_target_model (bool): use target_model or not
  
  Returns:
      act (torch tensor): action, shape([B] + shape of act_n[agent_index]),
          noted that in the discrete case we take the argmax along the last axis as action
docstr_tok: ["use","the","policy","model","to","sample","actions","Args",":","obs","(","torch","tensor",")",":","observation",",","shape","(","[","B","]","+","shape","of","obs_n","[","agent_index","]",")","use_target_model","(","bool",")",":","use","target_model","or","not","Returns",":","act","(","torch","tensor",")",":","action",",","shape","(","[","B","]","+","shape","of","act_n","[","agent_index","]",")",",","noted","that","in","the","discrete","case","we","take","the","argmax","along","the","last","axis","as","action"]
code: def sample(self, obs, use_target_model=False):
      """use the policy model to sample actions
  
      Args:
          obs (torch tensor): observation, shape([B] + shape of obs_n[agent_index])
          use_target_model (bool): use target_model or not
  
      Returns:
          act (torch tensor): action, shape([B] + shape of act_n[agent_index]),
              noted that in the discrete case we take the argmax along the last axis as action
      """
      if use_target_model:
          policy = self.target_model.policy(obs)
      else:
          policy = self.model.policy(obs)
  
      # add noise for action exploration
      if self.continuous_actions:
          random_normal = torch.randn(size=policy[0].shape).to(
              self.device
          )
          action = policy[0] + torch.exp(policy[1]) * random_normal
          action = torch.tanh(action)
      else:
          uniform = torch.rand_like(policy)
          soft_uniform = torch.log(-1.0 * torch.log(uniform)).to(
              self.device
          )
          action = F.softmax(policy - soft_uniform, dim=-1)
  
      return action
  
file_path: PARL/parl/algorithms/torch/maddpg.py
imports: import parl
  import torch
  import torch.nn
  import torch.nn.functional
  from parl.utils.utils import check_model_method
  from copy import deepcopy
label_desc: Use image node_id 3 for calling the MADDPG obj's underlying member method code with example usage: obj.sample(obs, use_target_model) and returns: action