Skip to content
AI360Xpert
Beta

Maximum Entropy RL

Score the goal and the spread. The policy keeps every good path alive in proportion to its value instead of collapsing to one narrow line.

Q values 2.0 and 1.0 give Boltzmann chances 0.7311 and 0.2689, entropy 0.5822, and soft value 2.3132
Q values 2.0 and 1.0 give Boltzmann chances 0.7311 and 0.2689, entropy 0.5822, and soft value 2.3132

Why Does This Exist?

Plain RL maxes expected reward:

J(π)=Eτ∼π[∑tγtR(st,at)]J(\pi) = \mathbb{E}_{\tau \sim \pi}\left[\sum_t \gamma^t R(s_t, a_t)\right]

That push collapses to one deterministic pick. Spread hits zero, backup routes vanish, and a small gust or slip breaks the run. Tasks with two equal doors keep only one.

Max entropy RL from Ziebart plus Haarnoja and Levine adds spread to the goal. Each step pays reward plus α\alpha times entropy H(π(⋅∣s))\mathcal{H}(\pi(\cdot \mid s)). Policies stay smooth and multimodal, with weight on every viable path. This page covers the objective and the soft values. The actor critic built on it lives in soft actor-critic. The tabular value form lives in soft Q-learning. Plain gradients live in policy gradient.

The one idea you need first

Entropy H\mathcal{H} measures spread: H(π)=Ea∼π[−log⁡π(a∣s)]\mathcal{H}(\pi) = \mathbb{E}_{a \sim \pi}[-\log \pi(a \mid s)]. Uniform is high, single spike is zero. Temperature α>0\alpha > 0 prices spread in reward units. Near zero recovers plain RL. Large values wander.

Think of It Like This

One ridge trail versus a mapped valley

A plain explorer finds one narrow ridge over a ravine and declares it the only route. All traffic walks single file. One fallen rock strands the party.

An entropy surveyor maps ridge, river path, and forest track, then splits traffic by safety and speed. A blocked ridge shifts walkers to the river with no panic.

Where it stops: hikers pick one path per trip. A MaxEnt policy is a full spread over actions at once, hedging every step instead of booking one trail.

How It Actually Works

Objective with temperature α\alpha:

JMaxEnt(π)=∑tE(st,at)∼π[γt(R(st,at)+αH(π(⋅∣st)))]J_{MaxEnt}(\pi) = \sum_t \mathbb{E}_{(s_t, a_t) \sim \pi}[\gamma^t (R(s_t, a_t) + \alpha \mathcal{H}(\pi(\cdot \mid s_t)))]

Hard max V(s)=max⁡aQ(s,a)V(s) = \max_a Q(s, a) turns soft:

Vsoft(s)=αlog⁡∑aexp⁡(Qsoft(s,a)/α)V_{soft}(s) = \alpha \log \sum_a \exp(Q_{soft}(s, a) / \alpha)

Action values still back up reward plus next soft value:

Qsoft(s,a)=R(s,a)+γEs′[Vsoft(s′)]Q_{soft}(s, a) = R(s, a) + \gamma \mathbb{E}_{s^\prime}[V_{soft}(s^\prime)]

Optimal policy is Boltzmann, in words exponentiated value over its sum:

π∗(a∣s)=exp⁡(Qsoft(s,a)/α)/Z(s)\pi^\ast(a \mid s) = \exp(Q_{soft}(s, a) / \alpha) / Z(s)

with Z(s)=∑a′exp⁡(Qsoft(s,a′)/α)Z(s) = \sum_{a^\prime} \exp(Q_{soft}(s, a^\prime) / \alpha). Better actions get exponentially more chance, weaker ones keep nonzero mass. As α\alpha drops to zero the soft value returns to hard max.

Worked example

One state, two actions, γ=0\gamma = 0, α=1.0\alpha = 1.0. Rewards give Q=[2.0,1.0]Q = [2.0, 1.0].

