docstr: This function is mostly borrowed from the Reinforcement Learning example.
  See https://github.com/pytorch/examples/tree/master/reinforcement_learning
  The main difference is that it joins all probs and rewards from
  different observers into one list, and uses the minimum observer rewards
  as the reward of the current episode.
docstr_tok: ["This","function","is","mostly","borrowed","from","the","Reinforcement","Learning","example",".","See","https",":","\/\/github.com\/pytorch\/examples\/tree\/master\/reinforcement_learning","The","main","difference","is","that","it","joins","all","probs","and","rewards","from","different","observers","into","one","list",",","and","uses","the","minimum","observer","rewards","as","the","reward","of","the","current","episode","."]
code: def finish_episode(self):
      r"""
      This function is mostly borrowed from the Reinforcement Learning example.
      See https://github.com/pytorch/examples/tree/master/reinforcement_learning
      The main difference is that it joins all probs and rewards from
      different observers into one list, and uses the minimum observer rewards
      as the reward of the current episode.
      """
  
      # joins probs and rewards from different observers into lists
      R, probs, rewards = 0, [], []
      for ob_id in self.rewards:
          probs.extend(self.saved_log_probs[ob_id])
          rewards.extend(self.rewards[ob_id])
  
      # use the minimum observer reward to calculate the running reward
      min_reward = min(
          [sum(self.rewards[ob_id]) for ob_id in self.rewards]
      )
      self.running_reward = (
          0.05 * min_reward + (1 - 0.05) * self.running_reward
      )
  
      # clear saved probs and rewards
      for ob_id in self.rewards:
          self.rewards[ob_id] = []
          self.saved_log_probs[ob_id] = []
  
      policy_loss, returns = [], []
      for r in rewards[::-1]:
          R = r + GAMMA * R
          returns.insert(0, R)
      returns = torch.tensor(returns)
      returns = (returns - returns.mean()) / (returns.std() + self.eps)
      for log_prob, R in zip(probs, returns):
          policy_loss.append(-log_prob * R)
      self.optimizer.zero_grad()
      policy_loss = torch.cat(policy_loss).sum()
      policy_loss.backward()
      self.optimizer.step()
      return min_reward
  
imports: import numpy
  from itertools import count
  import torch
  import torch.distributed.rpc
  import torch.nn
  import torch.nn.functional
  import torch.optim
  from torch.distributed.rpc import RRef, rpc_sync, rpc_async, remote
  from torch.distributions import Categorical
  from torch.testing._internal.dist_utils import dist_init, worker_name
  from torch.testing._internal.distributed.rpc.rpc_agent_test_fixture import RpcAgentTestFixture
label_desc: Use image node_id 5 for calling the Agent obj's underlying member method code with example usage: obj.finish_episode() and returns: min_reward