Chapter 15 · Section 15.3 · 60 min

Policy gradients and REINFORCE

A pretrained language model already has a policy, and a good one. It writes fluent text, follows most instructions, and gets some fraction of math problems right. What we want from RL is to make the responses that earn high reward a little more likely and the ones that earn low reward a little less likely, without throwing away everything the model already knows. Q-learning, from §15.2, would start over, learning a value for every (prefix, token) pair from scratch and acting greedily on it. That is the wrong tool.

The right tool treats the policy's parameters θ\theta as the thing to optimize and climbs the expected reward by gradient ascent, exactly as supervised learning descends a loss. Two obstacles seem to stand in the way. The reward is often not differentiable at all (a unit test passes or fails), and the expectation is taken over samples that the policy itself generates, so changing θ\theta changes the distribution we are averaging over. One identity, the log-derivative trick from §0.4, removes both obstacles. This section derives the policy gradient from it, proves the policy gradient theorem, builds REINFORCE, runs it on a bandit and on a small environment where only a stochastic policy is optimal, and then confronts its great weakness, variance.

The objective

Let πθ(a∣s)\pi_\theta(a \mid s) be a policy with parameters θ\theta (for us, a softmax over logits produced by a network). Running it in the environment for at most TT steps produces a random trajectory τ=(s0,a0,r0,…,sT−1,aT−1,rT−1,sT)\tau = (s_0, a_0, r_0, \dots, s_{T-1}, a_{T-1}, r_{T-1}, s_T), where as in §15.1 rtr_t is the reward for taking ata_t in sts_t. Its probability factors into the start distribution p0p_0, the policy's choices, and the environment's transitions PP,

pθ(τ)=p0(s0)∏t=0T−1πθ(at∣st) P(st+1∣st,at).p_\theta(\tau) = p_0(s_0) \prod_{t=0}^{T-1} \pi_\theta(a_t \mid s_t)\, P(s_{t+1} \mid s_t, a_t).

Write R(τ)=∑t=0T−1γtrtR(\tau) = \sum_{t=0}^{T-1} \gamma^t r_t for the discounted return of the whole trajectory. The objective is the expected return,

J(θ)=Eτ∼pθ[R(τ)]=∑τpθ(τ) R(τ),J(\theta) = \mathbb{E}_{\tau \sim p_\theta}\big[R(\tau)\big] = \sum_\tau p_\theta(\tau)\, R(\tau),

where the sum runs over all possible trajectories (an integral, if states are continuous). In plain words, J(θ)J(\theta) is the average total reward the policy earns, and we want to make it larger.

We cannot differentiate R(τ)R(\tau) with respect to θ\theta, and we do not need to, because R(τ)R(\tau) does not depend on θ\theta at all. A given trajectory has a given return. What depends on θ\theta is how likely each trajectory is.

The log-derivative trick

Differentiate JJ and move the gradient inside the sum (fine for finite sums, and for integrals under mild regularity conditions),

∇θJ(θ)=∑τR(τ) ∇θpθ(τ).\nabla_\theta J(\theta) = \sum_\tau R(\tau)\, \nabla_\theta p_\theta(\tau).

This is not yet an expectation, so we cannot estimate it by sampling. The trick is the chain rule for the logarithm, ∇θlog⁡pθ=∇θpθ/pθ\nabla_\theta \log p_\theta = \nabla_\theta p_\theta / p_\theta, rearranged as ∇θpθ=pθ∇θlog⁡pθ\nabla_\theta p_\theta = p_\theta \nabla_\theta \log p_\theta. Substituting,

∇θJ(θ)=∑τpθ(τ) R(τ) ∇θlog⁡pθ(τ)=Eτ∼pθ[R(τ) ∇θlog⁡pθ(τ)].\nabla_\theta J(\theta) = \sum_\tau p_\theta(\tau)\, R(\tau)\, \nabla_\theta \log p_\theta(\tau) = \mathbb{E}_{\tau\sim p_\theta}\big[R(\tau)\, \nabla_\theta \log p_\theta(\tau)\big].

In plain words, the gradient of the expected return is the average, over trajectories the policy actually produces, of "how good was this trajectory" times "which way in parameter space makes this trajectory more likely". Every sampled trajectory pulls the parameters toward making itself more likely, with a strength set by its return, so high-return trajectories win the tug of war (and a negative return pushes away instead).

