Skip to content
AI360Xpert
Beta

Linear Methods in RL

Linear methods compute value estimates as a simple weighted sum of handcrafted features, guaranteeing that the mathematical error surface is a clean bowl with a single global optimum.

Linear methods compute value estimates as an inner product of weights and features, creating a convex error surface with a unique global optimum.
Linear methods compute value estimates as an inner product of weights and features, creating a convex error surface with a unique global optimum.

Why Does This Exist?

In realistic reinforcement learning applications—such as robotics, game playing, and resource allocation—the state space S\mathcal{S} is vast or continuous. Tabular representations, where a separate memory cell is allocated for every single state ss, collapse under memory limitations and fail completely to generalize: experiencing state ss tells a tabular agent nothing about a virtually identical state s′s'.

To generalize across states, practitioners use function approximation. However, complex non-linear function approximators like deep neural networks introduce thorny theoretical and practical headaches: non-convex loss landscapes, local minima, saddle points, sensitivity to hyperparameter tuning, and catastrophic divergence when paired with bootstrapping and off-policy sampling (the notorious "deadly triad").

Linear methods represent the premier, theoretically sound workhorse of function approximation. By parameterizing the value function strictly as an inner product of a learnable weight vector and a feature vector, linear methods transform the value-error objective into a strictly convex quadratic bowl. There are no local minima traps, gradients compute in O(d)O(d) time, and on-policy TD algorithms are mathematically guaranteed to converge to a bounded global fixed point.

Think of It Like This

The Weighted Grading Rubric

Imagine a university professor calculating a student's final course score using a syllabus rubric:

  1. The Feature Vector x(s)\mathbf{x}(s): The student's raw performance across different categories:
    • Homework assignments completed: x1=0.95x_1 = 0.95
    • Midterm exam score: x2=0.82x_2 = 0.82
    • Final exam score: x3=0.88x_3 = 0.88
    • Class attendance: x4=1.00x_4 = 1.00
  2. The Weight Vector w\mathbf{w}: The syllabus percentage allocated to each category:
    • w1=0.20,  w2=0.30,  w3=0.40,  w4=0.10w_1 = 0.20, \; w_2 = 0.30, \; w_3 = 0.40, \; w_4 = 0.10

To find the final course score v^(s,w)\hat{v}(s, \mathbf{w}), the professor does not run the data through a convoluted, non-linear multi-layer network. She simply computes the weighted sum (inner product): Final Score=w1x1+w2x2+w3x3+w4x4\text{Final Score} = w_1 x_1 + w_2 x_2 + w_3 x_3 + w_4 x_4

If the professor wants to adjust the final score upward by 55 points, the adjustment needed for each weight is directly proportional to how much that assignment contributed (x(s)\mathbf{x}(s)).

Where the analogy stops: A grading rubric is fixed beforehand by a human instructor. In reinforcement learning, the weights w\mathbf{w} are dynamic parameters learned through gradient descent, adjusting continuously on each observed state transition until prediction errors reach their mathematical minimum.

How It Actually Works

The Linear Function Approximator and the Gradient Property

In linear methods, any environmental state ss is mapped into a dd-dimensional feature vector:

x(s)=[x1(s)x2(s)⋮xd(s)]∈Rd\mathbf{x}(s) = \begin{bmatrix} x_1(s) \\ x_2(s) \\ \vdots \\ x_d(s) \end{bmatrix} \in \mathbb{R}^d

The approximate state-value function v^(s,w)\hat{v}(s, \mathbf{w}) is the linear combination (inner product) of the feature vector x(s)\mathbf{x}(s) and a learnable parameter vector w∈Rd\mathbf{w} \in \mathbb{R}^d:

v^(s,w)≜w⊤x(s)=∑i=1dwixi(s)\hat{v}(s, \mathbf{w}) \triangleq \mathbf{w}^\top \mathbf{x}(s) = \sum_{i=1}^d w_i x_i(s)

The mathematical elegance of linear approximation stems from its gradient with respect to the weights w\mathbf{w}. Taking the partial derivative with respect to any weight wiw_i:

∂∂wiv^(s,w)=∂∂wi∑j=1dwjxj(s)=xi(s)\frac{\partial}{\partial w_i} \hat{v}(s, \mathbf{w}) = \frac{\partial}{\partial w_i} \sum_{j=1}^d w_j x_j(s) = x_i(s)

In vector notation:

∇wv^(s,w)=x(s)\nabla_{\mathbf{w}} \hat{v}(s, \mathbf{w}) = \mathbf{x}(s)

