Skip to content
learn
  1. Learn
  2. Machine Learning
  3. Reinforcement Learning

Machine Learning ML-13.05

Policy gradients and actor-critic, PPO

Adjust the policy directly: REINFORCE, baselines that cut the noise, actor-critic methods and PPO's clipped objective, the workhorse behind RLHF.

Advanced 15 min Last reviewed

The big idea

Q-learning learns values and derives the policy from them: take the action with the highest Q. That works when you can list the actions and take a max. It breaks down for a robot arm choosing a continuous torque, and it gives only deterministic policies, where sometimes randomness is the best strategy (think of rock-paper-scissors).

Policy gradientReinforcement learning methods that represent the policy directly as a parameterized distribution over actions and adjust its parameters by gradient ascent on expected return. methods skip the detour. The policy is a network that outputs a probability for each action (or the mean and spread of a continuous action), and training nudges its weights to make actions that led to high return more likely. Think of a coach watching recordings of games. Plays that ended well get practised more, plays that ended badly get practised less, with no attempt to assign every position a precise score. Two refinements make this practical: compare each outcome with what was expected (a baseline, which becomes a learned critic), and never change the policy too much in one go (PPO's clip).

How it works

Step 1: REINFORCE

Write the policy as . The policy gradient theorem gives the direction that increases expected return :

REINFORCEThe basic Monte Carlo policy gradient algorithm (Williams, 1992): run an episode, then raise the log-probability of each action in proportion to the return that followed it. estimates this from whole episodes: play one, compute the return after each step, and move along . points in the direction that makes the chosen action more likely; scales the step. Good outcomes pull their actions up, bad ones push them down. No model of the environment and no max over actions are needed, so continuous actions are fine.

The weakness is noise. Returns vary a lot from episode to episode, often for reasons unrelated to the action (a lucky slip, a random opponent move). If every return is positive, every action taken gets reinforced, just some more than others, and it takes many episodes for the average to sort out which actions were actually good.

Step 2: Baselines and advantages

Subtract a baselineA reference value subtracted from the return in a policy gradient update; any baseline that does not depend on the action leaves the gradient unbiased while reducing its variance. from the return. As long as the baseline does not depend on the action, the expected gradient is unchanged, but its variance drops. The natural baseline is the state's value , which turns the weight into the advantageHow much better an action turned out than the state's expected value: A(s, a) = Q(s, a) - V(s), estimated in practice from returns or TD errors.:

Now the question for each action is not "was the outcome good?" but "was it better than usual from here?". A return of 7 from a state that usually yields 9 pushes the action down, not up.

Step 3: Actor-critic

Actor-critic The state feeds an actor, the policy, and a critic, the value function. The actor's action goes to the environment, which returns a reward and next state. The critic's estimates and the reward form a TD error, which flows back to the actor as its advantage signal and to the critic as its own update. action a r, s' advantage value update state s actor policy pi(a | s) critic value V(s) environment r, next state TD error r + gamma V(s') - V(s) Figure 1. The critic judges each step with a TD error; the actor uses that judgement as its advantage.

Actor-criticA reinforcement learning architecture with two learned parts: an actor (the policy) that chooses actions and a critic (a value function) whose estimates supply the advantage used to update the actor. methods learn the baseline as a second model, the critic, and often use its one-step TD error as the advantage instead of waiting for the full return:

That gives lower variance (one reward instead of a whole noisy future), updates every step instead of at the end of an episode, and some bias, because the critic's estimates are imperfect. Practical methods mix the two, using several steps of real rewards before trusting the critic.

Step 4: PPO

Policy gradients have a sharp edge: one step too large and the policy can collapse, after which the data it collects is useless for recovering. You would also like to reuse each batch of experience for several gradient steps, but the plain objective is only valid near the policy that collected the data. The PPO paper reports that optimizing it for several steps on the same data often leads to destructively large policy updates.

PPOProximal policy optimization: an actor-critic method that reuses each batch for several epochs while clipping the probability ratio between new and old policy, so no single update moves the policy far. (Schulman and colleagues, 2017) keeps the new policy close to the one that collected the data. With the probability ratio , it maximizes

with around 0.2.

PPO's clipped objective Two curves of the clipped objective against the ratio of new to old action probability, with dashed lines at 0.8 and 1.2. For a positive advantage the objective rises with the ratio until 1.2, then is flat. For a negative advantage the objective is flat below 0.8 and falls as the ratio grows above it. 0.40.60.811.21.41.6-1.5-1-0.500.51ratio pi_new / pi_oldobjective per unit advantage advantage > 0 advantage < 0 Figure 2. With epsilon 0.2, the objective stops rewarding a good action once it is 20 percent more likely, and stops punishing a bad one once it is 20 percent less likely.