Why not differentiate through the sampling instead, as the reparameterization trick of §0.4 does for Gaussians? Because that trick needs the sample to be a differentiable function of θ\theta and the reward to be differentiable in the sample. A discrete action (a token) is neither, and a unit test is not differentiable at all. The score-function estimator needs neither, which is why it is the workhorse of RL on language models, at the price of the variance we will fight for the rest of the chapter.

The environment drops out

Now take the log of the trajectory probability. The product becomes a sum,

log⁡pθ(τ)=log⁡p0(s0)+∑t=0T−1log⁡πθ(at∣st)+∑t=0T−1log⁡P(st+1∣st,at),\log p_\theta(\tau) = \log p_0(s_0) + \sum_{t=0}^{T-1} \log \pi_\theta(a_t \mid s_t) + \sum_{t=0}^{T-1} \log P(s_{t+1}\mid s_t, a_t),

and only the middle sum depends on θ\theta. The start distribution and the dynamics vanish when we take the gradient,

∇θlog⁡pθ(τ)=∑t=0T−1∇θlog⁡πθ(at∣st),so∇θJ(θ)=Eτ[R(τ)∑t=0T−1∇θlog⁡πθ(at∣st)].\nabla_\theta \log p_\theta(\tau) = \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t \mid s_t), \qquad\text{so}\qquad \nabla_\theta J(\theta) = \mathbb{E}_{\tau}\Big[ R(\tau) \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t \mid s_t)\Big].

This is the first form of the policy gradient. Read it slowly, because it is remarkable. To estimate the gradient we need only samples of trajectories, their returns, and the gradient of the log-probability of the actions the policy took. We never need PP, we never need its derivative, and the reward can come from anywhere, a human, a unit test, a reward model, or a game engine. This is why policy gradient methods are called model-free. The vector ∇θlog⁡πθ(a∣s)\nabla_\theta \log \pi_\theta(a\mid s) is called the score of the action.

The score of a softmax policy

For a softmax policy with logits z∈RK\mathbf{z} \in \R^{K} over KK actions, log⁡π(a)=za−log⁡∑bezb\log\pi(a) = z_a - \log\sum_{b} e^{z_b}. The gradient of the log-sum-exp is the softmax itself (§0.2), so

∇zlog⁡π(a)=ea−π,\nabla_{\mathbf{z}} \log \pi(a) = \mathbf{e}_a - \boldsymbol{\pi},

where ea\mathbf{e}_a is the one-hot vector of action aa and π=softmax⁡(z)\boldsymbol{\pi} = \operatorname{softmax}(\mathbf{z}). In plain words, to make action aa more likely, raise its logit and lower every logit in proportion to its current probability. This is the same p−y\mathbf{p} - \mathbf{y} as the gradient of cross-entropy in that section, with the sign flipped, which is no coincidence. log⁡π(a)\log\pi(a) is the negative cross-entropy loss with target aa. For a network, the chain rule takes it from the logits to every weight, and autograd does that for us.

Warm-up

The score of a softmax policy

Implement softmax_score(logits, actions) where logits has shape (N, K) and actions is an int array of shape (N,). Return the array of shape (N, K) whose row ii is ∇zlog⁡softmax⁡(zi)ai=eai−softmax⁡(zi)\nabla_{\mathbf{z}}\log\operatorname{softmax}(\mathbf{z}_i)_{a_i} = \mathbf{e}_{a_i} - \operatorname{softmax}(\mathbf{z}_i). It must be numerically stable for large logits.

Hidden tests, hints, and AI help, from $1.99 a month.

A worked example on a bandit

Take a two-armed bandit (a one-step MDP) with deterministic rewards r=(1,0)\mathbf{r} = (1, 0) and a softmax policy with logits z=(0,0)\mathbf{z} = (0, 0), so π=(0.5,0.5)\boldsymbol{\pi} = (0.5, 0.5). The objective is J(z)=∑aπara=π1J(\mathbf{z}) = \sum_a \pi_a r_a = \pi_1. Its exact gradient follows from the softmax Jacobian of §4.3, ∂πa/∂zj=πa(1[a=j]−πj)\partial \pi_a/\partial z_j = \pi_a(\mathbb{1}[a=j] - \pi_j), giving ∇zJ=π⊙(r−J1)=(0.25,−0.25)\nabla_{\mathbf{z}} J = \boldsymbol{\pi}\odot(\mathbf{r} - J\mathbf{1}) = (0.25, -0.25).

