Vanilla policy gradient takes one bad big step and the policy collapses. The whole frontier of model-free RL is a single question: how do you take the biggest safe step?
You have a working policy gradient agent. It rolls out the current policy, estimates the gradient of expected return, and steps the parameters uphill: θ′ = θ + α ∇θ J(θ). Everything depends on one number you picked by hand — the step size α.
Pick it too small and training crawls; you burn a million expensive robot rollouts to inch forward. Pick it too big and something much worse happens. The new policy is so different from the old one that the data you just collected — rolled out under the old policy — no longer describes the world the new policy will see. You step confidently in a direction that was only good locally, land far away, and the return falls off a cliff.
So the entire chapter we are about to walk through is one idea expressed five different ways. We want to take the biggest step we safely can — big enough to learn fast, small enough that the post-step policy still resembles the one we collected data under. That "still resembles" condition is called a trust region, and it is the spine of TRPO, PPO, and (in a different guise) DDPG and SAC.
The curve is true expected return as a function of how far you move the policy. The straight tangent is what your gradient thinks happens. Slide the step size: a small step lands where the gradient promised; a big step walks off the local peak and over the cliff, where return crashes.
Notice the asymmetry. Near zero, the tangent line and the true curve agree — the linear approximation behind the gradient is trustworthy. Far out, they diverge wildly. The gradient is a local object; it tells you nothing about what happens once you've moved far enough that the world looks different. A trust region is just a fence that keeps you in the zone where the local picture is still roughly true.
Before the new machinery, let us place it on the map you already know. The lecture splits model-free RL into three families by what they directly estimate.
| Family | What it learns | Examples |
|---|---|---|
| Value-based | The optimal Q-function; the policy is implicit (act greedily). | FQI, DQN |
| Policy-gradient | The policy directly, by ascending the return gradient. | REINFORCE, NPG, TRPO, PPO |
| Actor-critic | A critic for the current policy, used to improve the actor. | DDPG, TD3, SAC |
Everything in this lecture is either policy-gradient (the TRPO/PPO branch) or actor-critic (the DDPG/SAC branch). Why are there so many? Because there is no perfect RL algorithm — each one trades off three things the lecture names explicitly.
Two binary questions sort all six algorithms cleanly, and we will return to this grid as our final cheat sheet:
Vanilla policy gradient already has a hidden way to talk about step size. We can rewrite "step uphill with learning rate α" as a constrained optimization: maximize the linearized improvement, subject to not moving the parameters too far.
Read it left to right: among all new parameter vectors θ′ close to the old θ, pick the one that most increases the (linearized) objective. The fence is a ball of radius ε in parameter space. Solving this gives back ordinary gradient ascent — ε just plays the role of α.
The fix is to measure distance where it matters: directly between the two policies. Constrain a divergence between the old and new action distributions, not between their parameter vectors:
Natural Policy Gradient (NPG) makes this concrete. For small steps, the KL divergence between the policies is well-approximated by a quadratic form in the parameter change, with the Fisher information matrix F as its metric:
F is the local "ruler" of policy space: it stretches the directions that change the policy a lot and shrinks the ones that barely matter. Solving the constrained problem with this metric gives the natural gradient update:
That F−1 "pre-bends" the raw gradient so a unit step moves the same policy distance in every direction. The same numerical ε now means the same amount of behavioral change — which is exactly the trust region we wanted.
The teal dashed circle is a fixed ball in parameter space. The warm ellipse is what that same ball looks like measured in policy space, warped by the Fisher metric. Drag the anisotropy slider: when one direction changes the policy much more than the other, the naive ball lets you step too far along the sensitive axis. The natural gradient re-shapes the step so it's a true circle in policy space.
TRPO starts from a beautiful identity. The difference in return between a new policy and the old one can be written exactly as an expectation of the old policy's advantage A, taken over states the new policy visits:
If we could maximize the right-hand side directly, we'd be doing exact policy improvement. There's a chicken-and-egg problem, though: the expectation is over trajectories from the new policy πθ′ — the very thing we are still solving for. We can't sample from a policy we don't have yet.
Concretely, we maximize a surrogate objective — the old-policy-sampled advantage, reweighted by the probability ratio — subject to a hard cap on the KL divergence between old and new:
Read the objective: if an action had positive advantage, increase its probability ratio (make it more likely under the new policy); if negative, decrease it. The KL cap δ is the leash that keeps the importance-sampling approximation valid — the same trust region NPG hinted at, now explicitly enforced rather than approximated by a single F−1 step.
The importance-sampling trick is "evaluate the new policy using the old policy's data, reweighted by the ratio." It is exact in expectation, but its variance explodes when the policies drift apart. Feel it concretely. Suppose under the old policy an action had probability 0.5, and the new policy makes it probability 0.9. The reweighting ratio is 0.9 / 0.5 = 1.8 — mild. Now suppose the new policy makes it 0.99 while the old policy had it at 0.05. The ratio is 0.99 / 0.05 = 19.8 — a single sample now carries twenty times its honest weight, and a handful of such samples swamp the whole estimate.
This is the deep reason the trust region is not optional bookkeeping — it is what keeps these ratios near 1 so the estimate stays sane. The KL cap on the policy distributions directly bounds how large any reweighting ratio can get. Keep this picture: the leash isn't to be cautious for its own sake; it's to keep the math we used to justify the step from falling apart. PPO's clip, next chapter, attacks the exact same ratios from the other end — it caps them sample by sample instead of capping the distribution-level KL.
Background shading is true return (brighter = better). The teal circle is the trust region — the set of new policies within KL ≤ δ of where you stand. TRPO moves to the best point inside that circle, not the global optimum. Slide δ to grow or shrink the leash, then press Step to take several constrained updates and watch the path climb safely.
Bigger δ lets each step jump further and climb faster — until it's large enough that the linear/importance-sampling approximation breaks and a step overshoots into worse territory (the cliff from Chapter 0). Smaller δ is safe but slow. TRPO's guarantee is that, within the leash, every step is a genuine improvement.
PPO keeps TRPO's idea — reweight the advantage by the probability ratio, stay near the old policy — but throws away the expensive constrained solve. Instead of a hard KL leash, it bakes the "stay close" into the objective itself with a clip, so you can optimize it with ordinary minibatch SGD for several epochs.
Define the probability ratio — new action probability over old, at the actions you actually took:
When the new policy hasn't moved, r = 1. If the new policy makes an action more likely, r > 1; less likely, r < 1. The plain (TRPO-style) surrogate term is just r times the advantage: rt · At. Maximizing it with no leash is exactly the cliff — nothing stops r from running off to 5 or 0.01.
PPO compares two quantities and takes the minimum:
Two new pieces. clip(r, 1−ε, 1+ε) simply pins the ratio inside the band [1−ε, 1+ε] — with the standard ε = 0.2, that's [0.8, 1.2]. Anything below 0.8 becomes 0.8; anything above 1.2 becomes 1.2. The outer min takes the smaller of the unclipped term and the clipped term. Let us see exactly when each one bites, splitting on the sign of the advantage.
That asymmetry is the entire genius. The clip removes the incentive to overshoot in the helpful direction, but it never stops you from fixing a genuinely bad action. The lecture states it as a warning about the alternative: if you used only the clipped term, a "very bad" ratio (r ≪ 1 when A > 0) would not be punished — the min is what restores that punishment.
The dashed gray line is the unclipped surrogate r·A. The warm curve is LCLIP — what PPO actually optimizes. Toggle the sign of the advantage and watch which side goes flat (zero gradient) and which keeps a slope. The flat region is where one update can no longer move the policy too far.
Because the clip enforces the trust region per sample inside a plain loss, PPO can do what TRPO cannot: multiple epochs of minibatch SGD on the same batch of data. That reuse is why PPO is dramatically simpler to implement, plays nicely with dropout and shared networks, and — empirically — matches or beats TRPO's sample efficiency. It is the workhorse behind robot locomotion policies and the RLHF step that aligns large language models.
Formulas are slippery until you run a number through them. Let us evaluate LCLIP for several probability-ratio values, with ε = 0.2 so the band is [0.8, 1.2], for both signs of the advantage. The per-sample objective is
We want r above 1. Watch where the clip starts to bite.
| ratio r | r·A (unclipped) | clip(r) | clip(r)·A | min → L | gradient? |
|---|---|---|---|---|---|
| 0.90 | 1.80 | 0.90 | 1.80 | 1.80 | yes |
| 1.00 | 2.00 | 1.00 | 2.00 | 2.00 | yes |
| 1.10 | 2.20 | 1.10 | 2.20 | 2.20 | yes |
| 1.20 | 2.40 | 1.20 | 2.40 | 2.40 | edge |
| 1.50 | 3.00 | 1.20 | 2.40 | 2.40 (clipped) | no — flat |
| 2.00 | 4.00 | 1.20 | 2.40 | 2.40 (clipped) | no — flat |
At r = 1.5: the unclipped term is 1.5 × 2 = 3.0; the clipped term is clip(1.5)=1.2, so 1.2 × 2 = 2.4. The min is 2.4. Push r from 1.5 to 2.0 and L stays glued at 2.4 — the clip bit at r = 1.2 and froze the reward. No further gradient, so SGD stops enlarging this already-favored action. That is the safe-step mechanism, in arithmetic.
We want r below 1 (make a bad action less likely). Now the asymmetry shows.
| ratio r | r·A (unclipped) | clip(r) | clip(r)·A | min → L | gradient? |
|---|---|---|---|---|---|
| 1.00 | −2.00 | 1.00 | −2.00 | −2.00 | yes |
| 0.80 | −1.60 | 0.80 | −1.60 | −1.60 | edge |
| 0.50 | −1.00 | 0.80 | −1.60 | −1.60 (clipped) | no — flat |
| 1.50 | −3.00 | 1.20 | −2.40 | −3.00 (unclipped) | yes — punished! |
Two things to feel here. First row r = 0.5: we have already pushed the bad action well below its old probability (good!), and the clip stops us from being rewarded for pushing it to zero — the min picks the clipped −1.60, which is flat. Done; move on.
The last row is the punch line. r = 1.5 with A < 0 means the new policy made a bad action more likely — a real mistake. The unclipped term −3.00 is smaller (more negative) than the clipped −2.40, so the min keeps −3.00, which still has gradient. The optimizer is pulled hard to fix this. This is the lecture's warning made arithmetic: if PPO used only the clipped term, this "very bad" ratio would cap at −2.40 and be under-punished; the min restores the full penalty.
Now make the machine do it — and verify your hand answers against it.
PPO is on-policy and stochastic: it throws data away after each update. For continuous control on a real robot, that waste hurts. The other branch — DDPG (Deep Deterministic Policy Gradient) — reuses every transition from a replay buffer and learns a precise, deterministic action map.
DDPG has two networks. A critic Qφ(s, a) estimates the value of taking action a in state s, trained by the same Bellman/replay machinery as DQN. And an actor — a deterministic policy μθ(s) that outputs one action, no sampling.
Here is the elegant part. The actor wants to output the action that the critic rates highest. So we maximize the critic's value at the actor's own action, and the chain rule routes the gradient through the critic into the actor:
Read the data flow. The critic tells you, at the current action, which direction in action space increases value — that's ∇a Q. The actor's Jacobian ∇θ μ then says how to nudge the weights to move the output action in that good direction. The actor is dragged toward whatever the critic currently values. Because the critic learns from a replay buffer of any past data, DDPG is fully off-policy — that's its sample-efficiency win.
Make the shapes concrete, because the chain rule here is easy to wave at and hard to picture. Say the state is a 17-dimensional robot observation and the action is a 6-dimensional torque vector. The actor maps 17 numbers in to 6 numbers out: μθ: ℝ17 → ℝ6. The critic maps the 17 + 6 = 23 numbers (state concatenated with action) to a single scalar value. To improve the actor we ask the critic for ∇a Q — a 6-vector, one number per torque, saying "raise this torque, lower that one." We feed that 6-vector backward through the actor network and it becomes a gradient on the actor's weights. No reward, no probability ratio, no log-prob appears anywhere — the learning signal is purely "the critic says move the action this way." That is what makes it the deterministic policy gradient.
TD3 (Twin Delayed DDPG) keeps DDPG's skeleton and adds three fixes, each targeting a specific instability:
The actor must still explore, and a deterministic policy explores nothing on its own — so DDPG/TD3 bolt exploration noise onto the action during data collection. That bolt-on is exactly what SAC, next, replaces with something principled.
Let's make the critic-gradient mechanism concrete. The lab below recovers the action-gradient direction — the very signal that drives the DDPG actor — numerically.
SAC (Soft Actor-Critic) keeps DDPG's off-policy, replay-buffer efficiency but makes two changes that together make it the most robust continuous-control algorithm on the list: the policy is stochastic again, and the objective rewards not just return but entropy.
The entropy of a policy is a measure of how spread-out (unpredictable) its action distribution is. A policy that always picks the same action has zero entropy; one that spreads probability evenly across actions has maximum entropy. SAC adds an entropy bonus to every step's reward, scaled by a temperature α:
In words: succeed at the task and act as randomly as possible while doing so. The temperature α is the trade dial — large α values exploration heavily (the policy stays spread out); small α collapses toward pure reward-maximization (and toward DDPG-like determinism).
For a discrete policy with action probabilities p, the (Shannon) entropy is H = − ∑i pi log pi. Take a 3-action policy that is nearly deterministic, p = (0.90, 0.05, 0.05):
Now a spread-out policy p = (0.34, 0.33, 0.33):
The uniform-ish policy has nearly three times the entropy (1.098 vs 0.394). With temperature α = 0.2, the entropy bonus alone is 0.22 vs 0.08 per step — a standing reward the spread-out policy collects just for staying exploratory. Maximizing return plus αH tilts SAC toward keeping that breadth until the task reward is strong enough to justify narrowing.
Three actions; one has slightly higher task value. Slide the temperature α: at high α the SAC policy stays spread (high entropy, exploring); at low α it collapses onto the single best action (low entropy, exploiting). The bar heights are the policy's action probabilities; the readout shows the entropy and the entropy bonus αH.
Let's compute and verify the entropy itself, and confirm the headline fact: a hotter (more uniform) softmax policy has higher entropy.
Chapter 1 promised that two binary questions sort every algorithm. Here is the grid, and it is the single most useful picture to carry out of this lecture. The two axes:
Click a quadrant (or an algorithm chip) to see which methods live there and why. The horizontal axis is on-policy → off-policy; the vertical axis is stochastic → deterministic.
| On-policy (data thrown away) | Off-policy (replay buffer reused) | |
|---|---|---|
| Stochastic policy | REINFORCE, A2C, PPO, TRPO | SAC |
| Deterministic policy | — | DDPG, TD3 |
Read the columns. The whole on-policy / stochastic cell is the policy-gradient family — REINFORCE up through PPO — and it is exactly where the step-size problem lives, because each update discards its data. NPG, TRPO and PPO are the progressively cheaper trust regions that tame it.
The off-policy column is the actor-critic family that buys sample efficiency through replay. DDPG and TD3 sit in the deterministic row; SAC sits in the stochastic row because its entropy objective wants a distribution to spread. Notice the empty cell: on-policy and deterministic is essentially unused — a deterministic on-policy method would throw away data and have no built-in exploration, the worst of both.
You now own the advanced model-free toolbox — the algorithms people actually reach for in robot learning. Every one of them answered the Chapter 0 question (how big a step is safe?) with a different fence.
| On-policy | Off-policy | |
|---|---|---|
| Stochastic | REINFORCE, A2C, PPO | SAC |
| Deterministic | — | DDPG, TD3 |
This lesson is Lecture 11 of the 16-831 series. The natural neighbors:
"Take the biggest step you safely can — then take another."