The gradient of a linear function approximator is simply the feature vector itself. This identity drastically simplifies implementation: there is no backpropagation pass or chain-rule recursion—the direction of steepest value increase is already given directly by the input representation.

Strictly Convex Error Surfaces: No Local Minima

When evaluating the quality of approximation across a state distribution μ(s)\mu(s), practitioners measure the Mean Squared Value Error:

VE‾(w)≜∑s∈Sμ(s)[vπ(s)−w⊤x(s)]2\overline{\text{VE}}(\mathbf{w}) \triangleq \sum_{s \in \mathcal{S}} \mu(s) \left[ v_\pi(s) - \mathbf{w}^\top \mathbf{x}(s) \right]^2

Expanding this objective yields a quadratic form in w\mathbf{w}:

VE‾(w)=w⊤Aw−2b⊤w+c\overline{\text{VE}}(\mathbf{w}) = \mathbf{w}^\top \mathbf{A} \mathbf{w} - 2 \mathbf{b}^\top \mathbf{w} + c

where A=∑sμ(s)x(s)x(s)⊤\mathbf{A} = \sum_s \mu(s) \mathbf{x}(s) \mathbf{x}(s)^\top is the feature covariance matrix. Because A\mathbf{A} is positive semi-definite, VE‾(w)\overline{\text{VE}}(\mathbf{w}) forms a strictly convex paraboloid (a single bowl) in weight space:

  • There are no local minima traps.
  • There are no saddle points.
  • Any gradient descent process that converges is guaranteed to land at the unique global optimum w∗\mathbf{w}^*.

Linear Stochastic Gradient Descent vs. Semi-Gradient TD(0)

1. Linear Monte Carlo SGD

When trained with unbiased full-return targets Ut=GtU_t = G_t (Monte Carlo), the standard SGD update rule is:

wt+1=wt+α[Gt−wt⊤x(St)]x(St)\mathbf{w}_{t+1} = \mathbf{w}_t + \alpha \left[ G_t - \mathbf{w}_t^\top \mathbf{x}(S_t) \right] \mathbf{x}(S_t)

Because E[Gt∣St]=vπ(St)\mathbb{E}[G_t \mid S_t] = v_\pi(S_t), this update is an unbiased sample gradient of VE‾(w)\overline{\text{VE}}(\mathbf{w}), ensuring asymptotic convergence to the best possible linear approximation w∗\mathbf{w}^*.

2. Linear Semi-Gradient TD(0)

In temporal difference learning, the true return GtG_t is replaced by the bootstrapped one-step TD target:

Ut=Rt+1+γv^(St+1,wt)=Rt+1+γwt⊤x(St+1)U_t = R_{t+1} + \gamma \hat{v}(S_{t+1}, \mathbf{w}_t) = R_{t+1} + \gamma \mathbf{w}_t^\top \mathbf{x}(S_{t+1})

The TD error is:

δt=Rt+1+γwt⊤x(St+1)−wt⊤x(St)\delta_t = R_{t+1} + \gamma \mathbf{w}_t^\top \mathbf{x}(S_{t+1}) - \mathbf{w}_t^\top \mathbf{x}(S_t)

The semi-gradient update treats the target as independent of wt\mathbf{w}_t:

wt+1=wt+αδtx(St)\mathbf{w}_{t+1} = \mathbf{w}_t + \alpha \delta_t \mathbf{x}(S_t)

Convergence Guarantees and the TD Fixed-Point Bound

Unlike non-linear neural networks, which can diverge during semi-gradient bootstrapping, linear semi-gradient TD(0) is proven to converge on-policy to a unique weight vector called the TD fixed point wTD\mathbf{w}_{\text{TD}} (Tsitsiklis and Van Roy, 1997).

Furthermore, the error at the TD fixed point is strictly bounded relative to the global theoretical minimum:

VE‾(wTD)≤11−γmin⁡wVE‾(w)\overline{\text{VE}}(\mathbf{w}_{\text{TD}}) \le \frac{1}{1 - \gamma} \min_{\mathbf{w}} \overline{\text{VE}}(\mathbf{w})

For γ=0.9\gamma = 0.9, the final approximation error is at most 10×10\times the best achievable linear projection; for small discount factors, the solution is virtually identical to the optimal projection.

Worked numerical example