The policy gradient estimator sees one pull at a time. If it pulls arm 1 (probability 0.5), it reports r1(e1−π)=(0.5,−0.5)r_1(\mathbf{e}_1 - \boldsymbol\pi) = (0.5, -0.5). If it pulls arm 2, it reports r2(e2−π)=(0,0)r_2(\mathbf{e}_2 - \boldsymbol\pi) = (0, 0). The average of the two reports, weighted by their probabilities, is (0.25,−0.25)(0.25, -0.25), exactly the true gradient. Every single report is wrong, though, either twice too large or zero. The estimator is unbiased and noisy, and that combination is the story of the rest of this chapter.

In general, for a KK-armed bandit the expectation of the estimator is ∑aπara(ea−π)=π⊙r−Jπ=π⊙(r−J1)\sum_a \pi_a r_a(\mathbf{e}_a - \boldsymbol\pi) = \boldsymbol\pi\odot\mathbf{r} - J\boldsymbol\pi = \boldsymbol\pi\odot(\mathbf{r} - J\mathbf{1}), which matches the exact gradient term by term. The next exercise asks for this exact gradient, which is useful as a test oracle for any sampled implementation.

Core

The exact policy gradient of a softmax bandit

For a bandit with expected rewards r of shape (K,) and a softmax policy with logits z of shape (K,), implement bandit_policy_gradient(z, r) returning ∇zJ\nabla_{\mathbf{z}} J where J(z)=∑asoftmax⁡(z)a raJ(\mathbf{z}) = \sum_a \operatorname{softmax}(\mathbf{z})_a\, r_a. Also implement sampled_policy_gradient(z, r, n, seed), which draws n actions with np.random.default_rng(seed).choice(K, size=n, p=pi) and returns the average of the single-sample estimates rai(eai−π)r_{a_i}(\mathbf{e}_{a_i} - \boldsymbol\pi).

Hidden tests, hints, and AI help, from $1.99 a month.

The policy gradient theorem

The trajectory form multiplies every action's score by the return of the entire trajectory, including rewards that arrived before the action was taken. That cannot be the most efficient use of the data. An action at step 10 cannot have caused the reward at step 3. The policy gradient theorem (Sutton, McAllester, Singh, and Mansour 2000) gives a sharper form, in which each action is weighted by its own action value.

Theorem. For a discounted MDP with start distribution p0p_0 and objective J(θ)=∑sp0(s)Vπθ(s)J(\theta) = \sum_s p_0(s)V^{\pi_\theta}(s),

∇θJ(θ)=∑sρπ(s)∑a∇θπθ(a∣s) Qπ(s,a)=Eτ[∑t=0T−1γt Qπ(st,at) ∇θlog⁡πθ(at∣st)],\nabla_\theta J(\theta) = \sum_{s} \rho^{\pi}(s) \sum_a \nabla_\theta\pi_\theta(a\mid s)\, Q^{\pi}(s, a) = \mathbb{E}_{\tau}\Big[\sum_{t=0}^{T-1} \gamma^t\, Q^{\pi}(s_t, a_t)\, \nabla_\theta\log\pi_\theta(a_t\mid s_t)\Big],

where π=πθ\pi = \pi_\theta and ρπ(s)=∑t≥0γt P(st=s)\rho^\pi(s) = \sum_{t\ge0}\gamma^t\,\mathbb{P}(s_t = s) is the discounted state visitation, how often (with discounting) the policy finds itself in ss.

What is surprising is what is missing. Changing θ\theta changes which states the agent visits, so you might expect a term involving the derivative of ρπ\rho^\pi, which would be hopeless to estimate. There is no such term. The gradient only needs the policy's own score, weighted by how good each action is.

∂ Proof of the policy gradient theorem

Fix a state ss. The value is Vπ(s)=∑aπθ(a∣s)Qπ(s,a)V^\pi(s) = \sum_a \pi_\theta(a\mid s)Q^\pi(s,a), and both factors depend on θ\theta. By the product rule,

∇Vπ(s)=∑a[∇πθ(a∣s) Qπ(s,a)+πθ(a∣s) ∇Qπ(s,a)].\nabla V^\pi(s) = \sum_a \Big[\nabla\pi_\theta(a\mid s)\, Q^\pi(s,a) + \pi_\theta(a\mid s)\,\nabla Q^\pi(s,a)\Big].

