Skip to content
AI360Xpert
Beta

The REINFORCE Algorithm

REINFORCE updates a neural network policy by waiting for complete episodes, increasing the probability of actions that produced high returns and penalizing actions that led to low returns.

The REINFORCE workflow: sampling full episode trajectories, computing returns-to-go, subtracting a baseline, and scaling log-probability policy gradients.
The REINFORCE workflow: sampling full episode trajectories, computing returns-to-go, subtracting a baseline, and scaling log-probability policy gradients.

Why Does This Exist?

In many real-world control tasks, such as robotic arm manipulation or drone attitude stabilization, the action space is continuous (torque voltages, thrust vectors). Value-based methods struggle here: to act greedily, they must solve arg⁡max⁡aQ(s,a)\arg\max_a Q(s, a) at every timestep, which requires expensive continuous optimization inside the inner simulation loop. Furthermore, value-based methods cannot naturally learn stochastic policies, which are required in games of imperfect information or under state aliasing.

The REINFORCE algorithm (Williams, 1992) pioneered the policy gradient revolution. Instead of evaluating state-action values and deriving a policy indirectly, REINFORCE parameterizes the policy directly as πθ(a∣s)\pi_\theta(a \mid s)—typically outputting the mean and variance of a Gaussian distribution or logits of a categorical distribution.

Crucially, REINFORCE answers a fundamental question: how can you differentiate an objective function that depends on environment transitions when you do not know the environment's transition dynamics P(s′∣s,a)\mathcal{P}(s' \mid s, a)? By utilizing the log-derivative trick, REINFORCE converts the gradient of expected performance into an expectation of gradients, allowing agents to optimize policies via empirical Monte Carlo rollouts.

Think of It Like This

A basketball coach reviewing full game tape at the buzzer

Imagine a basketball coach who is not allowed to interrupt the game to give tactical corrections mid-play. Instead, the coach watches the entire 48-minute game from the stands without interfering, letting the players experiment with different passes and shots.

After the buzzer sounds and the final scoreboard confirms whether the team won or lost by 20 points, the coach sits down with the full game tape. For every shot taken in the fourth quarter, if the sequence ended in a scoring rally, the coach tells the player: "Do that exact dribble-drive move more often next time." If a sequence yielded turnovers and opponent fast-breaks, the coach says: "Reduce the frequency of that risky bounce pass."

Because the feedback is based on the entire completed game, credit is noisy—a brilliant pass in the first quarter might get dragged down by poor defense in the fourth. But across hundreds of games, the moves that systematically lead to high scores are reinforced, while moves that consistently lead to losses are suppressed.

How It Actually Works

Likelihood Ratio and Baseline Subtraction

Let a trajectory τ=(s0,a0,r1,s1,a1,…,sT)\tau = (s_0, a_0, r_1, s_1, a_1, \dots, s_T) be sampled by following policy πθ\pi_\theta. The expected return objective is:

J(θ)=Eτ∼πθ[R(τ)]=∫P(τ;θ)R(τ) dτJ(\theta) = \mathbb{E}_{\tau \sim \pi_\theta}[R(\tau)] = \int P(\tau; \theta) R(\tau) \, d\tau

The probability of a trajectory factors into initial state distribution, policy actions, and unknown environment transition probabilities:

P(τ;θ)=ρ0(s0)∏t=0T−1πθ(at∣st)P(st+1∣st,at)P(\tau; \theta) = \rho_0(s_0) \prod_{t=0}^{T-1} \pi_\theta(a_t \mid s_t) \mathcal{P}(s_{t+1} \mid s_t, a_t)

Taking the gradient ∇θJ(θ)\nabla_\theta J(\theta) directly is impossible because P\mathcal{P} is unknown. Applying the likelihood ratio trick (∇θP(τ)=P(τ)∇θlog⁡P(τ)\nabla_\theta P(\tau) = P(\tau) \nabla_\theta \log P(\tau)) eliminates the environment dynamics:

∇θlog⁡P(τ;θ)=∑t=0T−1∇θlog⁡πθ(at∣st)\nabla_\theta \log P(\tau; \theta) = \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t \mid s_t)

