rl-alignment-tabular-q-learning learned a Q-VALUE table directly, then acted greedily with respect to it. Policy gradient methods take a different route: train the POLICY (the action-selection strategy itself) directly via gradient ascent on expected return, using a beautifully simple update rule: "increase the log-probability of actions that led to good outcomes, decrease it for actions that led to bad ones." This question builds both pieces: the outcome signal (discounted_returns) and the loss that turns it into a gradient (policy_gradient_loss).
Implement discounted_returns (the REINFORCE return at every timestep, computed efficiently via one backward pass, correctly resetting at episode boundaries) and policy_gradient_loss (the basic policy-gradient loss).
discounted_returns(rewards, gamma, dones)[t] = rewards[t] + gamma * (1 - dones[t]) * discounted_returns[t+1], with the sequence treated as ending after the last index.dones[t] = 1 means episode t is the LAST step of an episode: the return computation must NOT carry any value across that boundary into the next episode.policy_gradient_loss(log_probs, advantages) returns -mean(log_probs * advantages).log_probs for an action with a POSITIVE advantage must strictly decrease the loss (the correct gradient-ascent direction).Open one at a time. Each gives away a little more than the last.
discounted_returns is computed BACKWARD, from the last timestep to the first, maintaining one running total: running = rewards[t] + gamma * (1 - dones[t]) * running: the (1 - dones[t]) factor is what zeroes out the carry-over exactly at an episode boundary.
policy_gradient_loss doesn't need discounted_returns internally: it's a general-purpose function that works with ANY advantage-like signal, whether that's raw returns from this exercise, or GRPO's group-normalized advantage, or GAE's more sophisticated estimate (rl-alignment-generalized-advantage-estimation).
No results yet
Run your code to check it against the examples, or submit to run every test.