The reward r(s,a)r(s,a) and the transitions PP do not depend on θ\theta, so differentiating Qπ(s,a)=r(s,a)+γ∑s′P(s′∣s,a)Vπ(s′)Q^\pi(s,a) = r(s,a) + \gamma\sum_{s'}P(s'\mid s,a)V^\pi(s') gives ∇Qπ(s,a)=γ∑s′P(s′∣s,a)∇Vπ(s′)\nabla Q^\pi(s,a) = \gamma\sum_{s'}P(s'\mid s,a)\nabla V^\pi(s'). Write u(s)=∑a∇πθ(a∣s)Qπ(s,a)\mathbf{u}(s) = \sum_a\nabla\pi_\theta(a\mid s)Q^\pi(s,a) for the first part (a vector with the shape of θ\theta), and P(s→x,k)\mathbb{P}(s\to x, k) for the probability of being in state xx after exactly kk steps of π\pi from ss. Then

∇Vπ(s)=u(s)+γ∑xP(s→x,1) ∇Vπ(x).\nabla V^\pi(s) = \mathbf{u}(s) + \gamma\sum_{x}\mathbb{P}(s\to x, 1)\,\nabla V^\pi(x).

The same identity holds for ∇Vπ(x)\nabla V^\pi(x), so substitute it in, and again for the states after that,

∇Vπ(s)=u(s)+γ∑xP(s→x,1)u(x)+γ2∑xP(s→x,2)∇Vπ(x)=⋯=∑x(∑k=0∞γk P(s→x,k))u(x).\nabla V^\pi(s) = \mathbf{u}(s) + \gamma\sum_x\mathbb{P}(s\to x,1)\mathbf{u}(x) + \gamma^2\sum_x\mathbb{P}(s\to x, 2)\nabla V^\pi(x) = \dots = \sum_x\Big(\sum_{k=0}^{\infty}\gamma^k\,\mathbb{P}(s\to x, k)\Big)\mathbf{u}(x).

(The remainder after kk unrollings is γk\gamma^k times a bounded quantity, so it vanishes as k→∞k\to\infty when γ<1\gamma < 1, or when every trajectory ends in finite time.) Average over the start state s∼p0s\sim p_0. The inner sum becomes ρπ(x)\rho^\pi(x), and we get the first form of the theorem.

For the second form, use ∇πθ(a∣s)=πθ(a∣s)∇log⁡πθ(a∣s)\nabla\pi_\theta(a\mid s) = \pi_\theta(a\mid s)\nabla\log\pi_\theta(a\mid s) inside u\mathbf{u}, so that ∑xρπ(x)u(x)=∑tγt∑xP(st=x)∑aπθ(a∣x)Qπ(x,a)∇log⁡πθ(a∣x)\sum_x\rho^\pi(x)\mathbf{u}(x) = \sum_{t}\gamma^t\sum_x\mathbb{P}(s_t = x)\sum_a\pi_\theta(a\mid x)Q^\pi(x,a)\nabla\log\pi_\theta(a\mid x), which is Eτ[∑tγtQπ(st,at)∇log⁡πθ(at∣st)]\mathbb{E}_\tau[\sum_t\gamma^tQ^\pi(s_t,a_t)\nabla\log\pi_\theta(a_t\mid s_t)] written out. □\square

You should not take a theorem like this on faith, and in a gridworld we do not have to. For a tabular softmax policy (one logit per state and action, θ∈R∣S∣×∣A∣\theta \in \R^{|\mathcal{S}|\times|\mathcal{A}|}), the gradient with respect to the logits of state ss is ρπ(s) π(⋅∣s)⊙(Qπ(s,⋅)−Vπ(s))\rho^\pi(s)\,\boldsymbol\pi(\cdot\mid s)\odot(Q^\pi(s,\cdot) - V^\pi(s)), by the same softmax algebra as the bandit. Everything on the right can be computed exactly with linear solves, including ρπ=(I−γPπ⊤)−1p0\rho^\pi = (\mathbf{I} - \gamma\mathbf{P}_\pi^\top)^{-1}\mathbf{p}_0, and the left side can be checked by finite differences of the exact JJ.

Python · cell 1

The theorem's gradient agrees with brute-force finite differences to about ten decimal places, with no derivative of the state distribution anywhere. (The visitation sums to 1/(1−γ)=101/(1-\gamma) = 10, because the absorbing terminal states keep collecting visitation after the episode ends. They contribute nothing to the gradient, since all their actions have the same value.)

