Skip to content

Proximal Policy Optimization (PPO)

PPO (Schulman et al., 2017) is the workhorse of modern RL. It improves on vanilla policy gradient by constraining how much the policy can change in each update, leading to more stable training.

REINFORCE updates can be unstable — you saw this in chapter 1’s live demo, where cranking the learning rate froze the policy onto a bad route, irreversibly. The problem gets worse in practice, because for sample efficiency we want to reuse each batch of trajectories for several gradient epochs — and every epoch after the first is computed under a policy that no longer matches the one that collected the data. The idea behind PPO is to keep the new policy “close” to the old one, so that reuse stays safe. At the bottom of this page you can run the full loop and toggle the safety off.

We define the probability ratio:

rt(θ)=πθ(atst)πθold(atst)r_t(\theta) = \frac{\pi_\theta(a_t \mid s_t)}{\pi_{\theta_\text{old}}(a_t \mid s_t)}

When rt=1r_t = 1, the new and old policies agree. When rtr_t deviates far from 1, the policy has changed significantly.

Slide πnew\pi_\text{new} to see the ratio cross the trust-region edges [1ε,1+ε][1-\varepsilon, 1+\varepsilon].

πold=0.20,ε=0.2\pi_\text{old} = 0.20, \varepsilon = 0.2. Then 1ε=0.81 - \varepsilon = 0.8 and 1+ε=1.21 + \varepsilon = 1.2, so πnew\pi_\text{new} must stay in [0.16,0.24][0.16, 0.24] to be inside the trust region. If a gradient step pushes πnew\pi_\text{new} to 0.300.30, the ratio r=1.50r = 1.50 is clipped to 1.201.20 for a good advantage (the objective stops growing), but stays uncapped if A^<0\hat A < 0 (the policy can be punished more for a bad action). This asymmetric clip is what stops one bad batch from collapsing the policy.

The vanilla surrogate objective is:

LCPI(θ)=Et[rt(θ)A^t]L^{CPI}(\theta) = \mathbb{E}_t \left[ r_t(\theta) \hat{A}_t \right]

where A^t\hat{A}_t is the estimated advantage. But maximizing this without constraint can lead to excessively large policy updates.

PPO clips the ratio to prevent large updates:

LCLIP(θ)=Et[min(rt(θ)A^t,  clip(rt(θ),1ϵ,1+ϵ)A^t)]L^{CLIP}(\theta) = \mathbb{E}_t \left[ \min \left( r_t(\theta) \hat{A}_t, \; \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) \hat{A}_t \right) \right]

The min\min ensures:

  • When A^t>0\hat{A}_t > 0 (good action): the ratio is capped at 1+ϵ1 + \epsilon, preventing over-reinforcement
  • When A^t<0\hat{A}_t < 0 (bad action): the ratio is capped at 1ϵ1 - \epsilon, preventing over-punishment

The typical value is ϵ=0.2\epsilon = 0.2.

Initialize policy π_θ and value function V_φ
for each iteration:
Collect trajectories using π_θ
Compute advantages Â_t using GAE
for each mini-batch epoch:
Compute r_t(θ) = π_θ(a_t|s_t) / π_θ_old(a_t|s_t)
L_clip = min(r_t·Â_t, clip(r_t, 1-ε, 1+ε)·Â_t)
Update θ to maximize L_clip
Update φ to minimize (V_φ(s_t) - G_t)²
θ_old ← θ

Live: The Whole Loop, With and Without the Clip

Section titled “Live: The Whole Loop, With and Without the Clip”

Everything above, running: batches are collected from πθold\pi_{\theta_\text{old}}, advantages are normalized, and the same batch is reused for several epochs of surrogate ascent — exactly the loop in the pseudocode.

What it models. PPO on a 10-armed bandit (batch = 16 pulls, noisy rewards). Blue bars are π; gray bars behind them are each arm’s true mean reward, so you can see whether the policy is concentrating on the right one. The purple histogram shows where the batch’s probability ratios ρᵢ end up after the reuse epochs — the green band is the clip region [1−ε, 1+ε].

Knobs. The clip toggle is the experiment; ε sets the band width; epochs per batch controls how hard each batch is reused (this is the off-policy pressure); learning rate scales every step.

Try this. Run the defaults to convergence — with clipping the ratios never leave the band and KL stays flat. Now reset, switch clipping off, and push epochs to 16: within a few dozen updates some ratios blow past 3 into the red overflow bucket, KL spikes, and the policy usually locks onto a mediocre arm the batch happened to flatter. Turn clipping back on mid-collapse and watch KL flatten again. Offline calibration of this exact setup: clip on converges 25/25 runs; clip off, 6/25.

  • Schulman, Wolski, Dhariwal, Radford, Klimov. Proximal Policy Optimization Algorithms. 2017. arXiv:1707.06347
  • Schulman et al. Trust Region Policy Optimization. ICML 2015 — the hard-constraint ancestor the clip approximates. arXiv:1502.05477