Deep Q-Learning

Machine Learning Notes · reinforcement learning 2 of 2 · Deep Q-learning ← Foundations back to the hub →

The previous note ended with a table of twelve numbers: two actions in each of six states, solved exactly with algebra because the rewards and the transitions were known in advance. Neither luxury survives contact with a real problem. A lander falling toward a pad has a state made of real numbers, so there is no table to fill in, and it does not know what a thruster does until it fires one.

This note is the bridge. The Bellman equation stops being an identity to solve and becomes a training target for a neural network, which turns the whole of reinforcement learning into a supervised learning problem that keeps rewriting its own labels.

In one line. Approximate $Q(s,a)$ with a network. For a stored transition $(s,a,r,s')$, the Bellman equation says the answer should be $y = r + \gamma \max_{a'} Q(s',a')$ — so use that as the label and fit by least squares. Act $\varepsilon$-greedily so the data keeps improving, replay old transitions so the batches are not correlated, and compute the target with a delayed copy of the network so the labels hold still long enough to be learned.

Contents
  1. Discrete states, and why they run out
  2. The lunar lander
  3. Approximating $Q$ with a network
  4. Turning Bellman into supervised learning
  5. Building the targets, worked
  6. The learning loop
  7. Exploration and $\varepsilon$-greedy
  8. The moving target, and how to slow it down
  9. Pitfalls
  10. Where this goes next

Discrete states, and why they run out

A discrete state space is a finite set — the six cells of the rover's strip. The state is an index, $V(s)$ and $Q(s,a)$ live in arrays, and exact dynamic programming applies. It is simple and it does not scale: describing the world by which of six boxes you are in is a very coarse description of anything.

Continuous state

A ground vehicle is better described by a vector of real numbers — where it is, which way it is pointing, and how fast each of those is changing:

$$ s = \begin{bmatrix} x \ y \ \theta \ \dot{x} \ \dot{y} \ \dot{\theta} \end{bmatrix} \qquad\qquad \text{a helicopter needs twelve: } \; \begin{bmatrix} x & y & z & \phi & \theta & \psi & \dot{x} & \dot{y} & \dot{z} & \dot{\phi} & \dot{\theta} & \dot{\psi} \end{bmatrix}^{\mathsf{T}} $$

There are now infinitely many states, so no table can be stored. The obvious escape — chop each axis into bins and go back to a table — fails for a reason worth seeing rather than asserting:

Figure 1: The size of a discretised table against the number of state variables, on a logarithmic axis, for three different bin counts per axis. Each extra variable multiplies the table by the bin count, so the lines are straight on a log scale and their slope is the only thing that differs. At a coarse 10 bins per axis the rover's 6 variables already need a million entries, the lander's 8 need a hundred million, and the helicopter's 12 need a million million — 4 TB at four bytes each, for a description so crude it cannot tell two nearby positions apart. This is the curse of dimensionality, and no amount of memory fixes it.

The only way forward is function approximation: represent $Q(s,a)$ as a parametrised function — linear features, a kernel, or a neural network — and fit its parameters. A network with a few thousand weights covers the whole space, and, unlike a table, what it learns at one state transfers to the states nearby.

Choosing a Markov state

The state must satisfy the Markov property to be usable:

$$ P\left(S_{t+1} \mid S_t = s,\, A_t = a,\, \text{history}\right) = P\left(S_{t+1} \mid s, a\right). $$

This is a design constraint, not a fact of nature. Position alone is not Markov for a moving vehicle — where it will be next depends on how fast it is going — so the velocities have to be in the state. Where sensors are noisy the raw reading is not Markov either, and a state estimator (a Kalman filter, say) is used to produce something that is.


The lunar lander

State and actions

A 2-D lander must touch down between two flags. The state is eight numbers:

$$ s = \begin{bmatrix} x & y & \dot{x} & \dot{y} & \theta & \dot{\theta} & \ell & r \end{bmatrix}, \qquad \ell, r \in \{0, 1\} . \tag{1} $$
Equation 1: The lunar lander's state. Six continuous quantities plus two binary flags; $\ell$ and $r$ say whether the left and right legs are touching the ground, which is how the agent can tell a landing from a hover.