Research

The policy gradient theorem, exactly, for a tabular policy

For a finite MDP with P of shape (S, A, S), R of shape (S, A), start distribution p0 of shape (S,), discount γ<1\gamma < 1, and a tabular softmax policy with logits theta of shape (S, A), implement exact_policy_gradient(P, R, p0, gamma, theta) that returns ∇θJ\nabla_\theta J, shape (S, A), using the policy gradient theorem (no finite differences). Then implement discounted_visitation(P, p0, gamma, pi) returning ρπ\rho^\pi, shape (S,).

Hidden tests, hints, and AI help, from $1.99 a month.

REINFORCE

We rarely know QπQ^\pi, but we can sample it. Given (st,at)(s_t, a_t), the reward-to-go Gt=∑k=tT−1γk−trkG_t = \sum_{k=t}^{T-1}\gamma^{k-t}r_k, the discounted return from step tt onward, has conditional expectation exactly Qπ(st,at)Q^\pi(s_t, a_t), by the definition of QπQ^\pi. Substituting it into the theorem gives an unbiased estimator that needs nothing but sampled episodes. Williams (1992) called the resulting algorithm REINFORCE.

  1. Run the current policy πθ\pi_\theta to collect NN episodes.
  2. For every step of every episode, compute the reward-to-go Gt(i)G_t^{(i)} with one backward pass (Exercise 15.1a).
  3. Estimate the gradient and take a step of gradient ascent,
g^=1N∑i=1N∑t=0Ti−1γt Gt(i) ∇θlog⁡πθ(at(i)∣st(i)),θ←θ+η g^.\hat{\mathbf{g}} = \frac{1}{N}\sum_{i=1}^{N}\sum_{t=0}^{T_i - 1}\gamma^t\, G_t^{(i)}\,\nabla_\theta\log\pi_\theta\big(a_t^{(i)}\mid s_t^{(i)}\big), \qquad \theta \leftarrow \theta + \eta\,\hat{\mathbf{g}}.
  1. Throw the episodes away and repeat. They were sampled from the old policy, and the estimator is only unbiased for the policy that generated the data. This is what on-policy means, and it is the waste that PPO (§15.6) will try to reduce.

In plain words, after each batch of episodes, raise the log-probability of every action in proportion to how much reward followed it.

(That GtG_t may replace the full R(τ)R(\tau) of the trajectory form, discarding the rewards before step tt, also has a direct one-line proof, which we give in §15.4 along with the baseline, because the same lemma proves both.)

The surrogate loss

In code, nobody writes down ∇θlog⁡πθ\nabla_\theta\log\pi_\theta by hand. We build a scalar whose gradient is the estimator and let autograd differentiate it. Treating the returns as constants (detached from the graph), define

LPG(θ)=−1N∑i∑tγt Gt(i) log⁡πθ(at(i)∣st(i)).\mathcal{L}^{\text{PG}}(\theta) = -\frac{1}{N}\sum_{i}\sum_{t} \gamma^t\, G_t^{(i)}\, \log \pi_\theta\big(a_t^{(i)} \mid s_t^{(i)}\big).

Its gradient is −g^-\hat{\mathbf{g}}, so minimizing it with any optimizer performs REINFORCE. Look at its shape. It is a cross-entropy loss on the policy's own samples, with each sample's log-likelihood weighted by its return. REINFORCE is weighted maximum likelihood on your own behavior. With a reward that is 1 for success and 0 for failure and no discounting, the loss is exactly the supervised fine-tuning loss on the successful samples, divided by NN, and the failures contribute nothing. That is a useful bridge to rejection-sampling fine-tuning (§18.2), which does exactly that.

Two warnings about the surrogate. Its value means nothing. It is not the expected return, it can go up while the policy improves, and plotting it as a training curve misleads everyone who reads the plot. Track the average return instead. And the normalization matters more than it looks. Dividing by the number of episodes NN gives the estimator above. Dividing by the total number of steps in the batch only rescales it by a batch-dependent number, which ties the step size to how long the episodes happened to be. Dividing each episode's sum by its own length before averaging, as the original GRPO loss does, is different in kind. It weights every step of a long episode less than every step of a short one, which changes the objective, a subtle bias that GRPO's variants argue about at length (§18.4).

Interview

The REINFORCE loss and its gradient