This yields the Policy Gradient Theorem:

∇θJ(θ)=Eτ∼πθ[∑t=0T−1∇θlog⁡πθ(at∣st)Gt]\nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[ \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t \mid s_t) G_t \right]

Where GtG_t is the return-to-go from step tt:

Gt=∑k=tT−1γk−tRk+1G_t = \sum_{k=t}^{T-1} \gamma^{k-t} R_{k+1}

Because future actions cannot influence past rewards, causality dictates replacing total trajectory return R(τ)R(\tau) with GtG_t, drastically reducing gradient variance.

Baseline Variance Reduction

To further reduce variance without introducing bias, a state-dependent baseline b(st)b(s_t) is subtracted from GtG_t. The update becomes:

θ←θ+α∑t=0T−1∇θlog⁡πθ(at∣st)(Gt−b(st))\theta \leftarrow \theta + \alpha \sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t \mid s_t) \left( G_t - b(s_t) \right)

The baseline does not introduce bias because:

Eat∼πθ[∇θlog⁡πθ(at∣st)b(st)]=b(st)∑aπθ(a∣st)∇θπθ(a∣st)πθ(a∣st)=b(st)∇θ(1)=0\mathbb{E}_{a_t \sim \pi_\theta} \left[ \nabla_\theta \log \pi_\theta(a_t \mid s_t) b(s_t) \right] = b(s_t) \sum_{a} \pi_\theta(a \mid s_t) \frac{\nabla_\theta \pi_\theta(a \mid s_t)}{\pi_\theta(a \mid s_t)} = b(s_t) \nabla_\theta (1) = 0

Worked Example

Consider a 2-step episode in an environment with two discrete actions (a1,a2a_1, a_2) parameterized by a single policy weight θ∈R\theta \in \mathbb{R}. The policy uses a softmax distribution where logit for a1a_1 is θ\theta and logit for a2a_2 is 00:

πθ(a1∣s)=eθeθ+1=σ(θ),πθ(a2∣s)=1−σ(θ)\pi_\theta(a_1 \mid s) = \frac{e^\theta}{e^\theta + 1} = \sigma(\theta), \quad \pi_\theta(a_2 \mid s) = 1 - \sigma(\theta)

The gradient with respect to θ\theta is:

  • If a1a_1 is chosen: ∇θlog⁡πθ(a1)=1−σ(θ)\nabla_\theta \log \pi_\theta(a_1) = 1 - \sigma(\theta)
  • If a2a_2 is chosen: ∇θlog⁡πθ(a2)=−σ(θ)\nabla_\theta \log \pi_\theta(a_2) = -\sigma(\theta)

Let initial weight θ=0.0\theta = 0.0, so σ(0.0)=0.5\sigma(0.0) = 0.5 (π(a1)=0.5,π(a2)=0.5\pi(a_1) = 0.5, \pi(a_2) = 0.5). Discount factor γ=1.0\gamma = 1.0, learning rate α=0.1\alpha = 0.1, and constant baseline b=5.0b = 5.0.

Sampled Episode Rollout:

  • Step 0 (s0s_0): Agent samples a1a_1. Receives reward r1=2.0r_1 = 2.0.
  • Step 1 (s1s_1): Agent samples a2a_2. Receives reward r2=8.0r_2 = 8.0. Episode terminates (T=2T=2).