The action space is discrete — four choices: do nothing, fire the left thruster, fire the main engine, fire the right thruster. Continuous state with discrete actions is exactly the combination value-based methods handle well, which is why this task is the standard example.

The shaped reward

EventReward
Getting to the pad and stabilising thereabout $+100$ to $+140$ in total
Soft landing (terminal)$+100$
Crash (terminal)$-100$
Each leg grounded$+10$
Firing the main engine, per step$-0.3$
Firing a side thruster, per step$-0.03$
Table 1: The lunar lander's reward function. The terminal rewards alone would be almost impossible to learn from — a random agent crashes for a very long time before it ever lands — so the reward is shaped: moving toward the pad pays continuously, and firing engines costs a little, which is what makes the problem learnable in reasonable time.

The objective is the usual one — find $\pi$ maximising $\mathbb{E}\pi\left[\sum_t \gamma^t R\right]$ — with $\gamma \approx 0.985$, high enough that a landing several hundred steps away still carries real weight. That claim is checkable: the share of the total discounted weight that falls within the first $N$ steps is $1 - \gamma^N$, so

Figure 2: How far ahead each discount factor actually looks — the fraction of all discounted weight lying within the first $N$ steps. At the lander's 0.985 the curve passes half at step 46 and 95 percent at step 198, so a touchdown 200 steps out is still most of what the agent is optimising. At 0.9 the whole horizon is over inside 50 steps, which is why that value would make the lander hover: the landing bonus would be worth almost nothing by the time it arrived.

Approximating $Q$ with a network

Two arrangements are used, and it is worth knowing both because the slides show one and every implementation uses the other:

Either way, acting greedily means $a^\ast = \arg\max_a Q_\theta(s,a)$.


Turning Bellman into supervised learning

The target

The Bellman equation from the previous note says what $Q(s,a)$ ought to equal. Take that right-hand side and call it a label:

