The Cross-Entropy Method on CartPole, Explained
After reading this you will understand how a four-number linear policy can balance an inverted pendulum, and how the cross-entropy method finds the weights for that policy by sampling, ranking and refitting a Gaussian, without ever computing a gradient.
What CartPole is and why it is the standard first problem
CartPole is a control task. A cart slides on a one-dimensional track. A pole is hinged to the top of the cart and can swing freely. At every time step you push the cart left or right with a fixed force, and the pole responds according to the physics of an inverted pendulum. The episode runs until the pole leans past 12 degrees from vertical, the cart leaves the track, or you reach 500 steps. The reward is one point per step, so the goal is simply to survive as long as possible.
The task earns its "fruit fly" reputation because it is small enough to reason about by hand yet hard enough to be interesting. The state is four numbers: cart position x, cart velocity \dot{x}, pole angle \theta, and pole angular velocity \omega. The action is binary: push left or push right. That is the entire interface.
Try Manual mode first. Even with only two buttons, keeping the pole up past 100 steps takes practice, because an inverted pendulum is unstable: a small tilt produces a torque that increases the tilt. Deviations grow roughly exponentially, so you have to push before the pole visibly falls, not after.
A linear policy is enough
You do not need a neural network here. A single weight vector solves CartPole. The policy takes the four state numbers, forms a weighted sum with a bias, and picks an action from the sign:
Here s = (x, \dot{x}, \theta, \omega) is the state, w is a vector of four weights, and b is a scalar bias. The dot product w \cdot s = w_1 x + w_2 \dot{x} + w_3 \theta + w_4 \omega collapses the four numbers into one, and the sign of that number plus the bias decides the push. Five numbers total: four weights and one bias.
Intuitively, a good policy weights the pole angle and angular velocity heavily. If the pole tilts right (\theta \gt 0) or is rotating right (\omega \gt 0), you want to push the cart right to slide back under the falling pole. So w_3 and w_4 should be positive and large. The cart position and velocity terms mostly keep the cart from drifting off the track.
The cross-entropy method as an optimizer
The cross-entropy method (CEM) does not follow a gradient. It treats the five policy numbers as a vector to be searched and maintains a Gaussian distribution over that vector. Each generation it samples candidate policies, scores them by episode length, keeps the best few, and refits the Gaussian to those survivors. Over generations the distribution concentrates around policies that balance well.
Formally, the parameter vector is \phi = (w_1, w_2, w_3, w_4, b), five numbers. The sampling distribution is a Gaussian with mean vector \mu and a diagonal covariance, so each coordinate i is drawn independently:
\mu_i is the current best guess for coordinate i, and \sigma_i is how far the method is willing to explore around it. The refit step is the whole idea. After scoring, you take the elite set (the top policies by episode length) and set the new mean and standard deviation to the sample mean and sample standard deviation of the elites:
Here K is the number of elites (6 in this demo) and \phi_i^{(k)} is coordinate i of the k-th elite. The mean moves toward what worked, and the standard deviation shrinks along any coordinate where the elites agree. That shrinking is what makes the method converge.
The name comes from the fact that refitting to the elites is equivalent to minimizing the cross-entropy (the KL divergence up to a constant) between the sampling Gaussian and a distribution placed on the elite samples. In practice you never compute that quantity: you just take the mean and standard deviation of the winners.
When to reach for it and when not to
CEM shines when the parameter space is small (tens of numbers), evaluations are cheap, and you have no gradient. That describes CartPole exactly: five parameters, an episode runs in milliseconds, and the reward is a step count with no usable derivative. The method is also easy to reason about and has almost no hyperparameters: population size, elite count, and an optional noise floor.
It scales poorly. With 1000 parameters you would need far more samples per generation to estimate the Gaussian, and the diagonal covariance ignores correlations between parameters. For large neural network policies, gradient-based methods such as policy gradients or PPO dominate. CEM is a fine baseline and a superb teaching tool, not a production solver for high-dimensional problems.
A worked run reproducing the demo defaults
The demo uses a population of 30 policies per generation, keeps the top 6 by episode length, and refits the Gaussian around them. The pole length and push force sliders stay at their defaults. Here is what one generation does, with small round numbers you can check.
One generation by hand, focusing on the pole-angle weight
Suppose the current sampling mean for the pole-angle weight w_3 is 0.20 with standard deviation 0.50. The method draws 30 values. Imagine the 6 elites (the policies that survived longest) had these w_3 values:
- Elite w_3 values:
0.9,1.1,0.8,1.3,1.0,0.7. - New mean: (0.9 + 1.1 + 0.8 + 1.3 + 1.0 + 0.7) / 6 = 5.8 / 6 = 0.9667.
- Deviations from the mean:
-0.0667,0.1333,-0.1667,0.3333,0.0333,-0.2667. - Squared deviations sum to 0.2333, so the variance is 0.2333 / 6 = 0.03889 and the new standard deviation is \sqrt{0.03889} = 0.1972.
In one generation the mean for w_3 jumped from 0.20 to 0.9667, and its standard deviation shrank from 0.50 to 0.1972. The method has learned that the pole-angle weight should be clearly positive, and it now searches a tighter band around 0.97. Repeat for all five coordinates every generation.
Because each coordinate is refit independently, the same shrinking happens in parallel across all five numbers. Coordinates that matter (angle, angular velocity) converge to definite values; coordinates that barely affect survival keep a wider spread, which is fine because their exact value does not change the outcome.
Reading the learning curve
The tool plots two lines per generation: the best episode length and the mean episode length over the 30 sampled policies. Watch both. The best line tells you whether any policy in the population can balance; the mean line tells you whether the whole distribution has moved toward balancing. Early on the best line jumps around while the mean stays low. As the Gaussian concentrates, the mean climbs to meet the best, and both flatten at the 500-step cap.
A healthy run reaches 500 steps within a few dozen generations. If the best line stalls well below 500, the sampling distribution has probably collapsed too early onto a mediocre policy, which is the classic CEM failure discussed next.
Common mistakes and how to avoid them
The failures below are the ones that show up when people build or tune a CEM run themselves.
- Premature collapse
- If the standard deviation shrinks to near zero while the mean sits on a poor policy, every future sample is nearly identical and learning stops. In the worked example, sigma went from
0.50to0.1972in one step. A few more such steps and it approaches zero. A small noise floor added to sigma each generation prevents this. - Too few elites
- Keeping only 1 or 2 elites out of 30 makes the standard deviation estimate noisy and speeds collapse. The 6-of-30 default (20 percent) is a reasonable balance.
- Evaluation noise
- If the initial state is randomized, a lucky policy can post a long episode by chance and enter the elite set undeservedly. Averaging each policy over several episodes before ranking reduces this, at the cost of more computation.
- Reacting instead of anticipating
- This one bites you in Manual mode, not the trained policy. Because tilt grows exponentially, waiting until the pole visibly leans means the correction arrives too late. Push toward the direction the pole is already rotating, early.
Harder settings are not just slower, they can be unsolvable for a linear policy. Push the pole length or force sliders far enough and no single weight vector balances the pole for 500 steps. If a run refuses to converge, check whether you have made the physics too extreme before blaming the optimizer.
Related tools on this site
CEM is one way to search for a policy. Two other reinforcement learning approaches on this site attack the problem differently. In Q-Learning Gridworld the agent learns a value for each state-action pair by trial and error and reads off the best path, rather than searching a space of whole policies. In Multi-Armed Bandit Lab you compare strategies for the pure exploration-versus-exploitation trade-off, which is the same tension you see when choosing the elite fraction and noise floor here.
Frequently asked questions
Why does the mean episode length lag behind the best?
The best line reflects one lucky or well-placed sample; the mean averages all 30, including the poor ones sampled from the still-wide tails of the Gaussian. As sigma shrinks, the samples cluster near the mean of the elites, so the average survival time rises to meet the best. The gap closing is the visible signature of convergence.
Does CEM need reward shaping or discounting?
No. CEM only ranks whole policies by their total return, which here is the raw episode length. It never looks at per-step rewards or a discount factor, so there is nothing to shape. That simplicity is also why it ignores information a gradient method would use.
Could a neural network do better than the linear policy?
Not on standard CartPole. The task is linearly solvable, so a network adds parameters without adding capability, and more parameters make the Gaussian harder to estimate from 30 samples. Networks pay off on harder tasks where a linear policy cannot represent the needed behavior.
Why does my run sometimes fail to reach 500 steps?
Usually premature collapse: the standard deviation fell to near zero on a mediocre policy. Restarting reseeds the Gaussian and often succeeds. Adding a small noise floor to sigma each generation makes success more consistent by keeping some exploration alive.
Is 12 degrees the only thing that ends an episode?
No. An episode also ends if the cart runs off the track or if you reach the 500-step cap. The 500-step cap is what "solved" means here: a policy that survives the maximum allowed steps.