docstr: Args:
      obs: An float32 tensor of shape ([B] + observation_space).
           E.g. [B, C, H, W] in atari.
      actions: An int64 tensor of shape [B].
      advantages: A float32 tensor of shape [B].
      target_values: A float32 tensor of shape [B].
      learning_rate: float scalar of leanring rate.
      entropy_coeff: float scalar of entropy coefficient.
docstr_tok: ["Args",":","obs",":","An","float32","tensor","of","shape","(","[","B","]","+","observation_space",")",".","E.g",".","[","B",",","C",",","H",",","W","]","in","atari",".","actions",":","An","int64","tensor","of","shape","[","B","]",".","advantages",":","A","float32","tensor","of","shape","[","B","]",".","target_values",":","A","float32","tensor","of","shape","[","B","]",".","learning_rate",":","float","scalar","of","leanring","rate",".","entropy_coeff",":","float","scalar","of","entropy","coefficient","."]
code: def learn(
      self,
      obs,
      actions,
      advantages,
      target_values,
      learning_rate,
      entropy_coeff,
  ):
      """
      Args:
          obs: An float32 tensor of shape ([B] + observation_space).
               E.g. [B, C, H, W] in atari.
          actions: An int64 tensor of shape [B].
          advantages: A float32 tensor of shape [B].
          target_values: A float32 tensor of shape [B].
          learning_rate: float scalar of leanring rate.
          entropy_coeff: float scalar of entropy coefficient.
      """
      # shape: [B, act_dim]
      logits = self.model.policy(obs)
      act_dim = logits.shape[-1]
      actions_onehot = F.one_hot(actions, act_dim)
      # [B, act_dim] --> [B]
      actions_log_probs = paddle.sum(
          F.log_softmax(logits) * actions_onehot, axis=-1
      )
      # The policy gradient loss
      pi_loss = -1.0 * paddle.sum(actions_log_probs * advantages)
  
      # The value function loss
      values = self.model.value(obs)
      delta = values - target_values
      vf_loss = 0.5 * paddle.sum(paddle.square(delta))
  
      # The entropy loss (We want to maximize entropy, so entropy_ceoff < 0)
      # Using the Categorical just for calculating the entropy.
      # See  https://github.com/PaddlePaddle/Paddle/blob/release/2.0/python/paddle/distribution.py for detail
      policy_distribution = Categorical(logits)
      policy_entropy = policy_distribution.entropy()
      entropy = paddle.sum(policy_entropy)
  
      total_loss = (
          pi_loss
          + vf_loss * self.vf_loss_coeff
          + entropy * entropy_coeff
      )
      self.optimizer.set_lr(learning_rate)
      total_loss.backward()
      self.optimizer.step()
      self.optimizer.clear_grad()
      return total_loss, pi_loss, vf_loss, entropy
  
file_path: PARL/parl/algorithms/paddle/a2c.py
imports: import parl
  import paddle
  import paddle.nn.functional
  from paddle.distribution import Categorical
  from parl.utils.utils import check_model_method
  import numpy
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, learning_rate, entropy_coeff) and returns: total_loss,  pi_loss,  vf_loss,  entropy