Type at least 2 letters. Enter opens the first result, Esc closes.

    Reinforcement Learning · Lesson 6 · Function approximation and policy optimization

    Function approximation, DQN and learning from fixed data

    Advanced 85 min 5 interactive figures 5 videos Colab notebook

    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 v^(s,w)≈Vπ(s)\hat v(s, w) \approx V^\pi(s) has a weight vector w∈Rdw \in \R^d with dd much smaller than the number of states. The simplest case is linear:

    v^(s,w)=w⊤x(s)=∑i=1dwi xi(s),∇wv^(s,w)=x(s).\hat v(s, w) = w^\top x(s) = \sum_{i=1}^d w_i\,x_i(s), \qquad \nabla_w \hat v(s, w) = x(s).

    The vector x(s)∈Rdx(s) \in \R^d is the feature vector of state ss. Three common choices:

    • One-hot features, one per state: this is the table again (dd = number of states).
    • State aggregation: group the states; x(s)x(s) is the one-hot vector of the group of ss. 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; x(s)x(s) has one 1 per tiling. Nearby states share many tiles, so they get similar values.

    A neural network v^(s,w)\hat v(s, w) 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 μ(s)\mu(s), the fraction of time the policy spends in ss:

    VE‾(w)=∑sμ(s) [Vπ(s)−v^(s,w)]2.\overline{VE}(w) = \sum_s \mu(s)\,\big[V^\pi(s) - \hat v(s, w)\big]^2 .

    With fewer weights than states, VE‾\overline{VE} can usually not be 0: making the value right in one state makes it wrong in another, and μ\mu 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 UtU_t, now through the weights:

    w←w+α [Ut−v^(st,w)] ∇wv^(st,w).w \leftarrow w + \alpha\,\big[U_t - \hat v(s_t, w)\big]\,\nabla_w \hat v(s_t, w).
    • Gradient Monte Carlo uses the return, Ut=GtU_t = G_t.
    • Semi-gradient TD(0) uses the bootstrapped target, Ut=rt+γ v^(st+1,w)U_t = r_t + \gamma\,\hat v(s_{t+1}, w) (and Ut=rtU_t = r_t when st+1s_{t+1} 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 −1-1, past state 1000 with reward +1+1; γ=1\gamma = 1. We use state aggregation with 10 groups of 100 states.

    Interactive figure: loading…

    Predict which staircase fits better, then press "Train 1000 episodes" a few times. The dashed black line is the true value Vπ(s)V^\pi(s). 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 μ\mu (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 μ\mu is small.

    What you see. Gradient MC converges to the best staircase: in each group, the μ\mu-weighted average of the true values (VE‾=0.0030\overline{VE} = 0.0030). Semi-gradient TD converges to a different staircase: too flat at the ends (VE‾=0.0136\overline{VE} = 0.0136, 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 w→2ww \to 2w example #

    Bootstrapping with a function has a new danger. Take two states that share one weight ww (Sutton and Barto §11.2). The first has feature x=1x = 1, so its value is ww; the second has x=2x = 2, value 2w2w. 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 w=0w = 0 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

    δ=0+γ⋅2w−w=(2γ−1) w,\delta = 0 + \gamma \cdot 2w - w = (2\gamma - 1)\,w,
    w←w+α δ⋅1=(1+α(2γ−1)) w.w \leftarrow w + \alpha\,\delta \cdot 1 = \big(1 + \alpha(2\gamma - 1)\big)\,w .

    For γ>1/2\gamma > 1/2 the factor is larger than 1, and ww grows geometrically. Each update raises ww to move the first value towards γ⋅2w\gamma \cdot 2w; but that also raises the target 2w2w, and by more.

    Interactive figure: loading…

    Move γ\gamma across 0.50.5, then switch the updates to "both states". The chart shows ∣w∣|w| on a log scale over 100 episodes, starting from w=1w = 1. With only the first state updated (magenta), ww grows for every γ>1/2\gamma > 1/2, even though w=0w = 0 is exactly right. With on-policy updates (blue), the second state is also updated, towards its own target 0, with gradient x=2x = 2. This pulls ww back, and it shrinks to 0.

    Quick check

    In the w→2ww \to 2w example with only the first state updated, α=0.1\alpha = 0.1 and γ=0.6\gamma = 0.6. What happens to ww, starting from w=1w = 1?

    3. Definitions and main results #

    Gradient Monte Carlo is SGD; semi-gradient TD is not #

    Gradient Monte Carlo is stochastic gradient descent on VE‾\overline{VE}. The gradient of 12VE‾(w)\frac12 \overline{VE}(w) is −∑sμ(s) [Vπ(s)−v^(s,w)] ∇v^(s,w)-\sum_s \mu(s)\,[V^\pi(s) - \hat v(s, w)]\,\nabla \hat v(s, w). The states sts_t of an episode are visited with frequencies μ\mu, and E[Gt∣st]=Vπ(st)\mathbb E[G_t \mid s_t] = V^\pi(s_t). So the update α [Gt−v^(st,w)] ∇v^(st,w)\alpha\,[G_t - \hat v(s_t, w)]\,\nabla \hat v(s_t, w) is, on average, a step along −∇12VE‾-\nabla \frac12\overline{VE}: SGD (see optimization 05). With Robbins–Monro step sizes it converges to a local minimum of VE‾\overline{VE}, the global one in the linear case.

    Semi-gradient TD is not. Its target rt+γv^(st+1,w)r_t + \gamma \hat v(s_{t+1}, w) depends on ww, but the update treats it as a constant: it differentiates only the prediction v^(st,w)\hat v(s_t, w). That is why it is called semi-gradient. The full gradient of 12δt2\frac12 \delta_t^2 would also contain the term −γ∇v^(st+1,w)-\gamma \nabla \hat v(s_{t+1}, w) ("residual gradient" methods use it; they are slower and need two independent samples of st+1s_{t+1} to be unbiased).

    For linear features we can say more. Write xt=x(st)x_t = x(s_t). The expected semi-gradient TD update is

    E[Δw]=α (b−Aw),A=E[xt (xt−γxt+1)⊤],b=E[rt xt],\mathbb E[\Delta w] = \alpha\,(b - A w), \qquad A = \mathbb E\big[x_t\,(x_t - \gamma x_{t+1})^\top\big], \quad b = \mathbb E[r_t\,x_t],

    with xt+1=0x_{t+1} = 0 after a terminal state. A vector field b−Awb - Aw is the negative gradient of some function only if its Jacobian −A-A is symmetric. Here AA 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 μ\mu, and Robbins–Monro step sizes, semi-gradient TD(0) converges with probability 1 to the TD fixed point

    wTD=A−1b.w_{TD} = A^{-1} b .

    The key step of the proof shows that AA is positive definite under the on-policy distribution, so the expected update w←w+α(b−Aw)w \leftarrow w + \alpha(b - Aw) is stable.

    The TD fixed point: what it solves and how good it is

    Projected Bellman equation. Let XX be the matrix with rows x(s)⊤x(s)^\top, D=diag⁡(μ)D = \operatorname{diag}(\mu), and Π\Pi the projection onto the span of the features in the μ\mu-weighted norm ∥v∥μ2=∑sμ(s)v(s)2\|v\|_\mu^2 = \sum_s \mu(s) v(s)^2. The condition b−Aw=0b - A w = 0 is X⊤D (rπ+γPπXw−Xw)=0X^\top D\,(r_\pi + \gamma P_\pi X w - X w) = 0: the Bellman error is orthogonal to the features. Equivalently, XwTD=Π Tπ(XwTD)Xw_{TD} = \Pi\,T^\pi(X w_{TD}): the TD solution is a fixed point of "apply the Bellman operator, then project". Gradient MC instead finds Π Vπ\Pi\,V^\pi, the projection of the true values.

    Error bound (continuing tasks with γ<1\gamma < 1; Sutton and Barto eq. 9.14):

    VE‾(wTD)≤11−γ min⁡wVE‾(w).\overline{VE}(w_{TD}) \le \frac{1}{1 - \gamma}\,\min_w \overline{VE}(w).

    The proof uses that ΠTπ\Pi T^\pi is a γ\gamma-contraction in ∥⋅∥μ\|\cdot\|_\mu when μ\mu is the on-policy distribution (this is where on-policy matters). For γ\gamma close to 1 the factor can be large, but in practice TD is often close to the best fit. In the random walk (γ=1\gamma = 1, episodic) the bound does not apply, and TD's error is 4.6 times the best.

    Off-policy. With a distribution d≠μd \ne \mu, A=X⊤Dd(I−γPπ)XA = X^\top D_d (I - \gamma P_\pi) X can have eigenvalues with negative real part, and then the expected update diverges. The w→2ww \to 2w example is the smallest case: d=(1,0)d = (1, 0) gives A=1⋅(1−2γ)<0A = 1 \cdot (1 - 2\gamma) < 0 for γ>1/2\gamma > 1/2. 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

    1. function approximation: values share parameters (linear or nonlinear), so an update in one state changes others;
    2. bootstrapping: targets use current estimates, as in TD and Q-learning, not complete returns;
    3. 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.

    Quick check

    A method uses a neural network for QQ 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?

    DQN #

    Deep Q-network (DQN) (Mnih et al., 2015) is Q-learning with a neural network Qθ(s,a)Q_\theta(s, a) that outputs one value per action. For a minibatch of transitions (s,a,r,s′,d)(s, a, r, s', d), where d=1d = 1 if the episode ended at s′s', it minimizes

    L(θ)=E(s,a,r,s′,d)∼buffer[ℓ(y−Qθ(s,a))],\mathcal L(\theta) = \mathbb E_{(s, a, r, s', d) \sim \text{buffer}}\Big[\ell\big(y - Q_\theta(s, a)\big)\Big],
    y=r+γ (1−d)max⁡a′Qθ−(s′,a′),y = r + \gamma\,(1 - d) \max_{a'} Q_{\theta^-}(s', a') ,

    where ℓ\ell is the squared loss or the Huber loss, and no gradient flows through yy. The factor (1−d)(1 - d) makes the target y=ry = r at the end of an episode. With the Huber loss ℓ(u)=12u2\ell(u) = \frac12 u^2 for ∣u∣≤1|u| \le 1 and ∣u∣−12|u| - \frac12 otherwise, the gradient is clip⁡(u,−1,1)\operatorname{clip}(u, -1, 1): a large TD error cannot produce a huge step. (The Nature DQN clipped the error term to [−1,1][-1, 1], which is the same.)

    Two tools make the regression stable:

    • Replay buffer. Store the last NN 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 θ−\theta^-, a copy of θ\theta that is updated only every CC steps (CC = 10 000 parameter updates in the Atari DQN). Between copies the targets yy do not depend on θ\theta, so each phase is an ordinary regression problem with fixed labels. Without it, a step that raises Qθ(s,a)Q_\theta(s, a) also raises Qθ(s′,⋅)Q_\theta(s', \cdot) for similar states, and the target runs away from the prediction. A smooth alternative is Polyak averaging: θ−←τθ+(1−τ)θ−\theta^- \leftarrow \tau\theta + (1 - \tau)\theta^- after every step, with small τ\tau such as 0.0050.005 (used by DDPG, TD3, SAC).
    Interactive figure: loading…

    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, (0.9,1)(0.9, 1) (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 C=1C = 1 (no target network), do the values reach the aqua point? Then try larger CC, and on-policy data.

    The moving-target view shows a real effect, not only an intuition. With C=1C = 1 the expected updates spiral away (the error grows by a factor 1.024 per step); with C=50C = 50 each period of 50 steps shrinks the error by a factor 0.805, and the values converge. With on-policy data even C=1C = 1 converges, as the theorem above promises. But a target network is not a guarantee: in the w→2ww \to 2w example any CC still diverges, because there the regression itself asks for w←2γww \leftarrow 2\gamma w 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 [−1,1][-1, 1]; ε falls linearly from 1.0 to 0.1 over the first million frames; γ=0.99\gamma = 0.99; the optimizer is RMSProp.

    Double DQN #

    DQN inherits the maximization bias of lesson 05: max⁡a′Qθ−(s′,a′)\max_{a'} Q_{\theta^-}(s', a') 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:

    a∗=arg⁡max⁡a′Qθ(s′,a′),ydouble=r+γ (1−d) Qθ−(s′,a∗).a^* = \arg\max_{a'} Q_\theta(s', a'), \qquad y^{\text{double}} = r + \gamma\,(1 - d)\,Q_{\theta^-}(s', a^*).

    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.

    Interactive figure: loading…

    Press "Repeat 1000 times". Ten actions all have true value 0; the online and target networks have independent errors of size σ\sigma. The orange histogram is the DQN target (the max of the target network): its mean is about 1.54 σ1.54\,\sigma. The violet histogram is the double DQN target (target network at the online network's argmax): its mean is about 0.

    Quick check

    For one transition, r=0r = 0, γ=0.99\gamma = 0.99, not done. The online network gives Qθ(s′,⋅)=(1.0,5.0,2.0)Q_\theta(s', \cdot) = (1.0, 5.0, 2.0) and the target network Qθ−(s′,⋅)=(1.5,3.0,4.0)Q_{\theta^-}(s', \cdot) = (1.5, 3.0, 4.0). What are the DQN and the double DQN targets?

    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, Q(s,a)=V(s)+A(s,a)−1∣A∣∑bA(s,b)Q(s, a) = V(s) + A(s, a) - \frac{1}{|\mathcal A|}\sum_b A(s, b); learns VV even for actions not taken
    multi-step targets nn-step returns rt+⋯+γn−1rt+n−1+γnmax⁡a′Qθ−(st+n,a′)r_t + \dots + \gamma^{n-1} r_{t+n-1} + \gamma^n \max_{a'} Q_{\theta^-}(s_{t+n}, a'): 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 a′a' 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 D\mathcal D of transitions collected by some behaviour policy πb\pi_b, 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:

    1. The target r+γmax⁡a′Q(s′,a′)r + \gamma \max_{a'} Q(s', a') asks for the values of all actions in s′s', including actions that πb\pi_b rarely or never took there: out-of-distribution (OOD) actions.
    2. No data point ever corrects the value of an OOD action, so its value is whatever the network extrapolates: this is extrapolation error.
    3. 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 ss of the data, with aDa_{\mathcal D} the action taken in the data,

    LCQL(θ)=LTD(θ)+α E(s,aD)∼D[pen(s)],\mathcal L_{\text{CQL}}(\theta) = \mathcal L_{\text{TD}}(\theta) + \alpha\,\mathbb E_{(s, a_{\mathcal D}) \sim \mathcal D}\big[\mathrm{pen}(s)\big],
    pen(s)=log⁡∑aeQθ(s,a)−Qθ(s,aD).\mathrm{pen}(s) = \log \sum_a e^{Q_\theta(s, a)} - Q_\theta(s, a_{\mathcal D}).

    (Here α\alpha 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 ss is

    ∂ pen(s)∂Q(s,a)=softmax⁡(Q(s,⋅))a−1[a=aD].\frac{\partial\,\mathrm{pen}(s)}{\partial Q(s, a)} = \operatorname{softmax}\big(Q(s, \cdot)\big)_a - \mathbb 1[a = a_{\mathcal D}] .

    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 α\alpha large enough, the learned value of the policy, Ea∼π[Q^(s,a)]\mathbb E_{a \sim \pi}[\hat Q(s, a)], is a lower bound on its true value; single values of data actions can still be pushed above their true values.

    Interactive figure: loading…

    Press "50 steps" with α=0\alpha = 0, then set α=1\alpha = 1 and press again. One state, three actions, a one-step decision (the target is the reward). The dashed lines are the true values (1.0,0.5,0.0)(1.0, 0.5, 0.0). The data contain only a1a_1 (grey coverage bars); the magenta actions never appear in the data. The values start at (1.0,0.5,3.0)(1.0, 0.5, 3.0): the network's guess for a3a_3 is an extrapolation error, and the greedy action (orange outline) is a3a_3. Plain offline Q-learning (α=0\alpha = 0) never changes it. The CQL penalty pushes a3a_3 down and a1a_1 up until a1a_1 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 λQ(s,π(s))−(π(s)−aD)2\lambda Q(s, \pi(s)) - (\pi(s) - a_{\mathcal D})^2.
    • 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.

    Quick check

    CQL is applied in a state with Q(s,⋅)=(2,0,0)Q(s, \cdot) = (2, 0, 0), and the data action is a1a_1. What is the sign of the penalty's gradient for Q(s,a1)Q(s, a_1), and what does gradient descent do to Q(s,a1)Q(s, a_1)?

    Answers to section 1. (1) No. On-policy linear TD converges to the TD fixed point A−1bA^{-1}b, which can have a larger VE‾\overline{VE} than the best weights (on the random walk, 0.0136 vs 0.0030); gradient MC finds the best weights. (2) Yes: w←(1+α(2γ−1)) ww \leftarrow (1 + \alpha(2\gamma - 1))\,w grows for γ>1/2\gamma > 1/2. Function approximation, bootstrapping and the off-policy distribution are all present. (3) Nothing corrects it: no data point contains a3a_3, so Q(s,a3)Q(s, a_3) 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 r=0r = 0, γ=0.99\gamma = 0.99, not done (d=0d = 0). Online network: Qθ(s′,⋅)=(1.0,5.0,2.0)Q_\theta(s', \cdot) = (1.0, 5.0, 2.0). Target network: Qθ−(s′,⋅)=(1.5,3.0,4.0)Q_{\theta^-}(s', \cdot) = (1.5, 3.0, 4.0).

    1. DQN: max⁡a′Qθ−(s′,a′)=4.0\max_{a'} Q_{\theta^-}(s', a') = 4.0 (action 3), so y=0+0.99⋅4.0=3.96y = 0 + 0.99 \cdot 4.0 = 3.96.
    2. Double DQN: the online network selects $\arg\max_{a'} Q_\theta(s', a') = $ action 2 (value 5.0).
    3. The target network evaluates action 2: Qθ−(s′,2)=3.0Q_{\theta^-}(s', 2) = 3.0, so y=0.99⋅3.0=2.97y = 0.99 \cdot 3.0 = 2.97.
    4. If the episode had ended at s′s' (d=1d = 1), both targets would be y=r=0y = r = 0.

    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 w→2ww \to 2w example with α=0.1\alpha = 0.1, γ=0.9\gamma = 0.9, w0=1w_0 = 1, only the first state updated:

    1. Factor per update: 1+α(2γ−1)=1+0.1⋅0.8=1.081 + \alpha(2\gamma - 1) = 1 + 0.1 \cdot 0.8 = 1.08.
    2. After 50 updates: w50=1.0850≈46.9w_{50} = 1.08^{50} \approx 46.9. The true value is 0.
    3. On-policy, each episode also updates the second state: δ=0−2w\delta = 0 - 2w, gradient x=2x = 2, so w←w+0.1⋅(−2w)⋅2=0.6 ww \leftarrow w + 0.1 \cdot (-2w) \cdot 2 = 0.6\,w. One episode multiplies ww by 1.08⋅0.6=0.6481.08 \cdot 0.6 = 0.648, and w→0w \to 0.

    (c) The CQL penalty for one state. Three actions with Q(s,⋅)=(1.0,0.5,3.0)Q(s, \cdot) = (1.0, 0.5, 3.0); the data contain only action 1.

    1. Log-sum-exp: log⁡(e1+e0.5+e3)=log⁡(2.718+1.649+20.086)=log⁡24.453=3.197\log(e^{1} + e^{0.5} + e^{3}) = \log(2.718 + 1.649 + 20.086) = \log 24.453 = 3.197.
    2. Penalty: 3.197−Q(s,a1)=3.197−1=2.1973.197 - Q(s, a_1) = 3.197 - 1 = 2.197.
    3. Softmax: (2.718,1.649,20.086)/24.453=(0.111,0.067,0.821)(2.718, 1.649, 20.086)/24.453 = (0.111, 0.067, 0.821).
    4. Gradient: softmax⁡(Q)−e1=(−0.889, 0.067, 0.821)\operatorname{softmax}(Q) - e_1 = (-0.889,\ 0.067,\ 0.821).

    Gradient descent raises Q(s,a1)Q(s, a_1) and lowers Q(s,a3)Q(s, a_3) 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 1+0.99⋅91 + 0.99 \cdot 9.

    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 yy 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 y=ry = r. Without (1−d)(1 - d) 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 VE‾\overline{VE}.
    • "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 w→2ww \to 2w example diverges for every CC).
    • "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 α\alpha. In CQL, α\alpha is the penalty weight; the learning rate of the network is η\eta.

    8. Check yourself #

    1. Why is gradient MC true SGD on VE‾\overline{VE}, but semi-gradient TD is not SGD on any loss?
      AnswerMC's target GtG_t does not depend on ww and has mean Vπ(st)V^\pi(s_t), so the update is an unbiased sample of −∇12VE‾-\nabla \frac12 \overline{VE}. TD's target depends on ww but is treated as a constant; the expected update b−Awb - Aw has the non-symmetric Jacobian −A-A, so it is not the gradient of any function.
    2. Name the three parts of the deadly triad and one method that avoids each.
      AnswerFunction approximation (tabular Q-learning), bootstrapping (gradient Monte Carlo), off-policy data (on-policy linear TD).
    3. With α=0.05\alpha = 0.05 and γ=0.99\gamma = 0.99, what is the factor per update in the w→2ww \to 2w example, and per episode with on-policy updates?
      AnswerOff-policy: 1+0.05⋅0.98=1.0491 + 0.05 \cdot 0.98 = 1.049 (diverges). On-policy: 1.049⋅(1−4⋅0.05)=1.049⋅0.8=0.8391.049 \cdot (1 - 4 \cdot 0.05) = 1.049 \cdot 0.8 = 0.839 (converges).
    4. What does the replay buffer fix, and what does the target network fix?
      AnswerReplay: strongly correlated consecutive samples (and it reuses data). Target network: the regression target that moves with every gradient step; with θ−\theta^- fixed, each phase is a regression with fixed labels.
    5. Compute the DQN and double DQN targets for r=1r = 1, γ=0.9\gamma = 0.9, not done, Qθ(s′,⋅)=(2,0)Q_\theta(s', \cdot) = (2, 0), Qθ−(s′,⋅)=(1,3)Q_{\theta^-}(s', \cdot) = (1, 3).
      AnswerDQN: 1+0.9⋅3=3.71 + 0.9 \cdot 3 = 3.7. Double DQN: the online network picks action 1, the target network gives 1, so y=1+0.9⋅1=1.9y = 1 + 0.9 \cdot 1 = 1.9.
    6. Why does offline Q-learning overestimate more than online Q-learning, and how does CQL respond?
      AnswerThe 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 α(log⁡∑aeQ(s,a)−Q(s,aD))\alpha(\log\sum_a e^{Q(s,a)} - Q(s, a_{\mathcal D})), which pushes all values down by their softmax weight and the data action up.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. Write the semi-gradient TD(0) update for a parametrized value function.

    2. Why is it called "semi-gradient"?

    3. Name the three parts of the deadly triad.

    4. In the w→2ww \to 2w example, what is the factor per update of the first state?

    5. Write the DQN target.

    6. Write the double DQN target.

    7. What is the purpose of the replay buffer?

    8. What is the purpose of the target network?

    9. What is extrapolation error in offline RL?

    10. Compute the CQL penalty gradient for Q(s,⋅)=(1,0.5,3)Q(s, \cdot) = (1, 0.5, 3) with data action a1a_1.

    Open the review →

    9. Interview angle #

    • "Why does DQN need a target network?" The target depends on the same weights; a step that raises Q(s,a)Q(s, a) also raises Q(s′,⋅)Q(s', \cdot) 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 w→2ww \to 2w example: factor 1+α(2γ−1)1 + \alpha(2\gamma - 1).
    • "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 QQ 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 VE‾\overline{VE} 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:

    1. 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.
    2. The w→2ww \to 2w example: divergence with off-policy updates and convergence with on-policy updates.
    3. Vectorized dqn_targets and double_dqn_targets with done flags.
    4. 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.
    5. Offline Q-learning on a gridworld with partial data coverage, then with a CQL penalty: measure the overestimation.

    11. Watch and read #

    Features, gradient MC and TD with approximation, convergence tables, and DQN with experience replay.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    From Q-learning to DQN, replay and target networks, double DQN and the Rainbow extensions, in one compact lecture.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The full theory: linear TD, the TD fixed point, the deadly triad and its examples.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    A visual introduction to features, semi-gradient methods and why bootstrapping with a function is different.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Why offline RL fails with standard off-policy methods: distribution shift and out-of-distribution actions.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play