For a good action (positive advantage), the objective grows as the action becomes more likely, but flattens once the ratio passes : there is no gain from pushing further, so the gradient is zero. For a bad action it stops at . The min makes it pessimistic: when the ratio moves the wrong way, the unclipped term applies in full. That gives PPO much of the safety of the older trust-region method (TRPO) with plain first-order optimization, and lets it run several epochs of minibatch updates on each batch. In the paper's comparison over seven simulated robot tasks, clipping with scored best (0.82 on their normalized scale), while the same objective with no clipping or penalty scored -0.39, worse than a random policy on average.

A full PPO agent is an actor-critic: a policy network trained with , a value network trained on returns, often with an entropy bonus to keep exploring.

Going deeper

Code: REINFORCE, a baseline, actor-critic and the clip

pg.pyruns with python3 + numpy
import numpy as np

# The corridor from ML-13.01: cells 0..6, start in 3, exits worth +1 (cell 0) and +10 (cell 6), moves
# slip with probability 0.1, gamma 0.9. The policy is a softmax over two logits per cell.
N, START, GAMMA = 7, 3, 0.9
pi = lambda th, s: np.exp(th[s] - th[s].max()) / np.exp(th[s] - th[s].max()).sum()

def episode(th, rng):
    s, traj = START, []
    while s not in (0, N - 1):
        a = rng.choice(2, p=pi(th, s)); s2 = s + (1 if a else -1) * (1 if rng.random() < 0.9 else -1)
        traj.append((s, a, {0: 1.0, N - 1: 10.0}.get(s2, 0.0), s2)); s = s2
    return traj

def value(th):                                          # exact V(start) by iterating the Bellman equation
    V = np.zeros(N)
    for _ in range(300):
        for s in range(1, N - 1):
            p = pi(th, s); q = [sum(pr * ({0: 1, N - 1: 10}.get(s2, 0) + GAMMA * V[s2] * (0 < s2 < N - 1))
                                    for pr, s2 in [(0.9, s + d), (0.1, s - d)]) for d in (-1, 1)]
            V[s] = p @ q
    return V[START]

def grad_logpi(th, s, a): g = np.zeros_like(th); g[s] = -pi(th, s); g[s, a] += 1; return g

def train(method, episodes=40, lr=0.05, seed=0):
    rng, th, V = np.random.default_rng(seed), np.zeros((N, 2)), np.zeros(N)
    for _ in range(episodes):
        traj, G = episode(th, rng), 0.0
        for t in reversed(range(len(traj))):
            s, a, r, s2 = traj[t]; G = r + GAMMA * G
            if method == "REINFORCE": adv = G                                    # raw return
            elif method == "REINFORCE + baseline": adv = G - V[s]; V[s] += 0.1 * adv
            else:                                                                # actor-critic: TD error
                adv = r + GAMMA * V[s2] * (0 < s2 < N - 1) - V[s]; V[s] += 0.1 * adv
            th += lr * GAMMA ** t * adv * grad_logpi(th, s, a)
    return value(th)

print(f"V(start): random policy {value(np.zeros((N, 2))):.2f}, always right {value(np.array([[0, 50.]] * N)):.2f}")
for m in ["REINFORCE", "REINFORCE + baseline", "actor-critic"]:
    v = [train(m, seed=sd) for sd in range(20)]
    print(f"{m:21s} after 40 episodes: V(start) mean {np.mean(v):.2f}, spread {np.std(v):.2f}, worst of 20 seeds {np.min(v):.2f}")

# PPO's clip: 30 gradient epochs on ONE batch of 10 episodes, with and without clipping the ratio.
rng = np.random.default_rng(1); th0 = np.zeros((N, 2)); batch = [x for _ in range(10) for x in episode(th0, rng)]
for clip in [None, 0.2]:
    th = th0.copy()
    for _ in range(30):
        g = np.zeros_like(th)
        for s, a, r, s2 in batch:
            ratio, adv = pi(th, s)[a] / pi(th0, s)[a], r + GAMMA * 5.0 * (0 < s2 < N - 1) - 5.0   # crude critic V = 5
            if clip is None or (adv > 0 and ratio < 1 + clip) or (adv < 0 and ratio > 1 - clip):
                g += ratio * adv * grad_logpi(th, s, a)                          # gradient of ratio x advantage
        th += 0.5 * g / len(batch)
    r_max = max(pi(th, s)[a] / pi(th0, s)[a] for s, a, _, _ in batch)
    print(f"{'no clip' if clip is None else 'clip 0.2':8s} largest ratio pi_new / pi_old {r_max:7.2f}")

Output

V(start): random policy 2.84, always right 7.56
REINFORCE             after 40 episodes: V(start) mean 6.27, spread 0.79, worst of 20 seeds 3.74
REINFORCE + baseline  after 40 episodes: V(start) mean 6.64, spread 0.18, worst of 20 seeds 6.34
actor-critic          after 40 episodes: V(start) mean 6.60, spread 0.19, worst of 20 seeds 6.32
no clip  largest ratio pi_new / pi_old    1.86
clip 0.2 largest ratio pi_new / pi_old    1.24