$$ x = (s, a), \qquad y = \begin{cases} r & \text{if done}, \\[4pt] r + \gamma \max_{a'} Q\left(s', a'\right) & \text{otherwise}, \end{cases} \tag{2} $$
Equation 2: The Bellman target. The input is the state-action pair actually experienced; the label is the reward that actually arrived plus the discounted value of the best action available next. When the episode ended there is no next state, so the label is just the reward — that is the done case, and forgetting it is the classic bug.

and now it is ordinary regression: fit $f_{W,B}(x) \approx y$ by least squares. The strange part is that the labels are produced by the network being trained — §8 is about the trouble that causes.

Why one step reaches the whole future

The target only looks one step ahead, yet a lander is rewarded hundreds of steps later. $Q(s', a')$ is defined by the same equation, so its own value already contains the step after that, and so on:

$$ Q(s_t, a_t) \approx r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \cdots $$

Information about a distant reward travels backwards one link per update. It is slow, and it is why deep RL needs so many episodes — but it does arrive.


Building the targets, worked

Three transitions from the replay buffer, $\gamma = 0.99$:

action$r$done$Q(s', \cdot)$ for the four actions$\max_{a'} Q(s',a')$target $y$
1main$-0.1$False$[\,1.2,\; 0.5,\; \mathbf{2.0},\; -0.3\,]$$2.0$$-0.1 + 0.99(2.0) = \mathbf{1.88}$
2left$+0.3$False$[\,0.7,\; 0.6,\; \mathbf{0.9},\; 0.1\,]$$0.9$$0.3 + 0.99(0.9) = \mathbf{1.191}$
3right$+100$True— episode over —$\mathbf{100}$
Table 2: Three transitions turned into three training labels. Row 1 has a negative immediate reward but a good future and ends up with a positive target; row 3 is terminal, so the future term vanishes and the label is the raw +100. The max in each row is taken over the four action-values of the next state, not the current one.

The three training pairs are $x^{(i)} = \left(s^{(i)}, a^{(i)}\right)$ against $y = [\,1.88,\; 1.191,\; 100\,]$, and the network is updated by gradient descent on

$$ L(\theta) = \frac{1}{3}\sum_{i=1}^{3}\left(Q_\theta\left(x^{(i)}\right) - y^{(i)}\right)^2 . $$

Nothing here is specific to reinforcement learning any more — it is the mean squared error of note 1, fitted to labels that happen to have been manufactured by the Bellman equation.


The learning loop

The algorithm

Figure 3: The DQN loop. Only the middle branch trains anything; the left branch exists to generate data, and the two run interleaved forever. The dashed part of the cycle — new parameters changing which actions get taken, which changes the data collected — is what makes reinforcement learning different from fitting a fixed dataset.

In the sizes Ng uses for the lander: keep the most recent 10,000 transitions, and train on random minibatches of 1,000 of them.

initialize Q-network parameters θ randomly
D = empty replay buffer (capacity 10,000)

loop over episodes:
    reset the environment, observe s
    repeat for each step:
        a = epsilon_greedy(Q_θ, s)              # explore or exploit
        execute a, observe r and s'
        store (s, a, r, s', done) in D          # oldest tuple falls out

        sample a minibatch of N = 1000 from D
        for each sample:  y_i = r_i                         if done
                          y_i = r_i + γ max_a' Q(s'_i, a')  otherwise
        take a gradient step on  (1/N) Σ (Q_θ(s_i, a_i) − y_i)²
        every K steps:  θ̄ ← θ                  # refresh the target network

Why a replay buffer

Two reasons, both about the data rather than the algorithm:


Exploration and $\varepsilon$-greedy

Why act randomly on purpose

Early in training $Q_\theta$ is nonsense — it was initialised at random. An agent that always takes $\arg\max_a Q_\theta(s,a)$ will act on that nonsense, and here is the trap: if the network happens to underrate firing the main engine, the agent never fires it, never sees the reward it would have produced, and never gets the data that would correct the estimate. The mistake is self-sealing.

The fix is to sometimes act at random. With probability $1-\varepsilon$ take the greedy action; with probability $\varepsilon$ pick uniformly among all actions.

The probabilities

With $K$ actions, the greedy one is also in the random draw, so:

$$ \Pr(a^\ast \mid s) = 1 - \varepsilon + \frac{\varepsilon}{K}, \qquad \Pr(a \ne a^\ast \mid s) = \frac{\varepsilon}{K}. $$

Worked, with the network outputting $[\,Q(s,\text{nothing}), Q(s,\text{left}), Q(s,\text{main}), Q(s,\text{right})\,] = [\,1.2,\, 0.7,\, 0.5,\, 1.1\,]$, so the greedy action is nothing, and $\varepsilon = 0.05$ with $K = 4$:

$$ \Pr(\text{nothing}) = 1 - 0.05 + \tfrac{0.05}{4} = 0.9625, \qquad \Pr(\text{left}) = \Pr(\text{main}) = \Pr(\text{right}) = \tfrac{0.05}{4} = 0.0125 . $$

So $96.25\%$ exploit and $3.75\%$ explore, split evenly over the three non-greedy actions.

Figure 4: How the four action probabilities move as $\varepsilon$ runs from pure exploitation to pure exploration, with $K = 4$. Both lines are straight, and they meet at $\varepsilon = 1$ — not at zero for the greedy action, but at $0.25$, because a uniform draw still picks the greedy action a quarter of the time. The marked pair is the worked case above. Note the asymmetry that makes small $\varepsilon$ useful: at $\varepsilon = 0.05$ the greedy action still runs 77 times as often as any single alternative, yet every alternative is guaranteed to be tried roughly once in 80 steps.

Annealing $\varepsilon$

The right amount of exploration changes over training: high at the start, when the estimates are worthless, and low later, when they are not. So $\varepsilon$ is decayed —

$$ \varepsilon_t = \max\left(\varepsilon_{\min},\; \varepsilon_{\max} - (\varepsilon_{\max} - \varepsilon_{\min})\tfrac{t}{T}\right) \quad\text{(linear)}, \qquad \varepsilon_t = \varepsilon_{\min} + (\varepsilon_{\max} - \varepsilon_{\min})e^{-t/\tau} \quad\text{(exponential)}, $$

typically from $\varepsilon_{\max} \approx 1.0$ down to $\varepsilon_{\min}$ between $0.01$ and $0.05$.

Figure 5: The two schedules over 1000 steps, from 1.0 down to 0.05. Linear decays at a constant rate and hits the floor exactly at $T$; exponential spends its exploration early — it is already below 0.5 by step 200, where the linear schedule is still at 0.81 — and then crawls. Which is better depends on whether the hard part of the problem is at the start.

Off-policy, and why that is fine. The agent behaves $\varepsilon$-greedily but the target uses $\max_{a'}$ — it learns the value of acting optimally while actually acting randomly some of the time. That mismatch is what "off-policy" means, and it is the property that lets a replay buffer full of old, worse-policy transitions still be useful.


The moving target, and how to slow it down

Target networks

There is something circular in §4: the labels $y = r + \gamma \max_{a'} Q_\theta(s',a')$ are computed from the network being updated. Every gradient step changes the labels, so the network is chasing a target that runs away from it — which oscillates and sometimes diverges.

The standard fix is a target network $Q_{\bar\theta}$, a delayed copy used only for computing labels:

$$ L(\theta) = \mathbb{E}_{(s,a,r,s') \sim D} \left[\left(Q_\theta(s,a) - \left(r + \gamma \max_{a'} Q_{\bar\theta}(s',a')\right)\right)^2\right], \qquad \bar\theta \leftarrow \theta \;\text{ every } K \text{ steps}. \tag{3} $$
Equation 3: The DQN loss with a target network. The gradient flows through $Q_\theta$ only; $Q_{\bar\theta}$ is treated as a constant, and is refreshed from $\theta$ every $K$ steps. That delay is what holds the labels still long enough to be fitted.

Soft updates (Polyak averaging)

Copying $\bar\theta \leftarrow \theta$ outright moves the targets abruptly every $K$ steps. A gentler version blends instead of replaces:

$$ \bar\theta \leftarrow \tau\,\theta + (1-\tau)\,\bar\theta, \qquad 0 < \tau \ll 1 \qquad\text{e.g. } \; W \leftarrow 0.01\,W_{\text{new}} + 0.99\,W . \tag{4} $$
Equation 4: The soft update. Each parameter takes a small step from its old value toward the new one, which makes the target network an exponential moving average of the online network's history — smoother targets, lower variance, no sudden jumps.

The trade is easiest to see by asking what each rule does when the online network moves. Let $\theta$ jump once, from $0$ to $1$, and watch $\bar\theta$ follow:

Figure 6: The response of the target network to a single step change in $\theta$. The hard update does nothing at all for $K$ steps and then closes the entire gap in one step — the targets are perfectly still, then discontinuous, and the loss spikes at every copy. The soft updates start moving immediately and never jump, at the price of never quite arriving: repeated application of $\bar\theta \leftarrow \tau\theta + (1-\tau)\bar\theta$ leaves a gap of $(1-\tau)^t$, so $\tau = 0.01$ is 63 percent of the way there after 100 steps and 90 percent after 229. The useful number is $1/\tau$ — the time constant in steps, so 50, 100 and 200 steps for $\tau = 0.02$, $0.01$ and $0.005$.

Neither column of that picture is obviously right, which is why both are in use. What they share is the property that matters: the labels move slower than the network being fitted, so each gradient step is aimed at something that has not already moved.


Pitfalls


Where this goes next

This completes the third course, and the arc of these notes: from fitting a line through classification, networks, evaluation and trees, to unsupervised structure, recommenders, and finally agents that generate their own data.

Deep Q-learning is the beginning of deep RL rather than the end of it. The natural next steps, in roughly the order they are usually met:

Backwards from here: foundations has the returns, policies and Bellman equation this note fits a network to; the network reference has the network itself; and model development is still the right place to look when training goes wrong.

Machine Learning Notes · reinforcement learning 2 of 2 · Deep Q-learning ← Foundations back to the hub →