docstr: 使用DQN算法更新self.model的value网络
          
code: def learn(self, obs, action, reward, next_obs, terminal):
      """使用DQN算法更新self.model的value网络"""
      # 获取Q预测值
      pred_values = self.model(obs)
      action_dim = pred_values.shape[-1]
      action = paddle.squeeze(action, axis=-1)
      # 将action转onehot向量，比如：3 => [0,0,0,1,0]
      action_onehot = paddle.nn.functional.one_hot(
          action, num_classes=action_dim
      )
      # 下面一行是逐元素相乘，拿到action对应的 Q(s,a)
      # 比如：pred_value = [[2.3, 5.7, 1.2, 3.9, 1.4]], action_onehot = [[0,0,0,1,0]]
      pred_value = pred_values * action_onehot
      #  ==> pred_value = [[3.9]]
      pred_value = paddle.sum(pred_value, axis=1, keepdim=True)
  
      # 从target_model中获取 max Q' 的值，用于计算target_Q
      with paddle.no_grad():
          max_v = self.target_model(next_obs).max(1, keepdim=True)
          target = reward + (1 - terminal) * self.gamma * max_v
      loss = self.mse_loss(pred_value, target)
  
      # 计算 Q(s,a) 与 target_Q的均方差，得到loss
      self.optimizer.clear_grad()
      loss.backward()
      self.optimizer.step()
      return loss
  
file_path: PARL/examples/tutorials/parl2_dygraph/lesson3/dqn/algorithm.py
imports: import copy
  import parl
  import paddle
label_desc: Use image node_id 3 for calling the DQN obj's underlying member method code with example usage: obj.learn(obs, action, reward, next_obs, terminal) and returns: loss