Consider a 2-dimensional feature representation for state SS: x(S)=[1.00.5],Initial weights: w0=[2.01.0],Learning rate: α=0.2\mathbf{x}(S) = \begin{bmatrix} 1.0 \\ 0.5 \end{bmatrix}, \quad \text{Initial weights: } \mathbf{w}_0 = \begin{bmatrix} 2.0 \\ 1.0 \end{bmatrix}, \quad \text{Learning rate: } \alpha = 0.2

1. Forward Prediction

v^(S,w0)=w0⊤x(S)=(2.0×1.0)+(1.0×0.5)=2.0+0.5=2.5\hat{v}(S, \mathbf{w}_0) = \mathbf{w}_0^\top \mathbf{x}(S) = (2.0 \times 1.0) + (1.0 \times 0.5) = 2.0 + 0.5 = \mathbf{2.5}

2. Target Observation

Suppose the agent observes an episode target return U=4.0U = 4.0. The prediction error is: δ=U−v^(S,w0)=4.0−2.5=+1.5\delta = U - \hat{v}(S, \mathbf{w}_0) = 4.0 - 2.5 = \mathbf{+1.5}

3. Weight Vector Update

Using the gradient identity ∇v^=x(S)\nabla \hat{v} = \mathbf{x}(S): Δw=αδx(S)=0.2×1.5×[1.00.5]=0.3×[1.00.5]=[0.300.15]\Delta \mathbf{w} = \alpha \delta \mathbf{x}(S) = 0.2 \times 1.5 \times \begin{bmatrix} 1.0 \\ 0.5 \end{bmatrix} = 0.3 \times \begin{bmatrix} 1.0 \\ 0.5 \end{bmatrix} = \begin{bmatrix} 0.30 \\ 0.15 \end{bmatrix}

w1=w0+Δw=[2.0+0.301.0+0.15]=[2.301.15]\mathbf{w}_1 = \mathbf{w}_0 + \Delta \mathbf{w} = \begin{bmatrix} 2.0 + 0.30 \\ 1.0 + 0.15 \end{bmatrix} = \begin{bmatrix} \mathbf{2.30} \\ \mathbf{1.15} \end{bmatrix}

4. New Prediction Verification

v^(S,w1)=w1⊤x(S)=(2.30×1.0)+(1.15×0.5)=2.30+0.575=2.875\hat{v}(S, \mathbf{w}_1) = \mathbf{w}_1^\top \mathbf{x}(S) = (2.30 \times 1.0) + (1.15 \times 0.5) = 2.30 + 0.575 = \mathbf{2.875}

Notice that the prediction shifted toward the target 4.04.0 by exactly: Δv^=2.875−2.50=0.375=αδ∥x(S)∥2=0.2×1.5×(1.02+0.52)=0.3×1.25=0.375\Delta \hat{v} = 2.875 - 2.50 = 0.375 = \alpha \delta \|\mathbf{x}(S)\|^2 = 0.2 \times 1.5 \times (1.0^2 + 0.5^2) = 0.3 \times 1.25 = 0.375

The prediction changed cleanly by a fraction determined by step size α\alpha and feature magnitude ∥x∥2\|\mathbf{x}\|^2.

Code

import mathfrom typing import List, Tuple

class LinearValueApproximator:    """Linear value function approximator v_hat(s, w) = w^T x(s)."""
    def __init__(self, num_features: int, initial_weights: List[float]):        assert len(initial_weights) == num_features        self.num_features = num_features        self.w = list(initial_weights)
    def predict(self, x: List[float]) -> float:        """Compute inner product between weights and features."""        assert len(x) == self.num_features        return sum(w_i * x_i for w_i, x_i in zip(self.w, x))
    def update_sgd(self, x: List[float], target: float, alpha: float) -> float:        """Update weights via linear SGD: w <- w + alpha * (target - v_hat) * x."""        v_hat = self.predict(x)        error = target - v_hat        for i in range(self.num_features):            self.w[i] += alpha * error * x[i]        return error
    def update_semi_gradient_td(        self,        x: List[float],        reward: float,        x_next: List[float],        gamma: float,        alpha: float,    ) -> float:        """Update weights via Semi-Gradient TD(0): delta = R + gamma * v(s') - v(s)."""        v_current = self.predict(x)        v_next = self.predict(x_next)        td_target = reward + gamma * v_next        td_error = td_target - v_current
        for i in range(self.num_features):            self.w[i] += alpha * td_error * x[i]        return td_error

