docstr: ensemble predict:
  1. For actions of all actors, each critic will score them
     and normalize its scores;
  2. For each actor, will calculate its score by 
     average scores given by all critics
  3. choose action of the actor whose score is best
docstr_tok: ["ensemble","predict",":","1",".","For","actions","of","all","actors",",","each","critic","will","score","them","and","normalize","its","scores",";","2",".","For","each","actor",",","will","calculate","its","score","by","average","scores","given","by","all","critics","3.","choose","action","of","the","actor","whose","score","is","best"]
code: def ensemble_predict(self, obs):
      """ensemble predict:
      1. For actions of all actors, each critic will score them
         and normalize its scores;
      2. For each actor, will calculate its score by
         average scores given by all critics
      3. choose action of the actor whose score is best
      """
      actor_outputs = []
      for i in range(self.ensemble_num):
          actor_outputs.append(self.models[i].policy(obs))
      batch_actions = layers.concat(actor_outputs, axis=0)
      batch_obs = layers.expand(
          obs, expand_times=[self.ensemble_num, 1]
      )
  
      critic_outputs = []
      for i in range(self.ensemble_num):
          critic_output = self.models[i].value(batch_obs, batch_actions)
          critic_output = layers.unsqueeze(critic_output, axes=[1])
          critic_outputs.append(critic_output)
      score_matrix = layers.concat(critic_outputs, axis=1)
  
      # Normalize scores given by each critic
      sum_critic_score = layers.reduce_sum(
          score_matrix, dim=0, keep_dim=True
      )
      sum_critic_score = layers.expand(
          sum_critic_score, expand_times=[self.ensemble_num, 1]
      )
      norm_score_matrix = score_matrix / sum_critic_score
  
      actions_mean_score = layers.reduce_mean(
          norm_score_matrix, dim=1, keep_dim=True
      )
      best_score_id = layers.argmax(actions_mean_score, axis=0)
      best_score_id = layers.cast(best_score_id, dtype="int32")
      ensemble_predict_action = layers.gather(
          batch_actions, best_score_id
      )
      return ensemble_predict_action
  
file_path: PARL/examples/NeurIPS2018-AI-for-Prosthetics-Challenge/multi_head_ddpg.py
imports: import parl
  from parl import layers
  from copy import deepcopy
  from paddle import fluid
label_desc: Use image node_id 3 for calling the MultiHeadDDPG obj's underlying member method code with example usage: obj.ensemble_predict(obs) and returns: ensemble_predict_action