Implement reinforce_loss(logits, actions, weights) for a batch of NN decisions, where logits has shape (N, K), actions is an int array of shape (N,), and weights of shape (N,) holds each decision's weight (for example γtGt\gamma^tG_t), treated as constants. Return (loss, dlogits) with

loss=−1N∑i=1Nwi log⁡softmax⁡(zi)ai\text{loss} = -\frac{1}{N}\sum_{i=1}^N w_i\,\log\operatorname{softmax}(\mathbf{z}_i)_{a_i}

and dlogits =∂ loss/∂z= \partial\,\text{loss}/\partial\mathbf{z}, of shape (N, K). Compute the log-softmax stably.

Hidden tests, hints, and AI help, from $1.99 a month.

REINFORCE on a bandit

Start with the simplest possible case, a three-armed Bernoulli bandit with success probabilities 0.20.2, 0.50.5, and 0.80.8, a softmax policy over three logits, and small batches of 4 pulls per update, over 30 independent runs. For a bandit every episode is one step, so the reward-to-go is just the reward.

Python · cell 2

With the small learning rate every one of the 30 runs ends with most of its probability on the best arm. With a learning rate of 4, two runs end certain of the wrong arm, and with 16, a third of them do. A few lucky pulls of a mediocre arm drove its probability so high that the best arm was almost never tried again. A softmax policy that has collapsed onto one action stops exploring, and since the gradient of a nearly deterministic softmax is nearly zero (π⊙(r−J)\boldsymbol\pi\odot(\mathbf{r} - J) vanishes when π\boldsymbol\pi is one-hot), it cannot climb back out. Keeping the policy from collapsing too early is the job of the entropy bonus in §15.6 and the KL penalty in §15.7.

REINFORCE where only a random policy is optimal

Here is a small environment that shows something value-based methods cannot do, from Sutton and Barto's Example 13.1, the short corridor with switched actions. There are three non-terminal cells in a row and a goal at the right end. Each step costs 11. Actions are "left" and "right", and they do what they say in the first and third cells, but in the middle cell they are reversed. The catch is that the agent cannot tell the cells apart. Every state looks the same, so the policy is a single probability pp of choosing "right", used everywhere.

A deterministic policy is a disaster here. Always going right gets stuck bouncing between the first two cells, and always going left never leaves the first cell. Let us compute the value of a general pp exactly. Write V1,V2,V3V_1, V_2, V_3 for the values of the three cells (all with γ=1\gamma = 1). In cell 1, "right" (probability pp) moves to cell 2 and "left" stays put. In cell 2, the reversed actions mean "right" moves back to cell 1 and "left" moves on to cell 3. In cell 3, "right" reaches the goal. So

V1=−1+(1−p)V1+pV2,V2=−1+pV1+(1−p)V3,V3=−1+(1−p)V2.V_1 = -1 + (1-p)V_1 + pV_2, \qquad V_2 = -1 + pV_1 + (1-p)V_3, \qquad V_3 = -1 + (1-p)V_2 .

The first equation gives V1=V2−1/pV_1 = V_2 - 1/p. Substitute it and the third equation into the second, V2=−1+p(V2−1/p)+(1−p)(−1+(1−p)V2)V_2 = -1 + p(V_2 - 1/p) + (1-p)(-1 + (1-p)V_2), which simplifies to V2 p(1−p)=p−3V_2\,p(1-p) = p - 3. Then

J(p)=V1=p−3p(1−p)−1p=−2(2−p)p(1−p).J(p) = V_1 = \frac{p-3}{p(1-p)} - \frac{1}{p} = -\frac{2(2 - p)}{p(1-p)} .

Setting the derivative to zero gives p2−4p+2=0p^2 - 4p + 2 = 0, so the best policy goes right with probability p⋆=2−2≈0.586p^\star = 2 - \sqrt 2 \approx 0.586 and earns J(p⋆)=−(6+42)≈−11.66J(p^\star) = -(6 + 4\sqrt 2) \approx -11.66. For comparison, an ε\varepsilon-greedy agent with ε=0.1\varepsilon = 0.1, which goes right with probability 0.950.95 or 0.050.05, earns −44.2-44.2 or −82.1-82.1. An agent that learns values and acts (nearly) greedily on them cannot represent the optimum. A policy gradient method can, because it searches over pp directly.

Python · cell 3