if __name__ == "__main__":    # State features: x(S) = [1.0, 0.5]    features_s = [1.0, 0.5]    init_w = [2.0, 1.0]    approximator = LinearValueApproximator(        num_features=2, initial_weights=init_w    )
    # 1. Forward Prediction Check    v_init = approximator.predict(features_s)    print(f"Initial Value Prediction: {v_init:.3f}")    assert math.isclose(v_init, 2.5), f"Expected 2.5, got {v_init}"
    # 2. Monte Carlo SGD Update towards target U = 4.0 with alpha = 0.2    target_return = 4.0    err = approximator.update_sgd(features_s, target=target_return, alpha=0.2)    v_updated = approximator.predict(features_s)
    print(f"Error: {err:.3f} | Updated Weights: {approximator.w}")    print(f"Updated Value Prediction: {v_updated:.3f}")
    assert math.isclose(        approximator.w[0], 2.30    ), f"Expected w[0] = 2.30, got {approximator.w[0]}"    assert math.isclose(        approximator.w[1], 1.15    ), f"Expected w[1] = 1.15, got {approximator.w[1]}"    assert math.isclose(        v_updated, 2.875    ), f"Expected v_updated = 2.875, got {v_updated}"
    # 3. Semi-Gradient TD(0) Update Step    features_next = [0.8, 0.4]    reward = 1.0    gamma = 0.9    td_err = approximator.update_semi_gradient_td(        x=features_s,        reward=reward,        x_next=features_next,        gamma=gamma,        alpha=0.1,    )
    print(f"TD Error: {td_err:.3f} | Weights after TD update: {approximator.w}")    print("\nAll linear method assertions passed successfully.")
# Expected Output:# Initial Value Prediction: 2.500# Error: 1.500 | Updated Weights: [2.3, 1.15]# Updated Value Prediction: 2.875# TD Error: 0.195 | Weights after TD update: [2.3195, 1.15975]## All linear method assertions passed successfully.

Watch Out For

Feature Scale Imbalance and Ill-Conditioned Curvature

A common failure mode in linear methods is using unnormalized features whose numerical scales differ by orders of magnitude (for instance, combining a vehicle velocity feature in [0,100][0, 100] with an obstacle distance feature in [0,0.01][0, 0.01]).

When features have disparate scales:

  • The covariance matrix A=∑μ(s)x(s)x(s)⊤\mathbf{A} = \sum \mu(s) \mathbf{x}(s) \mathbf{x}(s)^\top becomes ill-conditioned, elongating the quadratic error bowl into an extremely sharp, narrow elliptical canyon.
  • Gradient updates oscillate wildly perpendicular to the steep walls rather than progressing smoothly toward the minimum along the flat floor.
  • A single global learning rate α\alpha either causes divergence along the high-magnitude feature or painfully sluggish learning along the low-magnitude feature.

The Fix:

  1. Feature Normalization: Standardize all feature dimensions to zero mean and unit variance (μ=0,σ=1\mu = 0, \sigma = 1), or rescale strictly into [−1,1][-1, 1].
  2. Dimension-Specific Step Sizes: Scale individual learning rates inversely with feature magnitude: αi=αE[xi2]\alpha_i = \frac{\alpha}{\mathbb{E}[x_i^2]}.
  3. Normalized Feature Representations: Use tile coding, radial basis functions (RBFs), or Fourier bases where feature vector norms are naturally bounded: ∥x(s)∥2≤C\|\mathbf{x}(s)\|^2 \le C.

The Quick Version

  • Inner product formulation: Linear methods estimate state values as v^(s,w)=w⊤x(s)\hat{v}(s, \mathbf{w}) = \mathbf{w}^\top \mathbf{x}(s), combining handcrafted feature representations with learnable weights.
  • Gradient equals the feature: Because ∇wv^(s,w)=x(s)\nabla_{\mathbf{w}} \hat{v}(s, \mathbf{w}) = \mathbf{x}(s), updates simplify to Δw=αδx(s)\Delta \mathbf{w} = \alpha \delta \mathbf{x}(s) without backpropagation or chain-rule complexity.
  • Unimodal convex landscape: The Value Error VE‾(w)\overline{\text{VE}}(\mathbf{w}) is a quadratic paraboloid with a unique global optimum; there are zero local minima traps or saddle points.
  • Guaranteed TD fixed point: Linear semi-gradient TD(0) converges reliably on-policy to a bounded fixed point wTD\mathbf{w}_{\text{TD}} whose error is within 11−γ\frac{1}{1-\gamma} of the best theoretical linear projection.