Part II · Deep RL · Chapter 8
Actor-critic and advantage estimation
A learned critic to cut variance. Advantages, n-step returns, and GAE.
You are learning to balance a pole on a cart. You last 140 steps, then the pole falls. REINFORCE (Chapter 7) now goes back over all 140 actions and nudges each one by the same kind of signal: “from here on, you collected this much reward.” Step 12, where you made a fine correction, and step 135, where you made the fatal lurch, get credit through numbers that differ only because one is computed over a longer stretch of the future. To learn which steps were good, you need many, many episodes, because only averaging can separate the two.
Now imagine a coach standing next to you. The coach never touches the cart, but after every single step says “that went better than I expected” or “that went worse.” Step 12: better. Step 135: much worse. You would learn far faster. This chapter builds that coach. It is a second learned function, the critic, that predicts how well things will go from each state, so that every step can be judged against a prediction instead of against the noisy return of the whole episode. The policy being trained is called the actor. Together they make an actor-critic method.
This is not a modern idea. In 1983, Barto, Sutton and Anderson balanced a simulated pole with an “adaptive critic element” that learned to predict trouble and turned that prediction into an internal reward for a separate action-selecting element. The cartpole.py file you will use in the lab simulates the same physics they used. What is modern is the question this chapter spends most of its time on: given a critic that is wrong (and it always is), how should you combine its predictions with the real rewards you observed? The answer, generalized advantage estimation (GAE), has one knob, . It is the advantage estimator inside PPO (Chapter 9) and inside PPO-based RLHF for language models (Chapter 12).
Where REINFORCE leaves us
From Chapter 7, the policy gradient has this shape:
The score says which way to move to make more likely. The weight says how much, and whether to make it more likely or less. Everything in this chapter is about choosing . Here is the menu (the GAE paper by Schulman et al. opens with this same list):
| Weight | Name | Unbiased? | Needs |
|---|---|---|---|
| total return of the episode | yes | nothing | |
| reward-to-go | yes | nothing | |
| reward-to-go with a baseline | yes | a baseline | |
| action value | yes | the true | |
| advantage | yes | the true | |
| TD error | yes | the true |
Chapter 7 took you down to the third row. You saw that a baseline can be subtracted without adding bias, and that a good baseline cuts variance a lot. You also saw that the best simple baseline is close to the expected return from , which is . So the third row with the best baseline is . That is already an estimate of the advantage, the fifth row. This chapter makes that connection explicit and then goes further. In the last three rows the weights are “true” functions we don’t have, so we will learn them, and then decide how much to trust what we learned.
The advantage: was that action better than usual?
Recall the two value functions from Chapter 3. is the expected return if you start in and follow . is the expected return if you start in , take action once, and then follow . The advantage is their difference:
In words: how much better is action than what the policy does in on average? Positive means “better than my usual”, negative means “worse than my usual”.
A worked example
Take one state with three actions. The policy picks them with probabilities , and their action values are . Then
and the advantages are .
Two things to notice:
- The advantages average to zero under the policy: . This always holds, because is by definition the -weighted average of . So the advantage is the action value with its “typical level” removed.
- The most likely action has a negative advantage. The policy picks action 1 half the time, yet action 2 is much better. A gradient step weighted by lowers the probability of action 1 every time it is sampled and raises action 2’s whenever it is sampled. That is exactly the correction you want.
Now compare with weighting by instead. All three -values are . Every sampled action gets pushed up, just by different amounts. On average the pushes still come out right: is plus the constant , and a constant added to every weight averages out (shown in the box below). But single samples are misleading. When action 1 is drawn (half the time), the update pushes it up with weight 1, although it should go down. When action 3 is drawn (20% of the time), the weight is 0 and nothing happens, although action 3 should go down too. So on 70% of samples the update is wrong or useless, and only averaging over many samples sorts it out. That is variance.
Quick check In some state, π picks action a₁ with probability 0.9 and a₂ with probability 0.1. Q(s, a₁) = 5 and Q(s, a₂) = 10. What is the advantage of a₁?
V(s) = 0.9·5 + 0.1·10 = 5.5, so A(s, a₁) = 5 − 5.5 = −0.5. A good action can still have a negative advantage if the policy has a better option available. Each time a₁ is sampled, an advantage-weighted update lowers its probability slightly.
The critic: learning V
To use advantages we have to estimate them, and the cheapest route needs only one learned function, the state value. Here is why. You never need as a separate function, because you watched what actually happened after : you got and landed in . The one-sample estimate of is right there. So the plan is:
- Learn , a network with parameters . This is the critic.
- Use it to turn observed rewards into advantage estimates for the actor .
Learning is a regression problem you have already solved twice. In Chapter 5 you estimated values by Monte Carlo (target ) and by TD(0) (target ). In Chapter 6 you did it with a neural network and the semi-gradient rule: compute a target , treat it as a constant, and minimize
With the TD(0) target, the gradient step on this loss is , where
is the TD error. Remember this quantity. In the next section it becomes the actor’s weight too.
Why learn rather than ? is a function of the state only, so it is a smaller object to learn, and it does not need one output per action. With two actions (CartPole) that hardly matters. With a vocabulary of 100,000 tokens it matters a lot: Chapter 6 explained why per-action value methods are rarely used for LLMs.
The TD error is a one-sample advantage
Here is the key fact. Suppose for a moment the critic is perfect, . Average the TD error over what can happen after , namely the reward and the next state :
The middle equality is the Bellman equation for from Chapter 3: the action value is the expected immediate reward plus the discounted value of where you land. So with a perfect critic, the TD error is an unbiased one-sample estimate of the advantage. It is noisy only through one step of randomness (one reward, one transition). Compare , which is noisy through every reward and every action for the rest of the episode.
There is a catch, and it is the theme of the rest of the chapter. The critic is not perfect. With , is a biased advantage estimate. If the critic wrongly thinks is a great state, every action leading there looks great.
A running example
We will use one short episode for the rest of the chapter, so you can check every formula by hand. It has four steps and a single reward of 1 at the very end (think of a four-token answer that is graded correct). Take . The critic’s values along the way are shown below. is terminal, so .
| 0 | 0 | 0.5 | 0.4 | |
| 1 | 0 | 0.4 | 0.8 | |
| 2 | 0 | 0.8 | 0.6 | |
| 3 | 1 | 0.6 | 0 (terminal) |
Read the critic’s values as its running forecast of success. It starts at 50%. After step 0 it drops to 40%, so that move looked slightly bad. Step 1 raised it to 80%, which looks like a good move. Step 2 lowered it to 60%. Step 3 got the reward, a pleasant surprise of 0.4 relative to the forecast. The TD errors are exactly these changes of mind: they blame steps 0 and 2 a little and credit steps 1 and 3.
Monte Carlo sees it differently. The return from every step is , so : every step gets positive credit, because the episode succeeded. Which assignment is right? It depends on whether the critic is right. If its forecasts are accurate, the TD errors point at the moves that actually changed the odds. If its forecasts are garbage, the TD errors are garbage too, and Monte Carlo is the only honest signal.
Quick check Your critic happens to equal V^π exactly. Is the TD error δₜ = rₜ + γV(sₜ₊₁) − V(sₜ) equal to the advantage A^π(sₜ, aₜ)?
With a perfect critic, the expectation of δₜ given (sₜ, aₜ) is exactly A^π(sₜ, aₜ). Any single sample can still differ, because rₜ and sₜ₊₁ are random. So δₜ is unbiased but noisy, with only one step of noise.
A first actor-critic
You now have enough for a complete algorithm. The actor’s weight is , the critic learns by TD(0), and both update after every step:
One-step actor-critic (online)
Initialise actor parameters θ and critic parameters φ
for each episode:
s ← initial state
while s is not terminal:
sample a ~ π_θ(· | s); take it; observe r and s′
δ ← r + γ V_φ(s′) − V_φ(s) # V_φ(s′) = 0 if s′ is terminal
φ ← φ + α_φ · δ · ∇_φ V_φ(s) # critic: semi-gradient TD(0)
θ ← θ + α_θ · δ · ∇_θ log π_θ(a | s) # actor: policy gradient, Â = δ
s ← s′
(Sutton & Barto’s version also multiplies the actor step by , which is what the discounted objective strictly requires. Almost every deep-RL implementation drops that factor.)
Compared with REINFORCE, this algorithm:
- learns during the episode. It needs no complete return, so it works for very long or never-ending tasks.
- has much lower variance per update, because each weight involves one step of randomness.
- is biased whenever the critic is wrong, which is always, especially early in training.
- has two learners chasing each other. As the actor changes, changes, so the critic’s target moves. This is generalized policy iteration from Chapter 4: the critic does approximate policy evaluation and the actor does approximate policy improvement, interleaved at a fine grain.
The bias is the real problem. One step of real reward and everything else from the critic is a lot of trust to put in a network that started out as random weights. You want a way to use more real rewards when the critic is untrustworthy, and fewer when it is good.
n-step advantages: a dial between TD and Monte Carlo
The middle ground is to look ahead real steps and then hand over to the critic. You met this dial in Chapter 5 as a target for learning values (written there). Here it becomes an advantage estimate for the actor. The n-step return is
and the n-step advantage is . If the episode ends before step , use the rewards up to the end and . That is just the Monte Carlo return.
There is a neat identity that makes this easy to compute and reason about. The n-step advantage is the discounted sum of the next TD errors:
∂ Why the n-step advantage is a sum of TD errors
Write out the sum and group terms. With :
Shift the index in the middle sum (): it becomes . The last sum is . They share the terms , which cancel, leaving from the middle sum and from the last. So
Every intermediate value appears once with a plus sign (as “next state” of one step) and once with a minus sign (as “current state” of the next step), so the intermediate values all cancel.
Two limits:
- : , the one-step TD error.
- (or reaching past the end of the episode): , Monte Carlo with a baseline. This is REINFORCE with the critic as its baseline.
In the running example with and : . Check against the definition: . Both give 0.3.
Why trades bias for variance. Look at where the critic enters : only through and . The first is a state-only baseline and is harmless (more on this below). The second is discounted by and, if the critic is wrong, contributes bias. Larger pushes the critic further away and reduces its influence. But each extra step adds one more random reward and one more random action to the sum, which adds variance. Small : low variance, high bias. Large : low bias, high variance.
The A3C algorithm of Mnih et al. (2016) used exactly this. Each worker ran the policy for up to steps, then gave every state in that segment the longest n-step return available inside the segment (5 steps for the first state, 4 for the next, and so on).
Generalized advantage estimation
Which should you use? There is no single right answer: the best depends on how good the critic is, and that changes during training. GAE (Schulman et al., 2015) avoids the choice. It takes all the n-step estimates and averages them with exponentially decaying weights:
The weights sum to one, so this is a proper weighted average. Plug in the TD-error form of each and the average collapses to something very simple.
∂ From the average of n-step advantages to the sum of TD errors
Substitute :
Swap the order of summation. A given appears in every with , so
The inner sum is a geometric series: , valid for . The case follows as a limit, or directly from the Monte Carlo identity below.
Finite episodes. If the episode ends at step , define for (no rewards, and ). Every with is then the same Monte Carlo advantage, the formula above still holds, and the sum stops at .
The two ends of the dial:
- : only the term survives. , the one-step TD error. Lowest variance, and the most trust in the critic.
- : by the telescoping identity. This is Monte Carlo with the critic as a baseline: no trust in the critic beyond its role as a baseline, and the most variance. (Exercise 8.3 asks you to prove it.)
Computing it: one backward pass
You never evaluate the infinite sum. Peel off the first term and the rest is the same quantity one step later:
So you start at the end of the rollout and walk backward. This is an exponential filter run in reverse time: the sequence of TD errors goes in, and each output is the current input plus a decayed copy of the next output. How far ahead does it look? The weights fall by a factor in about steps. PPO’s default settings, and , give , a look-ahead of roughly 17 steps.
The running example with (), walking backward from the last step:
All the estimators side by side:
| () | 2-step | GAE, | MC, | |
|---|---|---|---|---|
| 0 | ||||
| 1 | ||||
| 2 | ||||
| 3 |
Look at step 2. One-step TD blames it (the critic’s forecast dropped). Monte Carlo credits it (the episode succeeded). GAE with sits in between and calls it neutral. The last row is the same in every column, because from step 3 only one step remains, so every estimator sees the same thing.
Episode boundaries and the critic’s target
In practice a rollout is a block of consecutive steps that can contain the end of one episode and the start of the next. The recursion must not leak advantage across that boundary. With when the episode ended at step :
GAE also hands you the critic’s regression target for free. is the λ-return, an exponentially weighted average of all the n-step returns. If you have read about TD() in Sutton & Barto (chapter 12), this is the same object: GAE is TD()‘s weighting applied to advantages. Using as the critic’s target means the critic and actor see the same blend of real rewards and bootstrapped values.
compute_gae(rewards, values, last_value, dones, γ, λ): # arrays of length T
A_next ← 0
for t = T−1 down to 0:
V_next ← last_value if t = T−1 else values[t+1]
δ ← rewards[t] + γ · V_next · (1 − dones[t]) − values[t]
A_next ← δ + γ · λ · (1 − dones[t]) · A_next
advantages[t] ← A_next
returns ← advantages + values # λ-returns: the critic's targets
return advantages, returns
Here last_value is the critic’s value of the state reached after the final row, . When the rollout stops in the middle of an episode (dones[T−1] = 0), the last step has no next row to read a value from, so it bootstraps from last_value instead.
This is Task 2 of the lab, and it runs in time.
Quick check With γ = 0.99 and λ = 0.9, roughly how many future TD errors contribute substantially to a GAE estimate?
The weights are (γλ)^l with γλ = 0.891. They shrink by a factor e every 1/(1 − 0.891) ≈ 9 steps, so the estimate mostly reflects the next ten or so TD errors. Raising λ to 0.95 or 0.99 lengthens this window.
Seeing the trade-off
The claims so far are qualitative: small trusts the critic, large trusts the rewards, and the right choice depends on how good the critic is. The demo below lets you measure all of this exactly.
The world. Nothing is learned in this demo. The policy is fixed, and the only question is how well each estimator measures that policy’s advantages. A walker starts at height and takes 12 steps. At each step the policy flips a fair coin: up (+1) or down (−1). The only reward is on the last step, if the walker finishes at . With a fair coin that happens about 39% of the time. The world is small enough that we can compute and exactly for every state, and also the exact mean and variance of any GAE estimate over all possible episodes. There is no sampling noise in the readouts.
The critic. The demo’s critic is the true plus a fixed random mistake in every state, with size set by the “critic error σ” slider. At σ = 0 the critic is perfect. “New critic mistakes” draws a different set of mistakes of the same size.
The top panel shows one sampled episode: the path, then for each step a bar with this episode’s estimate , a whisker showing the mean ± one standard deviation you would get if you re-rolled the future from that step, and a thick dark tick for the target. Tap a column (or focus the plot and use the arrow keys) to see that step’s numbers. The bottom panel shows bias², variance and their sum, the mean squared error, averaged over every step of every possible episode, as a function of . The green triangle marks the best for the current critic, and the dashed vertical line is the you have selected.
this episode's Âtmean ± 1 std over all futurestarget Qπ(st,at) − V(st)
bias²varianceMSE = bias² + variance
What to try: (1) Press Perfect critic. Every λ is unbiased and the best λ is 0. Why is the variance at λ = 0 exactly zero in this world? (2) Drag the critic error up to 0.4 and watch the green triangle slide right: a worse critic means you should lean on the real rewards. (3) At error 0.15, press Play at λ = 0 and then at λ = 1, and watch the bars at step 0 from episode to episode. (4) Lower γ to 0.9 and see what happens to the variance at λ = 1.
Some numbers to check against the demo, for its default critic: at σ = 0.15 and γ = 1, the MSE is 0.018 at (all bias, no variance) and 0.139 at (all variance, no bias). The minimum is about 0.012, near . At σ = 0.4 the best moves to about 0.7.
What the target is, and where bias comes from
You may have noticed that the target tick is , using the critic’s rather than the true . Here is why that is the right target. Write the critic as the truth plus an error, . Then each TD error splits into the true TD error plus error terms:
and summing with GAE’s weights gives (Exercise 8.5 walks through it)
- The term depends only on the state, so it acts like a baseline and cannot bias the policy gradient (Chapter 7’s argument again). That is why the demo measures error against and not against : a wrong baseline can cost some variance, but it adds no bias.
- The real bias comes from the critic’s mistakes at future states, weighted by . At every weight is zero: Monte Carlo is unbiased no matter how bad the critic is. At the whole weight lands on : one-step TD inherits the critic’s next-state mistake in full. In between, the mistakes of many future states are averaged, and in the demo (where mistakes in different states are independent) they partly cancel.
Where variance comes from. adds up the random TD errors with weights . Each one carries the randomness of one more reward and one more action, so the variance grows as the effective window grows. In the demo’s world, transitions are deterministic and the reward depends only on the final position, so is fully determined by , and the variance at is exactly zero. In most environments it isn’t, but the shape of the curve is the same.
A2C: the practical algorithm
The one-step actor-critic updates after every single transition. That is slow on modern hardware, and consecutive transitions are strongly correlated, which is the problem Chapter 6 solved with a replay buffer. The standard deep-RL recipe instead runs many environments in parallel and updates on batches.
A3C (Asynchronous Advantage Actor-Critic, Mnih et al., 2016) ran many CPU threads, each with its own copy of the environment. Each thread computed gradients on its own short rollout and applied them to shared parameters without locks. Because the threads were in different parts of their episodes, a batch of their data was far less correlated than one long trajectory. That made a replay buffer unnecessary and kept the method on-policy. A3C used n-step advantages with and an entropy bonus (below). A2C is the synchronous version: step all environments together, wait for every one, then make one batched update. OpenAI’s Baselines team reported in 2017 that their synchronous A2C performed at least as well as their asynchronous implementation, and it uses a GPU much better. A2C is what people usually implement today, and it is what you will build in the lab.
A2C with GAE
Initialise actor π_θ, critic V_φ, and N environments
repeat:
# 1. Rollout: n_steps in each of N environments with the current policy
for k = 1..n_steps:
a ~ π_θ(· | s) in every environment; record s, a, r, done, V_φ(s)
# 2. Advantages and targets (no gradients here)
Â, R̂ ← compute_gae(rewards, values, V_φ(last states), dones, γ, λ)
 ← ( − mean(Â)) / (std(Â) + 1e-8) # advantage normalization
