code: def learn(
      self, obs, actions, advantages, target_values, lr, entropy_coeff
  ):
      logits = self.model.policy(obs)
      act_dim = logits.shape[-1]
      actions_onehot = F.one_hot(actions, act_dim)
      actions_log_probs = torch.sum(
          F.log_softmax(logits, dim=1) * actions_onehot, dim=-1
      )
      # The policy gradient loss
      pi_loss = -1.0 * torch.sum(actions_log_probs * advantages)
  
      # The value function loss
      values = self.model.value(obs)
      delta = values - target_values
      vf_loss = 0.5 * torch.sum(torch.square(delta))
  
      policy_distri = Categorical(logits=logits)
      # The entropy loss (We want to maximize entropy, so entropy_ceoff < 0)
      policy_entropy = policy_distri.entropy()
      entropy = torch.sum(policy_entropy)
  
      total_loss = (
          pi_loss
          + vf_loss * self.vf_loss_coeff
          + entropy * entropy_coeff
      )
  
      for param_group in self.optimizer.param_groups:
          param_group["lr"] = lr
  
      total_loss.backward()
      # clip the grad
      torch.nn.utils.clip_grad_norm_(
          self.model.parameters(), max_norm=40.0
      )
      self.optimizer.step()
      self.optimizer.zero_grad()
  
      return total_loss, pi_loss, vf_loss, entropy
  
file_path: PARL/parl/algorithms/torch/a2c.py
imports: import torch
  from torch.distributions import Categorical
  import torch.nn.functional
  import torch.optim
  import numpy
  import parl
  from parl.utils.utils import check_model_method
label_desc: Use image node_id 2 for calling the A2C obj's underlying member method code with example usage: obj.learn(obs, actions, advantages, target_values, lr, entropy_coeff) and returns: total_loss,  pi_loss,  vf_loss,  entropy