Starting from the ε\varepsilon-greedy-like policy p=0.95p = 0.95, REINFORCE walks pp down toward the optimum 0.5860.586, and the expected return climbs from −44-44 toward −11.7-11.7. It needed hundreds of episodes for a problem with one parameter, though, and the step size had to be tiny (2−122^{-12}). Every return is negative, often large (from −1-1 near the goal to −100-100 or worse after a long bounce), so every update pushes down on the probability of every action taken, and the useful signal is only the small difference between how hard good and bad actions get pushed. That observation is the subject of the next part of this section.

Why REINFORCE has high variance

An unbiased gradient is only useful if its noise is small enough that a reasonable number of samples averages it out. REINFORCE's noise is large, for four reasons that are worth separating.

  • It scales with the size of the returns, not their differences. Add a constant cc to every reward of a bandit. The expected gradient does not change, since Ea∼π[c ∇log⁡π(a)]=c ∇∑aπ(a)=c ∇1=0\mathbb{E}_{a\sim\pi}[c\,\nabla\log\pi(a)] = c\,\nabla\sum_a\pi(a) = c\,\nabla 1 = 0. But each single-sample estimate gains a term c ∇log⁡π(a)c\,\nabla\log\pi(a), whose variance grows like c2c^2. The corridor's returns are all large and negative, so most of each update is this useless term.
  • It sums over the horizon. The trajectory estimator multiplies a sum of TT random scores by a sum of TT random rewards, so its variance tends to grow with the episode length. A 1,000-token response is a 1,000-step episode.
  • One number takes the credit for everything. With a single reward at the end, every action in the episode gets the same weight, whether it helped, hurt, or did nothing.
  • Rare, large returns dominate. A trajectory that is unlikely under the policy but has a huge return contributes a huge estimate on the rare occasions it is sampled.

The first effect is the easiest to see and to fix. The widget below uses a two-armed bandit with rewards r1>r2r_1 > r_2 and a single parameter θ\theta, the logit of arm 1, so π1=σ(θ)\pi_1 = \sigma(\theta) and the true gradient is π1π2(r1−r2)\pi_1\pi_2(r_1 - r_2). Shift both rewards by the same offset and watch the spread of the single-sample estimates, and the learning curves, change while the true gradient stays put.

Why does adding a constant to every reward make policy gradients noisier, and how does a baseline fix it?
A two-armed bandit with rewards 1 and 0 plus an offset and Gaussian noise. The policy is π₁ = σ(θ). Left, 3,000 single-sample REINFORCE estimates of dJ/dθ. Right, 16 learning runs.
Loading interactive figure…

Subtracting a number from the rewards before multiplying by the score is called using a baseline, and the widget's toggle is the simplest one, the average reward. §15.4 proves that a baseline that does not depend on the action never introduces bias, finds the baseline that minimizes the variance, and arrives at the advantage function, actor-critic methods, and the form of the policy gradient used in every modern algorithm.

Do not conclude from the corridor that REINFORCE is only a teaching device. With a baseline it is a serious method for language models, whose pretrained policy starts so close to good behavior that small, noisy steps are enough. Ahmadian et al. (2024) fine-tuned models of about 7 billion parameters (Pythia-6.9B and Llama-7B) from human preferences on the TL;DR summarization and Anthropic helpful-and-harmless datasets, and found that REINFORCE-style updates matched or beat PPO there, as well as DPO and rejection-sampling fine-tuning. Their best variant used a leave-one-out baseline over several responses to the same prompt, which §15.4 derives and §18.4 turns into RLOO and GRPO.

In PyTorch

The production version of REINFORCE is three lines inside the training loop. Compute the log-probabilities of the taken actions, multiply by the detached returns, and call backward on the negative mean. Here we check that autograd's gradient of that surrogate loss on the gridworld equals the REINFORCE estimator computed by hand with the score formula.

🔥 In PyTorchfor a machine with PyTorch

Read more

Watch next

🎬 CS 285: Lecture 5, Part 1 · RAILThe first part of Sergey Levine's Berkeley lecture on policy gradients, the derivation this section follows, in the same trajectory notation.
🎬 RL Course by David Silver - Lecture 7: Policy Gradient Methods · Google DeepMindScore functions, the policy gradient theorem, and actor-critic methods from the classic course.
🎬 Policy Gradient Methods | Reinforcement Learning Part 6 · Mutual InformationAn animated walk through the policy gradient theorem and REINFORCE.