# 3. One gradient step on the combined loss over the N · n_steps samples
loss ← policy_loss + c_v · value_loss − c_e · entropy
take one optimizer step on (θ, φ); throw the batch away
The loss, term by term
For a batch of transitions, with and treated as constants:
- Policy loss. Its gradient is minus the policy-gradient estimate, so gradient descent on it is gradient ascent on . It is a “loss” only in the sense that differentiating it gives the right update. Its value is not a measure of how well you are doing.
- Value loss. Regression of the critic onto the λ-returns, weighted by (often 0.5).
- Entropy bonus. is largest for a uniform policy and zero for a deterministic one. Rewarding it slightly () slows the policy’s collapse onto one action before it has explored enough. A deterministic policy also stops producing varied data, and its score goes to zero, so learning stalls. The idea goes back to Williams & Peng (1991). The same collapse is a central problem in RL for reasoning models (Chapter 19).
Detach the targets. and were computed from , but they must be treated as constants. If gradients flowed into through the policy loss, the actor’s loss could be lowered by changing the critic to make advantages look different. That would be nonsense. If they flowed into , you would get a full-gradient TD method with different behavior from the semi-gradient method we analyzed (Chapter 6 explains why semi-gradient is the standard).
Quick check Why is the advantage Âₜ detached (treated as a constant) in the policy loss −log π(aₜ|sₜ)·Âₜ?
The policy gradient theorem says: move θ along ∇log π weighted by the advantage. The weight is a measurement, not something to optimize. Without detaching, gradient descent would also push the critic to make advantages smaller or larger, which has nothing to do with improving the policy.
Advantage normalization
Almost every implementation rescales each batch of advantages to mean 0 and standard deviation 1 before the policy loss. There are two reasons, and both are worth understanding.
- Scale. The size of the policy step is (learning rate) × (advantage size). Advantage sizes vary hugely across tasks and over training. In CartPole they can be dozens of reward units early on and much smaller later. Normalizing makes the learning rate mean roughly the same thing throughout.
- Sign. Subtracting the batch mean is one more baseline. Early in training the critic outputs about 0 while true values are large and positive. Then every is positive and every sampled action gets pushed up, which is the high-variance situation from the worked example. After centering, roughly half the actions are pushed up and half down.
It is not free. Strictly, the normalized estimator is no longer an unbiased policy gradient: the batch statistics depend on the samples, and the effective step size changes from batch to batch. In practice the gain in stability far outweighs this. Keep the idea in mind: GRPO’s “subtract the group mean, divide by the group std” (Chapter 15) is the same normalization done per prompt. Whether to divide by the std at all is one of the debates in Chapter 16.
Shared or separate networks?
| Separate actor and critic | Shared trunk, two heads | |
|---|---|---|
| Compute and memory | two networks | one network, cheaper |
| Features | each learns its own | the critic’s features can help the actor, and vice versa |
| Interference | none | the value loss’s gradients flow into the shared trunk and can swamp the policy’s, so needs tuning |
| Typical use | small control tasks; the lab default | Atari-style pixel inputs (A3C shared a convolutional trunk) |
Andrychowicz et al. (2020) ran a large ablation study of choices like this for on-policy methods and is worth a look once you have done the lab. For language models the question takes a different form. The “critic” in PPO-RLHF is either a separate full-size model or a scalar head on the policy, and its memory cost is one reason critic-free methods took over (Chapter 15).
One more detail: time limits are not terminal states
CartPole stops every episode at 500 steps. The pole has not fallen; we simply stopped watching. If you mark that step as terminal (, no bootstrap), the critic is taught that a perfectly balanced pole at step 500 is worth 0, while the same physical state at step 100 is worth a lot. Its input does not include the time, so it cannot fit both, and the error leaks into the advantages. The fix (Pardo et al., 2018) is to separate termination (a true end: bootstrap with 0) from truncation (a time-out: bootstrap with ). The lab’s rollout code does this, and Exercise 8.9 asks you to explain it.
What A2C still gets wrong: each batch is used for one gradient step and then discarded. This wastes data, and the size of a safe step is hard to know in advance: a single overly large step can wreck the policy, and the next batch is then collected by the wrecked policy. Chapter 9 keeps everything from this chapter (GAE, the value loss, the entropy bonus, normalization) and fixes exactly that.
Summary
- The policy gradient weights each by some . The advantage is the ideal weight. It has the same expected gradient as , averages to zero under , and carries only the “which action was better” signal.
- An actor-critic method learns a critic by regression (TD or λ-return targets) and uses it to estimate advantages for the actor .
- The TD error is an unbiased one-sample advantage estimate if , and biased otherwise. It is low-variance because it has only one step of randomness.
- n-step advantages satisfy : more real rewards means less critic bias and more variance.
- GAE averages all n-step estimates: , computed backward via . is one-step TD, is Monte Carlo minus a baseline. is the λ-return, the critic’s target.
- Critic error enters GAE’s bias through future states with weight . λ sets how much you trust the critic. is a robust default.
- A2C: parallel environments, short rollouts, GAE, normalized advantages, and loss = policy loss + × value loss − × entropy. Advantages and targets are detached. Truncation is not termination.
- In LLM training, PPO-RLHF uses a per-token value head and GAE (often ). GRPO-style methods drop the critic and use group-average rewards as the baseline.
Exercises
In a state with three actions, and .
- Compute and the three advantages.
- Check that .
- The agent samples the most likely action, action 2 (probability 0.5). Does a REINFORCE update weighted by raise or lower its probability? What about one weighted by ?
Solution
- . The advantages are .
- . This holds for any policy, because by definition, so .
- With weight , the update moves along , which raises , even though is the worst action. Only other samples (action 3, with weight 4) can undo this on average. With weight , the update lowers on this very sample. Same expected gradient, much less variance.
A three-step episode with has rewards , , , and then terminates. The critic says , , , and (terminal).
- Compute .
- Compute the Monte Carlo advantages for , and check that .
- Compute the 2-step advantage in two ways: from its definition and as .
- Compute GAE with for all three steps using the backward recursion.
Hint
Solution
- . . .
- , , . The advantages are . Check: . They match.
- Definition: . Sum of TD errors: . Both give .
- . . .
Notice how different the estimates for step 0 are: (TD), (2-step), (GAE 0.5), (MC). They are all “advantage estimates”, and they disagree because they trust the critic to different degrees. The 2-step estimate is the only negative one because it hands over to the critic at , where , while the actual return from was 2. On this episode the critic’s forecast for was too low, and every estimator that leans on it inherits that.
- An episode terminates at step (so ). Prove that for every ,
- Now suppose the rollout is cut off at step without the episode ending, so the last TD error bootstraps from . What does the same sum equal? Interpret the result in words.
Hint
Solution
-
Expand: . The rewards give , the full discounted return, because the episode ends at . For the values, with appears with coefficient (as the next state of step ) and (as the current state of step ), so it cancels. What survives is (only ever a current state) and (only ever a next state). Since , the sum is . This is exactly GAE at , so GAE(γ, 1) is Monte Carlo with as a baseline.
-
The same cancellation gives
In words: use real rewards up to the cut, then let the critic estimate the rest. So on a truncated rollout is the -step return, not pure Monte Carlo. It is unbiased only if is. This is why A2C with short rollouts still depends on the critic even at , but only at the rollout’s edge, discounted by .
Define and, for , .
- Show that for .
- Use part 1 to prove by induction that .
- From , derive the backward recursion .
Hint
Solution
-
. For the inner sum is empty and this reads , consistent with .
-
Base case : , an empty sum. Inductive step: assume the claim for at every time. Then
- , substituting .
The recursion in part 2 is the reason “n-step” and “a sum of TD errors” are the same thing. Each step contributes its own surprise, then passes the rest of the estimate one step down the line, discounted.
Let the critic be , where is its error (with at terminal states). Write for the TD error computed with the true .
- Show .
- Show that the GAE estimate decomposes as
- Show that for every .
- Explain why the term does not bias the policy gradient, and which removes the remaining error terms.
Hint
Solution
-
.
-
Summing with weights , the error part is . In the first sum put : . In the second, : . The coefficient of for is . That gives the stated formula. (In an episode all sums stop at the terminal state, where .)
-
For : , shown in the chapter. For : by the tower rule, . Since and advantages average to zero under , this is . So only the term survives, for any .
-
depends only on , so in the policy gradient it contributes . It is a (bad) baseline: it can add variance but not bias. The remaining terms involve future states, which depend on , so they do bias the gradient in general. Their weights are all zero at , so Monte Carlo is unbiased with any critic. At only survives, with weight : one-step TD carries the full error of the next state’s value. This is why the demo’s target is , which equals : it already contains the harmless baseline term.
Early in CartPole training, a batch of five transitions gets GAE advantages . The critic still outputs values near 0, and every reward is .
- Without normalization, which of the five sampled actions does the policy step make more likely?
- Normalize the batch (population std). Which actions are now pushed up, and which down?
- Give two distinct reasons normalization helps, and one thing it costs.
Hint
Solution
- All five. Every advantage is positive, so every sampled action’s probability goes up. Only the sizes differ. Information about which actions were better lives only in the differences, which is the high-variance situation of the chapter’s worked example.
- Mean 12, squared deviations , variance , std . Normalized: . The actions with advantages 15 and 14 are pushed up. Those with 9 and 10 are pushed down. The one with 12 is left alone.
- Centering is an extra baseline (the batch mean), which fixes the “everything positive” problem while the critic is still learning. Scaling makes the step size independent of the reward scale and of the training phase, so one learning rate works throughout. Cost: the estimator is no longer exactly the policy gradient. The batch mean and std depend on the samples themselves, and the effective learning rate changes from batch to batch (a batch of nearly identical advantages gets blown up to unit size, which amplifies noise; the in the denominator only prevents division by zero). GRPO normalizes per group of responses to the same prompt (Chapter 15), and Dr. GRPO argues that the std division introduces a bias worth removing (Chapter 16).
Use the GAE demo. Before each step, write down your prediction.
- Press Perfect critic. Where is the best ? The variance at is exactly zero. Why, in this particular world?
- Move the critic error to 0.05, 0.15, 0.25 and 0.4, and note the best each time. Describe the trend in one sentence.
- At critic error 0.15 and , change from 1 to 0.9. The variance drops a lot. Give two reasons, one of which is a warning.
- At critic error 0.15, press Play with , then with . Describe what happens to the bar at step 0 across episodes, compared to its target tick.
Hint
Solution
- Best , with MSE 0. With a perfect critic, every is unbiased (Exercise 8.5), so you should pick the one with least variance. Here is fully determined by : the move is deterministic and the reward depends only on the state reached. So the one-step estimate has no randomness at all. Larger adds the randomness of future coin flips. At the variance reaches about 0.139 (with γ = 1).
- For the demo’s default critic mistakes, the best is about 0.08, 0.38, 0.56 and 0.72 respectively (a different set of mistakes moves these a little). The worse the critic, the more you should rely on real rewards, so the best moves toward 1.
- First, discounting shrinks the weight of distant TD errors (the window shrinks from infinite to 10 steps), so fewer random terms enter. Second, and this is the warning: the reward sits up to 11 steps away and is multiplied by up to , so all the values, advantages and their spread shrink in absolute size. Part of the “variance reduction” is just a change of units, and part is a change of problem: you are now estimating advantages for a more short-sighted objective. is not a free variance-reduction knob the way is with a good critic.
- At the step-0 bar hardly moves from episode to episode (the start state is always the same, and only the first action varies), but it sits visibly away from the tick. That is bias, coming from the critic’s mistake at . At the bar jumps around a lot, sometimes far above and sometimes far below, but the whisker’s mean dot sits on the tick. That is unbiased but high variance. The best in between gives bars that move moderately and sit close to the tick.
In the lab 08-actor-critic, implement in actor_critic.py:
- Task 1,
td_errors, and Task 2,compute_gae, including episode boundaries inside a rollout and the(T, N)shape for parallel environments. The first GAE test is this chapter’s running example. - Task 3,
normalize_advantages, and Task 4,actor_critic_loss(policy loss, value loss, entropy bonus, with detached targets).
Then run python run.py. It trains A2C for on 3 seeds and saves a2c_lambda.png. In the demo, a good critic favored small . On CartPole, learns far more slowly than or 1. Explain why. Also look at the very start of the curve: it drops to about 10, below a random policy (about 22). Run train_a2c(total_steps=30_000, lam=0.0, verbose=True) and watch the printed entropy. What has happened to the policy?
Hint
Solution
Key lines (full code in solutions/actor_critic.py):
# Task 1: next_values is values shifted up one row, with last_value as the final row
next_values = np.concatenate([values[1:], last_value[None]], axis=0)
deltas = rewards + gamma * next_values * (1.0 - dones) - values
# Task 2: one backward pass; (1 - dones[t]) stops the carry at episode ends
for t in range(T - 1, -1, -1):
next_adv = deltas[t] + gamma * lam * (1.0 - dones[t]) * next_adv
advantages[t] = next_adv
returns = advantages + values
# Task 3
(adv - adv.mean()) / (adv.std(unbiased=False) + eps)
# Task 4
log_probs = torch.log_softmax(logits, -1)
logp = log_probs.gather(1, actions.unsqueeze(1)).squeeze(1)
policy_loss = -(logp * advantages.detach()).mean()
value_loss = ((values - returns.detach()) ** 2).mean()
entropy = -(log_probs.exp() * log_probs).sum(-1).mean()Because every operation in Tasks 1 and 2 indexes only the first (time) axis, the same code handles (T,) and (T, N) arrays.
Why λ = 0 is slow here. A fresh critic outputs about 0, while true values in CartPole are large: an episode that lasts more steps is worth , up to about 100. One-step advantages depend entirely on the critic, so early on they are nearly constant (about everywhere) and carry almost no information about which actions keep the pole up. That is maximal bias. The policy improves only after the critic has learned decent values, which itself takes a while, since TD(0) targets propagate information one step per update. With near 1, the advantages use real rewards: a step followed by an early fall has a much smaller return than one followed by a long balance. CartPole’s dynamics and rewards are deterministic, so the variance cost of is modest. The demo’s lesson still applies: the best depends on the critic’s quality, and early in training the critic is bad.
Why λ = 0 first gets worse than random. With the reference solution the printed entropy falls from about 0.69 (, a coin flip) to about 0.1 within 15k steps, and the average return settles near 9.6, which is what you get by pushing the cart the same way every time. The policy has collapsed onto one action. The one-step advantages are nearly constant, so after normalization the actor is fitting unit-sized versions of tiny differences that come from the fresh critic, not from the task (the cost of normalization from Exercise 8.6). Whatever direction the barely trained critic happens to prefer, the actor follows, and nothing in a one-step advantage contradicts it. Only after the critic learns that falling is bad (the value loss rises and then drops back) does the entropy come back up and the return start to climb. This is critic bias at its worst: it does not just slow learning, it points the actor the wrong way.
CartPole episodes end either when the pole falls (or the cart leaves the track), or after 500 steps.
- Suppose your code treats the 500-step cut-off like a fall:
done = 1, no bootstrap. What regression target does the critic see for a well-balanced state at step 499? And for the same physical state at step 100? - Why is that a problem for a critic whose input is ?
- The lab’s
collect_rolloutreplaces the reward at a truncated step with and then marks the step done. Show that this gives the same TD error as bootstrapping normally, while still stopping GAE from leaking into the next episode. - When would treating the time limit as terminal be correct?
Hint
Solution
- At step 499 the target is about (nothing follows). At step 100 the same state’s target reflects many more steps of reward, up to for a good policy.
- The critic cannot see the time, so it is asked to output both about 1 and about 100 for the same input. It ends up somewhere in between, wrong for both. Those errors feed into every advantage estimate. Worse, the actor is told that balancing well near step 500 is bad, because the forecast drops sharply there.
- With the bootstrap folded into the reward and : , the normal TD error. Setting also zeroes the carry, so the next row of the rollout, which belongs to a fresh episode, cannot leak into this one. (Note that here must be the state before the automatic reset, which is why
VecCartPole.stepalso returnsfinal_obs.) - When the time limit is a real part of the task (a game that ends at a fixed time, say) and the remaining time is part of the state, so the critic can tell step 100 from step 499. Pardo et al. (2018) discuss both cases.
Consider the token-level view of an LLM response from Chapter 11: state , action , , no KL penalty, and a single reward given after the last token.
- Write GAE with for token in terms of and the critic.
- Now replace the per-token critic with one number per prompt: the mean reward of responses sampled for the same prompt. What advantage does every token of response get?
- Give two reasons why training a per-token critic is harder for an LLM than for CartPole.
Hint
Solution
- With , GAE telescopes to Monte Carlo: . Each token is credited with the final reward minus the critic’s forecast just before that token.
- for every token of response . It is the same number for all tokens in a response. This is the advantage used by RLOO and GRPO (Chapter 15, Chapter 16), up to GRPO’s extra division by the group’s std and RLOO’s leave-one-out mean. You lose per-token credit assignment, but you lose the critic’s bias too, and you save a whole model.
- (a) Cost: the critic is usually itself a large transformer (often the size of the policy or the reward model), with its own activations, gradients and optimizer state. That roughly doubles training memory and compute. (b) Difficulty: it must predict, from a half-written answer, the eventual reward. That is a hard prediction problem with a sparse, end-of-sequence signal and millions of distinct prefixes, and an inaccurate critic biases every token’s advantage (Exercise 8.5). CartPole has a 4-dimensional state and a dense reward every step.
Files: actor_critic.py, test_actor_critic.py, run.py, README.md
cd 08-actor-critic
python -m pytest -q # your code: tests fail until you fill in the TODOs
RL_SOLUTIONS=1 python -m pytest -q # reference solutions: all passFirst time? See Exercises & setup.
Further reading
- Schulman, Moritz, Levine, Jordan & Abbeel (2015), High-Dimensional Continuous Control Using Generalized Advantage Estimation. The GAE paper. Sections 2–3 (the menu, “γ-just” estimators, which is the paper’s term for estimators that are unbiased for the γ-discounted advantage, and the derivation) are short and match this chapter closely.
- Sutton & Barto (2018), Reinforcement Learning: An Introduction, sections 13.4–13.5 (REINFORCE with baseline, actor-critic), chapter 7 (n-step bootstrapping) and chapter 12 (λ-returns). The tabular foundations behind everything here.
- Mnih et al. (2016), Asynchronous Methods for Deep Reinforcement Learning. A3C: parallel actor-learners, n-step advantages and an entropy bonus. Read section 4 and Algorithm S3 for the actor-critic version.
- Huang et al. (2022), The 37 Implementation Details of Proximal Policy Optimization. A blog post (ICLR Blog Track) on how real implementations handle GAE, advantage normalization, vectorized environments and truncation. Very useful once you start writing PPO in Chapter 9.
- Andrychowicz et al. (2020), What Matters In On-Policy Reinforcement Learning? A Large-Scale Empirical Study. Over 250,000 training runs ablating choices like GAE λ, normalization and network sharing. Read it for evidence instead of folklore.
- Pardo, Tavakoli, Levdik & Kormushev (2018), Time Limits in Reinforcement Learning. Why a time-out is not a terminal state, and what to do about it.
- Barto, Sutton & Anderson (1983), Neuronlike adaptive elements that can solve difficult learning control problems. The original actor-critic, balancing a pole. It is striking how much of this chapter is already there.
Next: Chapter 9 keeps GAE, the critic and the entropy bonus, and asks how to take bigger, safer policy steps by reusing each batch of data several times.