Partition:

Z=exp⁡(2.0)+exp⁡(1.0)=7.389056+2.718282=10.107338Z = \exp(2.0) + \exp(1.0) = 7.389056 + 2.718282 = 10.107338

Chances:

π1=7.389056/10.107338≈0.7311\pi_1 = 7.389056 / 10.107338 \approx 0.7311 π2=2.718282/10.107338≈0.2689\pi_2 = 2.718282 / 10.107338 \approx 0.2689

Sum is 1.00001.0000. Entropy in nats:

H=−[0.7311log⁡0.7311+0.2689log⁡0.2689]\mathcal{H} = -[0.7311 \log 0.7311 + 0.2689 \log 0.2689] H=−[0.7311×(−0.3132)+0.2689×(−1.3134)]≈0.5822\mathcal{H} = -[0.7311 \times (-0.3132) + 0.2689 \times (-1.3134)] \approx 0.5822

Mean reward:

E[R]=0.7311×2.0+0.2689×1.0=1.4622+0.2689=1.7311\mathbb{E}[R] = 0.7311 \times 2.0 + 0.2689 \times 1.0 = 1.4622 + 0.2689 = 1.7311

Total objective:

J=1.7311+1.0×0.5822=2.3133J = 1.7311 + 1.0 \times 0.5822 = 2.3133

Soft value check:

Vsoft=1.0×log⁡(10.107338)≈2.3132V_{soft} = 1.0 \times \log(10.107338) \approx 2.3132

Matches JJ to four places. Plain max would pay 2.002.00 on one spike. Soft pays 2.31322.3132 because it counts reward plus spread. Those are the numbers the diagram draws.

Code

This snippet uses only the standard library and prints the same partition, chances, entropy, mean, objective, and soft value.

import math
q1 = 2.0q2 = 1.0alpha = 1.0e1 = math.exp(q1 / alpha)e2 = math.exp(q2 / alpha)z = e1 + e2print(round(z, 4))  # -> 10.1073p1 = e1 / zp2 = e2 / zprint([round(p1, 4), round(p2, 4)])  # -> [0.7311, 0.2689]h = -(p1 * math.log(p1) + p2 * math.log(p2))print(round(h, 4))  # -> 0.5822mean = p1 * q1 + p2 * q2print(round(mean, 4))  # -> 1.7311print(round(mean + alpha * h, 4))  # -> 2.3133print(round(alpha * math.log(z), 4))  # -> 2.3132

Soft value 2.31322.3132 matches objective 2.31332.3133 up to rounding, which is the identity the page claims.

Watch Out For

Leaving temperature fixed for the whole run

One α\alpha cannot serve early roaming and late control. High α\alpha drowns reward in noise and walks at random. Low α\alpha collapses early to one spike and keeps plain RL flaws. A single static value picks one failure.

Track spread and move α\alpha against a target. In soft actor-critic style tuning, raise α\alpha when entropy falls below target and lower it when entropy runs hot. Log α\alpha, entropy, and mean reward together.

Reading soft value as plain best value

VsoftV_{soft} at 2.31322.3132 tops plain max 2.002.00 because it adds spread value. Treating it as achievable reward overstates the policy and breaks comparisons with hard backups.

Label soft and hard separately. Compare policies by sampled mean reward plus measured entropy, not by soft value alone. Convert only when α\alpha is near zero.

The Quick Version

  • Objective is reward plus α\alpha times entropy at every step.
  • Hard max turns into log sum exp with temperature α\alpha.
  • Optimal policy is Boltzmann: chance proportional to exp⁡(Q/α)\exp(Q / \alpha).
  • Worked numbers: Z≈10.1073Z \approx 10.1073, chances 0.73110.7311 and 0.26890.2689, entropy 0.58220.5822.
  • Soft value 2.31322.3132 matches mean 1.73111.7311 plus entropy 0.58220.5822.