Function approximation, DQN and learning from fixed data
Before this lesson: lesson 05 (Q-learning, the maximization bias, double Q-learning); lesson 04 (MC and TD targets); neural networks and the training loop (deep learning 01, deep learning 02); SGD (optimization 05); gradients (calculus 02). Time: about 85 minutes, plus the notebook.
Why this matters #
Every deep RL method uses function approximation. DQN (Mnih et al., 2015) learned 49 Atari games from pixels with one architecture and one set of hyperparameters, and reached a level comparable to a professional human tester. Its two stabilisers, experience replay and target networks, are now in almost every off-policy method: DDPG, TD3 and SAC (lesson 08) use them too. The deadly triad explains why these methods can be unstable and how to debug them. Offline RL matters wherever new experiments are costly or unsafe and only logs exist: recommendation, robotics from recorded demonstrations, decisions in operations and medicine.
1. Predict first #
2. The picture #
From a table to a function #
A parametrized value function has a weight vector with much smaller than the number of states. The simplest case is linear:
The vector is the feature vector of state . Three common choices:
- One-hot features, one per state: this is the table again ( = number of states).
- State aggregation: group the states; is the one-hot vector of the group of . All states in a group share one value, so the value function is a staircase.
- Tile coding: several overlapping grids (tilings) over a continuous state; has one 1 per tiling. Nearby states share many tiles, so they get similar values.
A neural network is the nonlinear case: the last layer is linear in features that the network learns itself.
Which weights are best? We can only be good where we are often, so the error is weighted by the on-policy distribution , the fraction of time the policy spends in :
With fewer weights than states, can usually not be 0: making the value right in one state makes it wrong in another, and decides which states matter more.
Two ways to fit: Monte Carlo targets and TD targets #
As in lesson 04, each update moves the value of the current state towards a target , now through the weights:
- Gradient Monte Carlo uses the return, .
- Semi-gradient TD(0) uses the bootstrapped target, (and when is terminal).
The 1000-state random walk (Sutton and Barto, Example 9.1) compares them. States 1 to 1000, start in state 500. Each step jumps 1 to 100 states to the left or to the right, all 200 moves equally likely. A jump past state 1 ends the episode with reward , past state 1000 with reward ; . We use state aggregation with 10 groups of 100 states.
Predict which staircase fits better, then press "Train 1000 episodes" a few times. The dashed black line is the true value . The aqua staircase is gradient Monte Carlo, the violet one semi-gradient TD(0), both trained on the same episodes. The grey curve at the bottom is the on-policy distribution (the walk spends most time in the middle). "Show the limits" draws where each method converges. Notice where TD is worse: at the ends, where is small.
What you see. Gradient MC converges to the best staircase: in each group, the -weighted average of the true values (). Semi-gradient TD converges to a different staircase: too flat at the ends (, more than four times larger). TD's error at one group leaks into its neighbours through the bootstrapped targets. TD is still often preferred in practice: it learns online, before the episode ends, and with lower variance.
When the target moves: the example #
Bootstrapping with a function has a new danger. Take two states that share one weight (Sutton and Barto §11.2). The first has feature , so its value is ; the second has , value . From the first state the agent moves to the second with reward 0; from the second the episode ends with reward 0. All true values are 0, and represents them exactly.
Suppose the data contain only the first transition (an off-policy distribution: the second state is never updated). The TD error and the update are
For the factor is larger than 1, and grows geometrically. Each update raises to move the first value towards ; but that also raises the target , and by more.
Move across , then switch the updates to "both states". The chart shows on a log scale over 100 episodes, starting from . With only the first state updated (magenta), grows for every , even though is exactly right. With on-policy updates (blue), the second state is also updated, towards its own target 0, with gradient . This pulls back, and it shrinks to 0.
In the example with only the first state updated, and . What happens to , starting from ?
The factor is , so grows geometrically (slowly). The contraction argument of lesson 02 is about tables; with a shared weight and off-policy updates it does not apply. forgets the step size .
3. Definitions and main results #
Gradient Monte Carlo is SGD; semi-gradient TD is not #
Gradient Monte Carlo is stochastic gradient descent on . The gradient of is . The states of an episode are visited with frequencies , and . So the update is, on average, a step along : SGD (see optimization 05). With Robbins–Monro step sizes it converges to a local minimum of , the global one in the linear case.
Semi-gradient TD is not. Its target depends on , but the update treats it as a constant: it differentiates only the prediction . That is why it is called semi-gradient. The full gradient of would also contain the term ("residual gradient" methods use it; they are slower and need two independent samples of to be unbiased).
For linear features we can say more. Write . The expected semi-gradient TD update is
with after a terminal state. A vector field is the negative gradient of some function only if its Jacobian is symmetric. Here is not symmetric in general, so semi-gradient TD does not minimize any fixed loss. The guarantees of SGD do not apply; convergence must be proved separately.
Theorem (linear TD on-policy; Tsitsiklis and Van Roy, 1997). With linear features, data from the on-policy distribution , and Robbins–Monro step sizes, semi-gradient TD(0) converges with probability 1 to the TD fixed point
The key step of the proof shows that is positive definite under the on-policy distribution, so the expected update is stable.
The TD fixed point: what it solves and how good it is
Projected Bellman equation. Let be the matrix with rows , , and the projection onto the span of the features in the -weighted norm . The condition is : the Bellman error is orthogonal to the features. Equivalently, : the TD solution is a fixed point of "apply the Bellman operator, then project". Gradient MC instead finds , the projection of the true values.
Error bound (continuing tasks with ; Sutton and Barto eq. 9.14):
The proof uses that is a -contraction in when is the on-policy distribution (this is where on-policy matters). For close to 1 the factor can be large, but in practice TD is often close to the best fit. In the random walk (, episodic) the bound does not apply, and TD's error is 4.6 times the best.
Off-policy. With a distribution , can have eigenvalues with negative real part, and then the expected update diverges. The example is the smallest case: gives for . Gradient-TD methods (GTD2, TDC) minimize the projected Bellman error with true gradients and are stable off-policy, at the cost of a second set of weights.
The deadly triad #
The deadly triad (Sutton and Barto §11.3) is the combination of
- function approximation: values share parameters (linear or nonlinear), so an update in one state changes others;
- bootstrapping: targets use current estimates, as in TD and Q-learning, not complete returns;
- off-policy training: the data come from a distribution other than the one of the policy being evaluated.
With all three, the values can diverge, even with exact expected updates and a function class that can represent the true values. With any two of the three, instability can be avoided: tabular Q-learning (no approximation) converges; gradient Monte Carlo (no bootstrapping) is SGD; linear TD on-policy converges to the TD fixed point. Q-learning with a neural network has all three: approximation, a bootstrapped target, and a greedy target policy that differs from the ε-greedy behaviour. DQN's tricks do not remove the triad, but they make divergence much less likely in practice.
A method uses a neural network for and learns from a replay buffer of old ε-greedy data with the Q-learning target. Which single change removes one part of the deadly triad?
The triad is function approximation, bootstrapping and off-policy data. Monte Carlo returns do not bootstrap, so that part is gone (but with old off-policy data the returns belong to the old policy and need corrections). A larger buffer makes the data more off-policy, not less; the Huber loss and the target-network period change the stability in practice, but the three ingredients are still there.
DQN #
Deep Q-network (DQN) (Mnih et al., 2015) is Q-learning with a neural network that outputs one value per action. For a minibatch of transitions , where if the episode ended at , it minimizes
where is the squared loss or the Huber loss, and no gradient flows through . The factor makes the target at the end of an episode. With the Huber loss for and otherwise, the gradient is : a large TD error cannot produce a huge step. (The Nature DQN clipped the error term to , which is the same.)
Two tools make the regression stable:
- Replay buffer. Store the last transitions (one million in the Atari DQN) and train on random minibatches (32). Consecutive steps are strongly correlated, and SGD assumes roughly independent samples; random samples from many episodes are much less correlated. Each transition is also used many times, which saves data. Replay needs an off-policy method: the stored actions came from older policies. Q-learning is off-policy.
- Target network , a copy of that is updated only every steps ( = 10 000 parameter updates in the Atari DQN). Between copies the targets do not depend on , so each phase is an ordinary regression problem with fixed labels. Without it, a step that raises also raises for similar states, and the target runs away from the prediction. A smooth alternative is Polyak averaging: after every step, with small such as (used by DDPG, TD3, SAC).
Press "Next step" six times to walk through one iteration of DQN: act, store, sample, compute targets with the target network, take a gradient step on the online network, and copy. Then switch to "moving target". There, a linear Q-network with two weights must learn the values of two states, (aqua), from off-policy data, and the second state's feature doubles the first one's weight. The blue path shows the values over 1000 updates; the violet dots are the regression targets after each copy. Predict first: with (no target network), do the values reach the aqua point? Then try larger , and on-policy data.
The moving-target view shows a real effect, not only an intuition. With the expected updates spiral away (the error grows by a factor 1.024 per step); with each period of 50 steps shrinks the error by a factor 0.805, and the values converge. With on-policy data even converges, as the theorem above promises. But a target network is not a guarantee: in the example any still diverges, because there the regression itself asks for at each copy.
Other details of the Atari DQN. The input is the last 4 frames (84 × 84 grey images) stacked, so that the network can see motion; the agent repeats each action for 4 frames; rewards are clipped to ; ε falls linearly from 1.0 to 0.1 over the first million frames; ; the optimizer is RMSProp.
Double DQN #
DQN inherits the maximization bias of lesson 05: is a max over noisy estimates, and bootstrapping carries the overestimation backwards. Double DQN (van Hasselt, Guez and Silver, 2016) applies the double estimator with the two networks that DQN already has: the online network selects, the target network evaluates:
The two networks are not independent, so the bias is reduced, not removed. The change is one line of code, and on Atari it gave much less overestimation and better scores.
Press "Repeat 1000 times". Ten actions all have true value 0; the online and target networks have independent errors of size . The orange histogram is the DQN target (the max of the target network): its mean is about . The violet histogram is the double DQN target (target network at the online network's argmax): its mean is about 0.
For one transition, , , not done. The online network gives and the target network . What are the DQN and the double DQN targets?
DQN takes the max of the target network: . Double DQN lets the online network choose (action 2, value 5.0) and the target network evaluate it: . The option uses the online network's own max, which is neither method.
Later extensions, combined in Rainbow (Hessel et al., 2018); each one line:
| extension | idea |
|---|---|
| double DQN | the online network selects, the target network evaluates (above) |
| prioritized replay | sample transitions with large TD error more often; correct with importance weights |
| dueling network | two heads, ; learns even for actions not taken |
| multi-step targets | -step returns : faster propagation |
| distributional RL (C51) | learn the distribution of the return, not only its mean |
| noisy nets | learned noise in the weights replaces ε-greedy exploration |
For continuous actions the max over is not available; DDPG, TD3 and SAC learn an actor for it, and TD3 and SAC use clipped double Q (the smaller of two critics) against overestimation (lesson 08).
Learning from a fixed dataset (offline RL) #
In offline RL (also called batch RL), the agent learns from a fixed dataset of transitions collected by some behaviour policy , and it cannot collect new data. Off-policy methods such as DQN can, in principle, learn from any data. In practice they often fail offline:
- The target asks for the values of all actions in , including actions that rarely or never took there: out-of-distribution (OOD) actions.
- No data point ever corrects the value of an OOD action, so its value is whatever the network extrapolates: this is extrapolation error.
- The max picks the largest of these values, which are often too large, and bootstrapping carries the error to earlier states. The learned policy prefers exactly the actions that the data do not support.
Online, the agent would try such an action, see the real reward and correct the value. Offline it cannot. This is the maximization bias of lesson 05 in its strongest form: the noise is not small sampling noise but unconstrained guesses.
Conservative Q-learning (CQL) (Kumar et al., 2020) adds a penalty to the TD loss. In its basic form, for each state of the data, with the action taken in the data,
(Here is the weight of the penalty, not a step size.) The log-sum-exp is a soft maximum over all actions. The gradient of the penalty with respect to the values in state is
So gradient descent pushes every action down in proportion to its softmax weight, which is largest for the most over-valued actions, and pushes the data action up. Unsupported high values fall the most. Kumar et al. prove that, for large enough, the learned value of the policy, , is a lower bound on its true value; single values of data actions can still be pushed above their true values.
Press "50 steps" with , then set and press again. One state, three actions, a one-step decision (the target is the reward). The dashed lines are the true values . The data contain only (grey coverage bars); the magenta actions never appear in the data. The values start at : the network's guess for is an extrapolation error, and the greedy action (orange outline) is . Plain offline Q-learning () never changes it. The CQL penalty pushes down and up until is greedy.
Two other families avoid OOD actions in other ways:
- Policy constraints keep the learned policy close to the behaviour policy. TD3+BC (Fujimoto and Gu, 2021) adds a behaviour-cloning term to the actor loss: maximize .
- Implicit Q-learning (IQL) (Kostrikov et al., 2022) never queries actions outside the data: it learns values only from dataset actions (with expectile regression), then extracts a policy by weighted behaviour cloning.
Behaviour cloning itself, learning the policy by supervised learning on the data actions, is in lesson 10.
CQL is applied in a state with , and the data action is . What is the sign of the penalty's gradient for , and what does gradient descent do to ?
The gradient is . Here , so the gradient is , and gradient descent moves up. For any data action the softmax weight is below 1, so the gradient is negative: CQL raises data actions and lowers the others. Descent moves against the sign of the gradient.
Answers to section 1. (1) No. On-policy linear TD converges to the TD fixed point , which can have a larger than the best weights (on the random walk, 0.0136 vs 0.0030); gradient MC finds the best weights. (2) Yes: grows for . Function approximation, bootstrapping and the off-policy distribution are all present. (3) Nothing corrects it: no data point contains , so stays at 3 (or drifts with the network), the max picks it, and bootstrapping spreads the overestimate to earlier states.
4. Worked example #
(a) DQN and double DQN targets. One transition with , , not done (). Online network: . Target network: .
- DQN: (action 3), so .
- Double DQN: the online network selects $\arg\max_{a'} Q_\theta(s', a') = $ action 2 (value 5.0).
- The target network evaluates action 2: , so .
- If the episode had ended at (), both targets would be .
The two networks disagree about the best action. The DQN target takes a max over the noise of one network, and so it is the higher, more optimistic one.
(b) Divergence in numbers. The example with , , , only the first state updated:
- Factor per update: .
- After 50 updates: . The true value is 0.
- On-policy, each episode also updates the second state: , gradient , so . One episode multiplies by , and .
(c) The CQL penalty for one state. Three actions with ; the data contain only action 1.
- Log-sum-exp: .
- Penalty: .
- Softmax: .
- Gradient: .
Gradient descent raises and lowers the most: the unsupported value 3.0 falls fastest.
5. In code #
The cells below check the worked example with NumPy. In a real DQN the same target code runs on batches; the notebook writes it with done flags and adds fitted Q-iteration with a scikit-learn regressor, a DQN-like method without a deep-learning library.
import numpy as np
from scipy.special import logsumexp, softmax
# (a) DQN vs double DQN, vectorized over a batch with done flags
r = np.array([0.0, 1.0]); done = np.array([0.0, 1.0]); gamma = 0.99
q_online_next = np.array([[1.0, 5.0, 2.0], [0.0, 0.0, 0.0]])
q_target_next = np.array([[1.5, 3.0, 4.0], [9.0, 9.0, 9.0]])
y_dqn = r + gamma * (1 - done) * q_target_next.max(axis=1)
a_star = q_online_next.argmax(axis=1)
y_double = r + gamma * (1 - done) * q_target_next[np.arange(2), a_star]
print(y_dqn, y_double) # [3.96 1. ] [2.97 1. ]
# (b) the w -> 2w example
alpha, gamma = 0.1, 0.9
w = 1.0
for _ in range(50):
w += alpha * (gamma * 2 * w - w) * 1.0 # only the first state, feature 1
print(round(w, 1), round(1.08 ** 50, 1)) # 46.9 46.9
# (c) CQL penalty and its gradient for one state, data action a_1
Q = np.array([1.0, 0.5, 3.0])
print(round(logsumexp(Q) - Q[0], 3)) # 2.197
print((softmax(Q) - np.eye(3)[0]).round(3)) # [-0.889 0.067 0.821]
The done flag matters in the second transition: its target is the reward 1.0, not .
6. Where it shows up #
- Games and control from pixels. DQN and Rainbow on Atari; the replay buffer and target network (or Polyak averaging) are in DDPG, TD3, SAC and most off-policy deep RL code (CleanRL, Stable-Baselines3).
- Recommendation and operations. Q-learning with function approximation is trained on logs of user sessions or system states; this is offline or nearly offline RL, so extrapolation error and conservative methods matter.
- Robotics from recorded data. Large offline datasets of robot interaction are trained with conservative or constrained Q-learning before any real deployment.
- Language models. Value-based offline RL ideas (implicit Q-learning, conservative values) appear in methods that fine-tune language models from logged conversations with rewards.
- ML for science. Control of physical processes from logged sensor data (for example fusion or chemical plant operation logs) is offline RL: the logged actions cover only safe operating regions, and a plain Q-learner would trust its guesses outside them. Fitted Q-iteration with tree ensembles is a common, stable baseline on such tabular, low-dimensional data.
7. Common mistakes #
- Gradient through the target. In DQN the target is a constant (
torch.no_grad()or.detach()). Backpropagating into it gives a different method (residual gradient), usually slower. - Forgetting the done flag. At a terminal transition . Without the agent adds the value of a state that does not exist; with time limits, a transition cut by the time limit is not terminal.
- "Semi-gradient TD minimizes the squared TD error." It does not minimize any fixed loss; on-policy linear TD converges to the TD fixed point, which is not the minimizer of .
- "The target network removes the deadly triad." It makes each phase a regression with fixed labels and often helps a lot, but divergence is still possible (the example diverges for every ).
- "Double DQN needs two new networks." It reuses DQN's online and target networks; only the target formula changes.
- Trusting offline Q-values. A high value for an action that is rare in the data is a warning sign, not a discovery. Check the data coverage and evaluate the policy with off-policy evaluation before deployment.
- Mixing up the two . In CQL, is the penalty weight; the learning rate of the network is .
8. Check yourself #
- Why is gradient MC true SGD on , but semi-gradient TD is not SGD on any loss?
Answer
MC's target does not depend on and has mean , so the update is an unbiased sample of . TD's target depends on but is treated as a constant; the expected update has the non-symmetric Jacobian , so it is not the gradient of any function. - Name the three parts of the deadly triad and one method that avoids each.
Answer
Function approximation (tabular Q-learning), bootstrapping (gradient Monte Carlo), off-policy data (on-policy linear TD). - With and , what is the factor per update in the example, and per episode with on-policy updates?
Answer
Off-policy: (diverges). On-policy: (converges). - What does the replay buffer fix, and what does the target network fix?
Answer
Replay: strongly correlated consecutive samples (and it reuses data). Target network: the regression target that moves with every gradient step; with fixed, each phase is a regression with fixed labels. - Compute the DQN and double DQN targets for , , not done, , .
Answer
DQN: . Double DQN: the online network picks action 1, the target network gives 1, so . - Why does offline Q-learning overestimate more than online Q-learning, and how does CQL respond?
Answer
The max in the target queries actions that the data never contain; their values are never corrected, and the max picks the largest guesses. Online, the agent would try them and correct them. CQL adds , which pushes all values down by their softmax weight and the data action up.
Write the semi-gradient TD(0) update for a parametrized value function.
; the target is treated as a constant.
Why is it called "semi-gradient"?
The target depends on , but the update differentiates only the prediction , not the target.
Name the three parts of the deadly triad.
Function approximation, bootstrapping, and off-policy training.
In the example, what is the factor per update of the first state?
; it is above 1 (divergence) for .
Write the DQN target.
, with the target network and no gradient through .
Write the double DQN target.
: the online network selects, the target network evaluates.
What is the purpose of the replay buffer?
Train on random minibatches of past transitions: less correlated samples than consecutive steps, and each transition is reused many times.
What is the purpose of the target network?
Keep the regression labels fixed for steps, so each phase is ordinary regression and the target does not run away with every gradient step.
What is extrapolation error in offline RL?
Values of actions that the dataset never contains are never corrected by data; the max in the target picks these guesses and bootstrapping spreads them.
Compute the CQL penalty gradient for with data action .
.
9. Interview angle #
- "Why does DQN need a target network?" The target depends on the same weights; a step that raises also raises and the target runs away. A frozen copy makes each phase a regression with fixed labels.
- "Why a replay buffer? What does it require?" It decorrelates the samples and reuses data; it requires an off-policy learner, since the stored actions came from older policies.
- "Why can Q-learning with neural networks diverge?" The deadly triad: approximation, bootstrapping, off-policy data. Give the example: factor .
- "Where does overestimation come from, and how does double DQN fix it?" The max over noisy estimates; the online network selects, the target network evaluates. TD3 and SAC take the min of two critics.
- "Why is offline RL hard, and what does CQL do?" Out-of-distribution actions and extrapolation error; CQL penalizes the soft max of and rewards data actions, which gives conservative values. Alternatives: policy constraints (TD3+BC), IQL.
- "Does TD with linear features converge to the best fit?" On-policy it converges, but to the TD fixed point, not to the minimizer; gradient MC finds the minimizer.
10. Practice #
The notebook for this lesson runs in Colab. It has five exercises, each with a check cell and a folded solution:
- Gradient MC and semi-gradient TD(0) with state aggregation on the 1000-state random walk; compare with the exact fixed points computed by linear algebra.
- The example: divergence with off-policy updates and convergence with on-policy updates.
- Vectorized
dqn_targetsanddouble_dqn_targetswith done flags. - Fitted Q-iteration with a scikit-learn regressor on a small task with a continuous state: a batch, DQN-like method where each iteration is one regression with a frozen target.
- Offline Q-learning on a gridworld with partial data coverage, then with a CQL penalty: measure the overestimation.
11. Watch and read #
- Richard Sutton and Andrew Barto, Reinforcement Learning: An Introduction, 2nd ed., free PDF: chapter 9 (§9.1–9.5: , gradient MC, semi-gradient TD, linear methods and the TD fixed point; Example 9.1 is the 1000-state random walk) and §11.1–11.3 (off-policy divergence, the example, the deadly triad).
- Volodymyr Mnih et al., Human-level control through deep reinforcement learning, Nature 2015: the DQN paper; its Methods section lists all hyperparameters.
- Hado van Hasselt, Arthur Guez, David Silver, Deep Reinforcement Learning with Double Q-learning.
- Matteo Hessel et al., Rainbow: Combining Improvements in Deep Reinforcement Learning.
- Sergey Levine, Aviral Kumar, George Tucker, Justin Fu, Offline Reinforcement Learning: Tutorial, Review, and Perspectives on Open Problems, §1–4.
- Aviral Kumar, Aurick Zhou, George Tucker, Sergey Levine, Conservative Q-Learning for Offline Reinforcement Learning.
- Costa Huang et al., CleanRL single-file DQN: about 200 lines that contain everything in section 3.
Runs in your browser with nothing to install. The notebook repeats the key demos and has exercises with checks; solutions are inside, folded.
No Google account needed: Python runs inside your browser. The first start downloads about 40 MB; your changes are saved in this browser only.