docstr: Update model with policy gradient algorithm
  
  Args:
      obs (paddle tensor): shape of (batch_size, obs_dim)
      action (paddle tensor): shape of (batch_size, 1)
      reward (paddle tensor): shape of (batch_size, 1)
  
  Returns:
      loss (paddle tensor): shape of (1)
code: def learn(self, obs, action, reward):
      """Update model with policy gradient algorithm
  
      Args:
          obs (paddle tensor): shape of (batch_size, obs_dim)
          action (paddle tensor): shape of (batch_size, 1)
          reward (paddle tensor): shape of (batch_size, 1)
  
      Returns:
          loss (paddle tensor): shape of (1)
  
      """
      prob = self.model(obs)
      log_prob = Categorical(prob).log_prob(action)
      loss = paddle.mean(-1 * log_prob * reward)
  
      self.optimizer.clear_grad()
      loss.backward()
      self.optimizer.step()
      return loss
  
file_path: PARL/parl/algorithms/paddle/policy_gradient.py
imports: import parl
  import paddle
  from paddle.distribution import Categorical
  from parl.utils.utils import check_model_method
label_desc: Use image node_id 3 for calling the PolicyGradient obj's underlying member method code with example usage: obj.learn(obs, action, reward) and returns: loss