The corridor from RL fundamentals and MDPs , now starting in cell 3, with a softmax policy (two logits per cell). A random policy is worth 2.84 from the start; always moving right is worth 7.56. Each method trains for 40 episodes, 20 seeds each, with the same learning rate.

  • REINFORCE reaches a mean of 6.27, but with a spread of 0.79 across seeds and a worst seed at 3.74: some runs got unlucky early and reinforced the wrong moves.
  • Adding a baseline (a running estimate of each cell's value) gives a mean of 6.64, a spread of 0.18, and a worst seed of 6.34. Same expected gradient, much less noise.
  • Actor-critic with a one-step TD error is about as good here (6.60, spread 0.19), and it can update before an episode ends.
  • The clip in action. Thirty gradient epochs on one batch of 10 episodes: without clipping, the most-changed action becomes 1.86 times as likely as under the policy that collected the data. With it stops at 1.24. The objective gives no further reward past 1.2, so it stops there apart from the overshoot of the final step.

Fine-tuning a language model with human feedback is the same machinery at scale ( RLHF ). The policy is the language model, an action is the next token, an episode is one response, and the reward comes from a reward model trained on human preference comparisons, usually with a penalty for drifting too far from the original model. PPO was the standard optimizer for this step; its clip and the drift penalty both keep the model from changing so much at once that it starts exploiting the reward model.

Trade-offs

OptionWins whenLoses when
Value-based (DQN) Sample-efficient with replay; strong on discrete actions No continuous actions; deterministic greedy policies
REINFORCE Simplest policy gradient; unbiased; any action space High variance; waits for full episodes; on-policy, so data is used once
Actor-critic Lower variance; updates every step Two models to tune; the critic's errors bias the actor
PPO Stable; reuses each batch for several epochs; simple to implement Still on-policy and data-hungry; sensitive to advantage normalization and other details

Common mistakes

  • Using raw returns without a baseline, then blaming the learning rate for unstable training.
  • Letting the baseline depend on the action, which biases the gradient.
  • Reusing a batch for many epochs without PPO's clip or a KL penalty, so the policy jumps far from the data.
  • Letting the policy's entropy collapse early; once it is near-deterministic it stops exploring.
  • Reading the clipped objective as the agent's performance. It is a training signal; track returns.

Where you will see this

PPO and its relatives are a common default for training agents in simulation: robot locomotion, game-playing agents and control tasks with continuous actions. In language models, PPO was the optimizer of the original RLHF pipelines, and newer preference-tuning methods are usually described by how they differ from it ( RLHF ). Wherever actions are continuous or the best policy should stay random, policy gradients are the tool of choice.

Check yourself

  1. In REINFORCE, what does the term grad log pi(a_t | s_t) times G_t do?

    Show answer

    B. Moves the parameters to make the chosen action more likely, scaled by the return that followed grad log pi points toward making a_t more likely; G_t sets how strongly (and, with a baseline, in which direction).

  2. Why does subtracting a baseline V(s) not bias the policy gradient?

    Show answer

    B. Because a baseline that does not depend on the action has zero expected effect on the gradient, while it reduces variance The expected value of grad log pi times anything that does not depend on the action is zero, so only the variance changes. In the code it cut the spread across seeds from 0.79 to 0.18.

  3. PPO with epsilon 0.2. An action had advantage +3 and its probability ratio is already 1.3. What is the gradient of the clipped objective with respect to that ratio?

    Show answer

    B. 0, because the clipped term is the minimum and it is flat beyond 1.2 For a positive advantage the objective is min(r A, 1.2 A). Beyond 1.2 the second term is smaller and constant, so there is no incentive to push the ratio further.

  4. What is the main advantage of actor-critic over plain REINFORCE?

    Show answer

    B. The critic's TD error gives a lower-variance learning signal and allows updates before the episode ends Using one reward plus a bootstrapped value is much less noisy than a full return, at the cost of some bias from the critic.

  5. In RLHF with PPO, what plays the role of the action?

    Show answer

    B. Each next token the language model generates The model is the policy and generating a token is an action; a response is an episode scored by the reward model.

Recap

  • Policy gradients adjust the policy directly, which handles continuous actions and stochastic policies.
  • REINFORCE raises the log-probability of each action in proportion to the return that followed; it is unbiased but noisy.
  • A baseline, ideally V(s), turns returns into advantages and cuts variance without adding bias; actor-critic learns it as a critic and uses TD errors.
  • PPO clips the probability ratio to about 1 plus or minus 0.2, so each batch can be reused for several epochs without destructive updates.
  • PPO was the optimizer behind the original RLHF pipelines for language models.

Get new lessons by email

Get new posts on backend and AI internals. No spam, unsubscribe anytime.

Your email is only used to send new posts. Privacy