code: def ppo_loss_given_predictions(log_probab_actions_new,
                                 log_probab_actions_old,
                                 predicted_values,
                                 padded_actions,
                                 padded_rewards,
                                 reward_mask,
                                 gamma=0.99,
                                 lambda_=0.95,
                                 epsilon=0.2):
    
    B, T = padded_rewards.shape  # pylint: disable=invalid-name
    assert (B, T) == padded_actions.shape
    assert (B, T) == reward_mask.shape
  
    _, _, A = log_probab_actions_old.shape  # pylint: disable=invalid-name
    assert (B, T + 1, 1) == predicted_values.shape
    assert (B, T + 1, A) == log_probab_actions_old.shape
    assert (B, T + 1, A) == log_probab_actions_new.shape
  
    # (B, T)
    td_deltas = deltas(
        np.squeeze(predicted_values, axis=2),  # (B, T+1)
        padded_rewards,
        reward_mask,
        gamma=gamma)
  
    # (B, T)
    advantages = gae_advantages(
        td_deltas, reward_mask, lambda_=lambda_, gamma=gamma)
  
    # (B, T)
    ratios = compute_probab_ratios(log_probab_actions_new,
                                   log_probab_actions_old,
                                   padded_actions,
                                   reward_mask)
    assert (B, T) == ratios.shape
  
    # (B, T)
    objective = clipped_objective(
        ratios, advantages, reward_mask, epsilon=epsilon)
    assert (B, T) == objective.shape
  
    # ()
    average_objective = np.sum(objective) / np.sum(reward_mask)
  
    # Loss is negative objective.
    return -average_objective
docs: PPO objective, with an eventual minus sign, given predictions.