Step-by-Step Computations:

  1. Returns-to-go:

    G1=r2=8.0G_1 = r_2 = 8.0 G0=r1+γG1=2.0+8.0=10.0G_0 = r_1 + \gamma G_1 = 2.0 + 8.0 = 10.0
  2. Advantage with Baseline:

    A0=G0−b=10.0−5.0=+5.0A_0 = G_0 - b = 10.0 - 5.0 = +5.0 A1=G1−b=8.0−5.0=+3.0A_1 = G_1 - b = 8.0 - 5.0 = +3.0
  3. Log-Probability Gradients:

    • At t=0t=0, action was a1a_1: ∇θlog⁡π(a1)=1−0.5=+0.5\nabla_\theta \log \pi(a_1) = 1 - 0.5 = +0.5
    • At t=1t=1, action was a2a_2: ∇θlog⁡π(a2)=−0.5\nabla_\theta \log \pi(a_2) = -0.5
  4. Total Policy Gradient:

    ∇θJ=(∇θlog⁡π(a0)⋅A0)+(∇θlog⁡π(a1)⋅A1)\nabla_\theta J = (\nabla_\theta \log \pi(a_0) \cdot A_0) + (\nabla_\theta \log \pi(a_1) \cdot A_1) ∇θJ=(0.5×5.0)+(−0.5×3.0)=2.5−1.5=+1.0\nabla_\theta J = (0.5 \times 5.0) + (-0.5 \times 3.0) = 2.5 - 1.5 = +1.0
  5. Parameter Update:

    θ←θ+α∇θJ=0.0+0.1×1.0=0.1\theta \leftarrow \theta + \alpha \nabla_\theta J = 0.0 + 0.1 \times 1.0 = 0.1

New probability for a1a_1: σ(0.1)=e0.1e0.1+1≈0.525\sigma(0.1) = \frac{e^{0.1}}{e^{0.1} + 1} \approx 0.525. The probability of taking action a1a_1 increased because its advantage was strongly positive.

Code

from typing import List, Tupleimport numpy as np
def reinforce_update(    theta: float,    actions: List[int],    rewards: List[float],    gamma: float = 1.0,    alpha: float = 0.1,    baseline: float = 5.0,) -> Tuple[float, List[float]]:    """Executes a Monte Carlo REINFORCE parameter update over one episode."""    # Compute returns-to-go G_t backward from terminal step    returns: List[float] = [0.0] * len(rewards)    g = 0.0    for t in reversed(range(len(rewards))):        g = rewards[t] + gamma * g        returns[t] = g
    # Softmax probability for action 0: p = 1 / (1 + exp(-theta))    prob_a1 = 1.0 / (1.0 + np.exp(-theta))        total_grad = 0.0    for t, action in enumerate(actions):        advantage = returns[t] - baseline        # Gradient of log pi: (1 - prob) if action 0, else -prob        grad_log = (1.0 - prob_a1) if action == 0 else (-prob_a1)        total_grad += grad_log * advantage
    updated_theta = theta + alpha * total_grad    return updated_theta, returns
# Episode: action 0 (a1) then action 1 (a2), rewards 2.0 and 8.0init_theta = 0.0new_theta, returns_computed = reinforce_update(    theta=init_theta,    actions=[0, 1],    rewards=[2.0, 8.0],    gamma=1.0,    alpha=0.1,    baseline=5.0,)
print(f"Returns G_t: {returns_computed}")# -> Returns G_t: [10.0, 8.0]
print(f"Updated Theta: {new_theta:.2f}")# -> Updated Theta: 0.10
new_prob = 1.0 / (1.0 + np.exp(-new_theta))print(f"Updated P(a1): {new_prob:.4f}")# -> Updated P(a1): 0.5250

Watch Out For

The Monte Carlo Variance Explosion

Because REINFORCE computes full episodic returns GtG_t by summing across all subsequent timesteps, the variance of the gradient estimator compounds exponentially with episode horizon TT. A single stochastic transition or exploratory action near the end of the episode introduces noise into the gradient of every preceding action in that episode, causing training to stall or destabilize.

Always implement reward-to-go instead of total trajectory return, normalize advantages across batch rollouts (A−μAσA+10−8\frac{A - \mu_A}{\sigma_A + 10^{-8}}), and subtract a learned state-value baseline Vϕ(s)V_\phi(s). If episode horizons exceed a few hundred steps, transition from pure Monte Carlo REINFORCE to an Actor-Critic architecture that bootstraps after nn steps.

The Quick Version

  • REINFORCE uses the log-derivative likelihood ratio trick to optimize parameterized policies without knowing environment transition dynamics.
  • Updates occur strictly at the end of complete episodes using Monte Carlo returns-to-go: Gt=∑k=tTγk−tRk+1G_t = \sum_{k=t}^T \gamma^{k-t} R_{k+1}.
  • Subtracting an unbiased baseline b(st)b(s_t) from GtG_t preserves the expected gradient while dramatically reducing sampling variance.