Vanishing Gradients: Why RNNs Fail on Long Sequences

Michael BrenndoerferMay 8, 202545 min read

Part of Language AI Handbook

Explains why gradient magnitudes collapse exponentially in RNNs, making long-range dependencies impossible to learn without architectural changes like LSTMs.

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Vanishing Gradients

In the previous chapter, we derived Backpropagation Through Time (BPTT) and saw how gradients flow backward through an unrolled RNN. We noted that the same weight matrix WhW_h multiplies the gradient at every timestep. That single observation, almost a footnote at the end of the BPTT derivation, turns out to be the central obstacle of training recurrent networks on long sequences. This chapter explores what happens to those gradients as they travel backward across dozens or hundreds of timesteps, why they almost always collapse to zero, and why this collapse makes RNNs unreliable for learning long-range dependencies. Understanding this failure mode thoroughly is the essential motivation for the LSTM architecture we will study next.

Before examining the mathematics, consider the task that any sequence model must accomplish. Language is deeply hierarchical. A sentence can contain a relative clause that interrupts the main clause. A paragraph can open with a claim that its final sentence resolves. A document can introduce a character whose actions hundreds of words later depend on a motivation established at the beginning. Any model that hopes to understand language must be able to connect information across these distances. For an RNN, this means the gradient signal that tells the network "your prediction at time TT was wrong because of the information at time tt" must survive a journey through TtT - t steps. As we will see, for realistic sequence lengths, that journey is almost impossible.

The Gradient Product Problem

To train an RNN, we need to compute how the loss at time TT depends on the hidden state at some earlier time tt. This is exactly the gradient LTht\frac{\partial L_T}{\partial h_t}, where LTL_T is the loss at the final timestep and hth_t is the hidden state at time tt.

Recall from the BPTT derivation that the hidden state evolves as:

ht=tanh(Whht1+Wxxt+b)h_t = \tanh(W_h h_{t-1} + W_x x_t + b)

where:

  • htRnh_t \in \mathbb{R}^n is the hidden state vector at time tt
  • WhRn×nW_h \in \mathbb{R}^{n \times n} is the recurrent weight matrix
  • WxRn×dW_x \in \mathbb{R}^{n \times d} maps input xtx_t to the hidden layer
  • bRnb \in \mathbb{R}^n is the bias

Applying the chain rule, the gradient of hTh_T with respect to hth_t involves all intermediate steps:

hTht=k=t+1Thkhk1\frac{\partial h_T}{\partial h_t} = \prod_{k=t+1}^{T} \frac{\partial h_k}{\partial h_{k-1}}

where each factor in the product is the Jacobian matrix:

hkhk1=diag(tanh(zk))Wh\frac{\partial h_k}{\partial h_{k-1}} = \text{diag}(\tanh'(z_k)) \cdot W_h

where:

  • zk=Whhk1+Wxxk+bz_k = W_h h_{k-1} + W_x x_k + b is the pre-activation at step kk
  • tanh(zk)\tanh'(z_k) is the element-wise derivative of tanh evaluated at zkz_k
  • diag(tanh(zk))\text{diag}(\tanh'(z_k)) is the diagonal Jacobian of the tanh nonlinearity

So the full gradient becomes:

hTht=k=t+1Tdiag(tanh(zk))Wh\frac{\partial h_T}{\partial h_t} = \prod_{k=t+1}^{T} \text{diag}(\tanh'(z_k)) \cdot W_h

This is a product of TtT - t matrices. When TtT - t is large, this product determines whether learning succeeds or fails.

To understand why this product is dangerous, think about what it represents physically. Each factor diag(tanh(zk))Wh\text{diag}(\tanh'(z_k)) \cdot W_h is a local linear approximation to how perturbations to hk1h_{k-1} propagate to hkh_k. Multiplying these local approximations together gives the global sensitivity: how much does a small change to hth_t affect hTh_T? The answer, for long sequences, is almost always: very little. The product of many factors smaller than one collapses to zero.

The Chain Rule Imposes a Product Structure

It is worth pausing to understand why the chain rule produces this particular structure and why there is no way around it within the RNN formulation. The chain rule is not a choice or an approximation: it is the exact rule for computing how composed functions depend on their inputs. The RNN is a composed function. hTh_T depends on hT1h_{T-1}, which depends on hT2h_{T-2}, all the way back to hth_t. The gradient of this chain of compositions is exactly the product of the local derivatives.

This means the vanishing gradient problem is not a bug in the BPTT algorithm or a consequence of a bad implementation. It is built into the structure of the RNN itself. The recurrence relation that makes RNNs powerful at processing sequences is also the source of the gradient problem. You cannot have sequential composition without a multiplicative gradient chain.

The only escape is to change the recurrence relation itself, which is precisely what LSTM does. Rather than composing a function at every timestep (multiplying), the LSTM adds to a memory cell. Addition distributes gradient flow uniformly backward, as we will see in the LSTM chapter.

Eigenvalue Analysis: Why Products of Matrices Shrink or Explode

The behavior of a matrix product depends critically on the spectral properties of each factor. Let's analyze what happens when you repeatedly multiply similar matrices together.

Consider a simplified version where WhW_h is a scalar weight ww (or, more precisely, where we track the behavior along the dominant eigenvalue direction). Each factor in the gradient product contributes a scaling of approximately λ1(DkWh)|\lambda_1(D_k \cdot W_h)|, where λ1\lambda_1 denotes the largest singular value and Dk=diag(tanh(zk))D_k = \text{diag}(\tanh'(z_k)) is the diagonal scaling matrix from the nonlinearity.

Since tanh(z)1|\tanh'(z)| \leq 1 for all zz (the tanh derivative is at most 1, achieved at z=0z = 0), and in practice the hidden states often saturate the tanh function, DkD_k contributes factors strictly less than 1.

The gradient product norm satisfies:

k=t+1TDkWhk=t+1TDkWh(γWh)Tt\left\| \prod_{k=t+1}^{T} D_k W_h \right\| \leq \prod_{k=t+1}^{T} \|D_k W_h\| \leq (\gamma \cdot \|W_h\|)^{T-t}

where γ=maxkDk<1\gamma = \max_k \|D_k\| < 1 is the maximum gain from the nonlinearity across all timesteps.

This inequality has two regimes:

  • If γWh<1\gamma \cdot \|W_h\| < 1, the product shrinks exponentially in TtT - t. This is the vanishing gradient regime.
  • If γWh>1\gamma \cdot \|W_h\| > 1, the product grows exponentially. This is the exploding gradient regime.

The boundary between the two is the unit circle in eigenvalue space. Practical networks almost always fall into the vanishing regime because the tanh nonlinearity enforces γ<1\gamma < 1, and weight matrices are initialized to have spectral radius near or below 1 for stability.

Spectral Radius

The spectral radius of a matrix AA is the largest absolute eigenvalue: ρ(A)=maxiλi(A)\rho(A) = \max_i |\lambda_i(A)|. For a product of matrices to avoid exponential decay, the spectral radius of each factor must be at or above 1. With tanh nonlinearities constraining γ<1\gamma < 1, this is almost impossible to achieve in practice across a long sequence.

What the Eigenvalue Decomposition Reveals

To understand the behavior of the gradient product more deeply, it helps to think about the eigenvalue decomposition of WhW_h. Suppose WhW_h is diagonalizable with eigenvalues λ1,λ2,,λn\lambda_1, \lambda_2, \ldots, \lambda_n, sorted by absolute value so that λ1λ2λn|\lambda_1| \geq |\lambda_2| \geq \cdots \geq |\lambda_n|.

When you multiply the matrix by itself many times, the eigenvectors associated with large eigenvalues dominate the product. For a matrix power WhkW_h^k, the contribution from the ii-th eigendirection scales as λik\lambda_i^k. For directions where λi<1|\lambda_i| < 1, the product collapses exponentially. For directions where λi>1|\lambda_i| > 1, the product grows exponentially.

In the gradient product, the situation is analogous but more complex because each factor also includes the diagonal scaling from the nonlinearity. Nevertheless, the dominant behavior is determined by the spectrum of WhW_h. The gradient signal propagates reliably only through eigendirections with eigenvalue magnitude near or above 1. All other directions lose information exponentially fast.

This has a subtle but important consequence for what RNNs can remember. The information that survives long backward passes is not arbitrary: it is precisely the information aligned with the dominant eigenvectors of WhW_h. The recurrent weight matrix effectively selects which aspects of the hidden state are memorable and which are forgettable based purely on its spectral structure, not based on what the task requires. This spectral selectivity is one reason vanilla RNNs are difficult to reason about and hard to train for specific long-range tasks.

The Sigmoid Nonlinearity Makes Things Worse

While the analysis above uses tanh, the original LSTM paper and many early RNNs used sigmoid activations in some layers. Sigmoid is even more problematic for gradient flow.

The sigmoid function σ(z)=11+ez\sigma(z) = \frac{1}{1 + e^{-z}} has a maximum derivative of 0.250.25, occurring at z=0z = 0:

σ(z)=σ(z)(1σ(z))0.25\sigma'(z) = \sigma(z)(1 - \sigma(z)) \leq 0.25

where:

  • σ(z)\sigma(z) is the sigmoid output, always in (0,1)(0, 1)
  • 1σ(z)1 - \sigma(z) is the complement, also in (0,1)(0, 1)
  • Their product is maximized when σ(z)=0.5\sigma(z) = 0.5, giving 0.5×0.5=0.250.5 \times 0.5 = 0.25

This means each sigmoid gate contributes at most a factor of 0.250.25 to the gradient. A chain of 10 sigmoid layers multiplies the gradient by at most 0.25101060.25^{10} \approx 10^{-6}. Over 100 timesteps, the gradient magnitude is bounded by 0.251000.25^{100}, which is effectively zero in floating-point arithmetic.

Tanh has a maximum derivative of 1 (at z=0z = 0), so it is somewhat better, but the maximum is only achieved exactly at zero. In practice, hidden states drift away from zero as the network processes sequences, and the effective gain drops well below 1.

Saturating Nonlinearities

A saturating nonlinearity is one where the derivative approaches zero as the input magnitude grows. Both tanh and sigmoid saturate: tanh approaches plus or minus 1 with near-zero slope for large z|z|, and sigmoid approaches 0 or 1 with near-zero slope. When hidden states are pushed into saturated regions, they contribute near-zero factors to the gradient product, accelerating vanishing.

To appreciate the interplay between saturation and vanishing gradients, consider what happens during the forward pass of a long sequence. At each step, the network computes a new hidden state and passes it through tanh. If the inputs are informative and the network is responding strongly, the pre-activation values zkz_k will have large magnitudes, and tanh will saturate them to values near ±1\pm 1. This saturation is desirable from a representational standpoint: it allows the network to make confident decisions about whether information is present. But the same saturation that makes the forward representation less brittle makes the backward gradient fragile. A hidden state near ±1\pm 1 has a derivative near zero, contributing nearly zero gain to the gradient product at that step. The very steps where the network is most confident about its representation are the steps that contribute most to gradient decay.

This creates a fundamental tension. Informative hidden states tend to saturate, which kills gradient flow. Unsaturated hidden states near zero have maximum gradient flow, but they also represent uncertain, low-magnitude activations. The network cannot simultaneously have rich, confident representations and efficient gradient flow when using saturating nonlinearities.

Exploding Gradients and Norm Explosion

The complementary problem is exploding gradients. When the spectral radius of WhW_h exceeds 1/γ1/\gamma, the gradient product grows without bound. In practice, this manifests as the gradient norm increasing by orders of magnitude within a few backward steps.

Exploding gradients are easier to detect than vanishing gradients: the loss suddenly spikes to NaN or infinity, and you can observe the gradient norm growing exponentially in training logs. The standard fix is gradient clipping, covered separately in the Neural Network Foundations chapter.

The asymmetry between vanishing and exploding gradients is important:

  • Exploding gradients are detectable and fixable through gradient clipping. The norm becomes absurdly large, giving you a clear signal.
  • Vanishing gradients are silent. The loss may appear to decrease, but the network learns only from the most recent few timesteps. There is no error or warning: the weight updates for long-range connections are just approximately zero.

This asymmetry makes vanishing gradients the more dangerous and practically important failure mode.

How Exploding Gradients Manifest in Practice

When gradients explode, the effect is dramatic and unmistakable. A weight update of magnitude 10510^5 to 101010^{10} is applied to parameters that were initialized with magnitudes near 0.01. The parameters jump to wildly incorrect values, the forward pass produces garbage activations or NaN values, and the loss spikes to infinity. Training collapses.

The fix, gradient clipping, is simple in concept: if the global gradient norm exceeds a threshold (typically 1.0 or 5.0), scale down all gradients proportionally so the global norm equals the threshold. This prevents catastrophic parameter updates while preserving the gradient direction. Gradient clipping does not fix the underlying gradient explosion problem but makes it manageable.

It is worth asking why the same spectral radius condition that causes vanishing gradients for small spectral radii causes explosion for large ones. The answer is that both are consequences of the same product structure. When each factor has spectral radius less than 1, the product converges to zero. When each factor has spectral radius greater than 1, the product diverges. The only difference is the direction of the instability.

In practice, training with exploding gradients is more tractable than training with vanishing gradients, because clipping provides a consistent workaround. Vanishing gradients have no analogous fix: there is no operation you can apply after the fact to recover gradient information that was lost during backpropagation.

Effective Gradient Distance

The vanishing gradient problem means that the signal from distant timesteps is effectively zero. We can formalize this with the concept of effective gradient distance: the maximum number of timesteps over which a gradient signal remains large enough to update the weights.

If each timestep contributes a multiplicative factor of ρ<1\rho < 1 to the gradient magnitude, then after kk steps, the gradient has magnitude proportional to ρk\rho^k. The effective gradient distance is roughly the kk at which ρk\rho^k falls below the numerical noise floor, often taken as 10410^{-4} relative to the initial magnitude:

keff=log(104)log(ρ)=4log(10)log(ρ)k_{\text{eff}} = \frac{\log(10^{-4})}{\log(\rho)} = \frac{-4 \log(10)}{\log(\rho)}

For ρ=0.9\rho = 0.9, this gives keff87k_{\text{eff}} \approx 87 steps, which seems large. But typical RNN training uses ρ\rho values closer to 0.7 to 0.8, giving keffk_{\text{eff}} between 25 and 50 steps. Sequences of hundreds of tokens far exceed this budget, and dependencies across paragraphs or documents are completely invisible to the gradient signal.

The Memory Horizon

The effective gradient distance defines what we can call the memory horizon of the network: the temporal window within which the network can learn. Beyond this horizon, weight updates are effectively zero and the network behaves as if those earlier tokens never existed.

The memory horizon is not a sharp cutoff. Gradients decay continuously, and the rate of decay varies across different directions in the hidden state space. Some information can survive longer than average if it happens to align with the dominant eigenvectors of WhW_h. But the average behavior is exponential decay, and for most practical tasks, the memory horizon falls well short of what is needed.

Consider the implications for language modeling. Subject-verb agreement in English typically requires connecting a noun to a verb separated by a short clause. For a sentence like "The man who lives in the old house is friendly," the subject "man" and the verb "is" are separated by six tokens. A network with a memory horizon of 20 steps could in principle learn this dependency. But for a sentence like "The man who lives in the old house near the park with the beautiful fountain and the ancient oak trees that the children always play around in summer is friendly," the subject and verb are separated by more than 30 tokens. Such examples reveal how even moderate clause embeddings can push dependencies beyond the vanilla RNN's effective range.

In practice, the memory horizon for a vanilla RNN trained on natural language is often estimated at roughly 10 to 15 tokens. This is enough for local syntactic patterns, short-distance agreement, and simple phrase-level semantics. It is not enough for clause-level dependencies, paragraph-level coherence, or document-level structure.

Empirical Evidence of Vanishing in Practice

Beyond the theoretical analysis, empirical experiments confirm that vanilla RNNs consistently fail to learn long-range dependencies. Several classic experiments demonstrate this.

Copying task: The network receives a sequence of symbols, then must reproduce the symbols after a delay. Vanilla RNNs succeed easily for delays of 5 to 10 steps but fail almost completely for delays of 50 to 100 steps. The required information simply cannot survive the gradient decay. This task is entirely artificial, with no linguistic complexity, yet the RNN cannot solve it for long delays. This eliminates confounding factors: it is not that the task is linguistically hard. It is that the gradient cannot travel far enough to train the relevant weights.

Counting task: The network must count occurrences of a pattern across a long sequence. The count must be maintained in the hidden state, but gradients that would reinforce count-preserving behavior vanish before reaching the early timesteps. The network either fails to maintain the count at all or maintains it correctly for short sequences and fails for long ones.

Language modeling: When trained on natural language, vanilla RNNs learn local word patterns (bigrams, trigrams, short syntactic structures) reasonably well. They fail to capture subject-verb agreement across long clauses, pronoun coreference, or topic coherence across paragraphs. The perplexity of vanilla RNNs on held-out text plateaus at values that reflect this shallow modeling: the network has learned a sophisticated local grammar but cannot connect information across the document.

Sentiment analysis across long reviews: A review that opens with extensive praise and ends with a qualification can fool a vanilla RNN. The positive signal at the beginning is washed out by the long gradient chain before it influences the final prediction. LSTMs handle such long-range sentiment signals much more reliably.

These empirical failures match the theoretical prediction: the effective receptive field of a vanilla RNN is bounded by the effective gradient distance, not the full sequence length. No amount of additional training data or hyperparameter tuning can extend the effective gradient distance. The problem is structural, not empirical.

Why Long-Range Dependencies Require Stable Gradient Flow

To understand intuitively why long-range dependencies break down, consider training a network to predict that "the cat, which sat on the mat for a very long time, was hungry." The word "hungry" must agree with "cat," which appeared 10 tokens earlier. The gradient of the prediction error on "hungry" must travel backward through "was," "time," "very," "a," "for," "mat," "the," "on," "sat," "which" before reaching "cat." Each of those 10 backward steps multiplies the gradient by a factor less than 1, shrinking it toward zero.

The weight update that would strengthen the "cat to hungry" connection is proportional to this vanished gradient. With a gradient of 10810^{-8}, the weight update is effectively zero regardless of the learning rate. The network cannot learn this dependency, no matter how many epochs you train for.

This is not a problem of insufficient training time or learning rate tuning. It is a fundamental limitation of the architecture: the gradient signal cannot reliably propagate information over long distances because multiplication by many small factors inevitably destroys the signal.

The Credit Assignment Problem

The vanishing gradient problem is a specific manifestation of the broader credit assignment problem in machine learning. Credit assignment asks: given that the network made an error at step TT, which earlier decisions were responsible, and by how much? For a vanilla RNN, the credit assignment problem is particularly severe because the gradient is the only mechanism for tracing responsibility backward through time.

In a feedforward network, credit is assigned through the depth of the network (layers correspond to steps of transformation). In a recurrent network, credit must be assigned through the time dimension of the sequence. The longer the sequence, the harder the credit assignment problem. And unlike feedforward networks, where depth can be controlled by architecture design, sequence length is a property of the data and cannot be arbitrarily reduced without discarding information.

The vanishing gradient problem means that for distant timesteps, the credit assigned by gradient descent is essentially zero. The network assigns full credit to recent steps and no credit to distant ones, producing a systematic bias toward local patterns regardless of which patterns matter for the task. This is not a soft or gradual bias: for sequences longer than the memory horizon, the credit assignment for distant tokens rounds to exactly zero in floating-point arithmetic.

Visualizing Gradient Flow Through Time

The easiest way to see vanishing gradients empirically is to train an RNN and track the gradient norm at each timestep. In a healthy training scenario, gradients from all timesteps should have comparable magnitudes. In practice, you see exponential decay.

In[3]:
Code
import numpy as np

np.random.seed(42)


def tanh_deriv(z):
    return 1.0 - np.tanh(z) ** 2


def sigmoid_deriv(z):
    s = 1.0 / (1.0 + np.exp(-z))
    return s * (1.0 - s)


def compute_gradient_norms(
    T, hidden_size, W_spectral_radius, activation="tanh", seed=0
):
    """
    Simulate gradient norms flowing backward through T timesteps.
    Returns a list of gradient norms at each timestep index (from T down to 0).
    """
    rng = np.random.default_rng(seed)
    W = rng.standard_normal((hidden_size, hidden_size))
    eigvals = np.linalg.eigvals(W)
    current_radius = np.max(np.abs(eigvals))
    W = W * (W_spectral_radius / current_radius)

    h = rng.standard_normal(hidden_size) * 0.1
    z_values = []
    for t in range(T):
        z = W @ h + rng.standard_normal(hidden_size) * 0.1
        z_values.append(z)
        if activation == "tanh":
            h = np.tanh(z)
        else:
            h = 1.0 / (1.0 + np.exp(-z))

    grad = np.eye(hidden_size)
    norms = [np.linalg.norm(grad, "fro")]

    for t in reversed(range(T)):
        z = z_values[t]
        if activation == "tanh":
            d = tanh_deriv(z)
        else:
            d = sigmoid_deriv(z)
        J = np.diag(d) @ W
        grad = J @ grad
        norms.append(np.linalg.norm(grad, "fro"))

    return norms
In[4]:
Code
T = 60
hidden_size = 32

scenarios = [
    ("tanh, rho=0.95", "tanh", 0.95, "#1f77b4"),
    ("tanh, rho=0.80", "tanh", 0.80, "#ff7f0e"),
    ("sigmoid, rho=0.95", "sigmoid", 0.95, "#2ca02c"),
    ("sigmoid, rho=0.80", "sigmoid", 0.80, "#d62728"),
]

results = {}
for label, act, rho, color in scenarios:
    norms = compute_gradient_norms(T, hidden_size, rho, activation=act, seed=42)
    results[label] = (norms, color)
Out[5]:
Visualization
Line plot of gradient norms vs timesteps showing exponential decay for four activation and spectral-radius combinations.
Gradient norm magnitude as gradients propagate backward through 60 timesteps for four RNN configurations. The sigmoid configurations decay by many orders of magnitude because sigmoid's maximum derivative is 0.25, while tanh preserves substantially more signal. A spectral radius closer to 1 slows the decay for either activation.

The plot confirms the theory. Even the most favorable configuration, tanh activations with a spectral radius near 1, shows the gradient norm decaying by several orders of magnitude over 60 timesteps. The sigmoid variants collapse far faster. When training on sequences of length 100 or more, the gradients reaching early timesteps are negligibly small: the weights responsible for long-range dependencies receive near-zero updates throughout training.

Notice how the y-axis of this plot spans many orders of magnitude. The gradient norm at step 60 is often a billion or a trillion times smaller. When you print out gradient values during training and see something like 3.2×10113.2 \times 10^{-11}, that is not a rounding error. That is the actual gradient, and it is telling you that the network is completely blind to any influence from 60 steps ago.

The Geometry of the Problem: A Worked Example

To make the vanishing gradient concrete, let's trace a specific gradient through a small RNN by hand.

Consider an RNN with hidden size 2 and a single timestep transition matrix:

Wh=(0.50.30.20.4)W_h = \begin{pmatrix} 0.5 & 0.3 \\ 0.2 & 0.4 \end{pmatrix}

The spectral radius of this matrix is approximately 0.71 (less than 1). Now imagine a sequence of length 5. The gradient of LL with respect to h0h_0 involves multiplying through 5 Jacobian factors:

Lh0=Lh5k=15Jk\frac{\partial L}{\partial h_0} = \frac{\partial L}{\partial h_5} \cdot \prod_{k=1}^{5} J_k

where each Jk=diag(tanh(zk))WhJ_k = \text{diag}(\tanh'(z_k)) \cdot W_h has spectral radius at most 0.71.

After 5 steps: 0.7150.180.71^5 \approx 0.18. The gradient has shrunk by a factor of about 5.

After 10 steps: 0.71100.0340.71^{10} \approx 0.034. A factor of 30 reduction.

After 20 steps: 0.71200.00110.71^{20} \approx 0.0011. A factor of 900 reduction.

After 40 steps: 0.71401.2×1060.71^{40} \approx 1.2 \times 10^{-6}. Numerically negligible.

This is just one specific matrix. Let's compute this numerically to see how it plays out across various sequence lengths:

In[6]:
Code
W_example = np.array([[0.5, 0.3], [0.2, 0.4]])
eigvals_example = np.linalg.eigvals(W_example)
spectral_radius_example = np.max(np.abs(eigvals_example))

sequence_lengths = [5, 10, 20, 40, 60]

np.random.seed(123)
h_ex = np.array([0.5, -0.3])
grad_ex = np.eye(2)
step_norms = [np.linalg.norm(grad_ex, "fro")]

for step in range(max(sequence_lengths)):
    z_ex = W_example @ h_ex
    d_ex = tanh_deriv(z_ex)
    J_ex = np.diag(d_ex) @ W_example
    grad_ex = J_ex @ grad_ex
    h_ex = np.tanh(z_ex)
    step_norms.append(np.linalg.norm(grad_ex, "fro"))

grad_norms_by_length = {
    length: step_norms[length] for length in sequence_lengths
}
Out[7]:
Console
Spectral radius of W_h: 0.7000

Sequence length      Gradient norm        Relative to step 1       
-----------------------------------------------------------------
5                    1.679169e-01         2.322032e-01             
10                   2.821764e-02         3.902066e-02             
20                   7.970731e-04         1.102230e-03             
40                   6.360027e-07         8.794940e-07             
60                   5.074810e-10         7.017682e-10

The output shows the gradient norm collapsing exponentially. By step 40, it has shrunk by more than 6 orders of magnitude relative to step 5. Any weight update proportional to this gradient is effectively zero regardless of learning rate choice.

The numbers make the problem viscerally clear. A learning rate of 0.01 applied to a gradient of 10710^{-7} produces a weight update of 10910^{-9}. With 32-bit floating-point precision, this update rounds to zero. Long-range dependencies are simply unlearnable.

What the Worked Example Reveals About Initialization

The example above used a specific matrix with spectral radius 0.71. But the choice of initialization matters enormously for how quickly gradients vanish. Early practitioners tried to fight vanishing gradients by using larger initialization, hoping to push the spectral radius closer to 1. This helps, but only partially.

The issue is that the tanh nonlinearity still contributes damping factors less than 1 at every step (unless all pre-activations are exactly at zero). Even with a weight matrix whose spectral radius is exactly 1, the effective spectral radius of the full Jacobian diag(tanh(zk))Wh\text{diag}(\tanh'(z_k)) \cdot W_h will be less than 1 at every step where the hidden state has moved away from zero. And as the network processes information, the hidden states will inevitably move away from zero.

This suggests that careful initialization can delay but not eliminate vanishing gradients. The network might successfully learn dependencies up to 30 or 40 steps with good initialization, compared to 10 or 15 steps with poor initialization. But for sequences of length 100, 500, or 1000, even the best initialization leaves most of the sequence out of the effective gradient range.

The Vanishing vs Exploding Tradeoff

The vanishing and exploding problems define the two sides of a knife-edge. When the spectral radius is far below 1, gradients vanish and long-range learning fails. When it is far above 1, gradients explode and training becomes numerically unstable. The stable regime is a narrow band around spectral radius 1, but even within this band, the tanh nonlinearity prevents perfect gradient preservation across long sequences because tanh(z)<1|\tanh'(z)| < 1 for z0z \neq 0.

This creates a fundamental architectural constraint: vanilla RNNs have no mechanism to maintain gradient magnitude over long distances. The recurrent multiplication is the same every step, driven by the same WhW_h, and there is no way to independently control gradient flow while also encoding sequence semantics.

In[8]:
Code
spectral_radii = np.linspace(0.1, 1.5, 100)
T_fixed = 50
hidden_size_small = 16

norm_after_T = []
for rho in spectral_radii:
    norms = compute_gradient_norms(
        T_fixed, hidden_size_small, rho, activation="tanh", seed=7
    )
    norm_after_T.append(norms[-1])

norm_after_T = np.array(norm_after_T)
Out[9]:
Visualization
Line plot of gradient norm vs spectral radius showing decay for low rho and explosion for high rho.
Final gradient norm after 50 backward steps as a function of the recurrent weight matrix spectral radius. Spectral radii below 1 cause vanishing gradients with norms collapsing toward zero, while spectral radii above 1 cause explosive growth. The vertical dashed line at rho=1 marks the theoretical boundary, but even slightly above this value, the gradient explodes quickly due to the multiplicative structure.

The plot makes the tradeoff vivid. Below spectral radius 1, gradient norms collapse toward zero over 50 steps. Above spectral radius 1, they explode. The inflection point near 1 appears to offer a solution, but even there, the tanh nonlinearity prevents perfect gradient preservation across long sequences.

The knife-edge at spectral radius 1 is not a stable operating point. Small perturbations to WhW_h from weight updates during training will push the spectral radius slightly above or below 1, and the gradient behavior will shift accordingly. Maintaining the spectral radius precisely at 1 would require a constraint on the optimization, and such constraints typically slow convergence and limit the expressiveness of the network.

Code Implementation: Observing Vanishing Gradients Empirically

To see vanishing gradients in a real training scenario, we can train a small RNN on a synthetic long-range dependency task and examine both the gradient norms at each timestep and the model's performance.

Synthetic Long-Range Dependency Task

We create a task where the correct prediction at the final timestep depends on a token that appeared many steps earlier. The network must remember information across an extended blank sequence. This is the classic copying task used in many papers to benchmark recurrent architectures.

In[10]:
Code
import torch

torch.use_deterministic_algorithms(False)


def generate_memory_task(n_samples, delay, vocab_size=8, seed=42):
    """
    Generate sequences where the last token must match the first token.
    Input: [signal, zeros*delay, query]
    Target: predict signal value at the query position.
    """
    torch.manual_seed(seed)
    signals = torch.randint(0, vocab_size, (n_samples,))
    X = torch.zeros(n_samples, delay + 2, dtype=torch.long)
    X[:, 0] = signals
    X[:, -1] = vocab_size  # special query token
    y = signals
    return X, y


delay_short = 5
delay_long = 40
vocab_size = 8
n_train = 800
n_test = 200

X_short, y_short = generate_memory_task(n_train, delay_short, vocab_size)
X_long, y_long = generate_memory_task(n_train, delay_long, vocab_size)
X_short_test, y_short_test = generate_memory_task(
    n_test, delay_short, vocab_size, seed=99
)
X_long_test, y_long_test = generate_memory_task(
    n_test, delay_long, vocab_size, seed=99
)

The task has a deliberate structure. The first token in each sequence is the signal: one of eight possible symbols. The next delay tokens are all zeros, acting as blank filler. The final token is a special query marker. At the query position, the network must predict the symbol that appeared at the very beginning. For a short delay, this is feasible. For a long delay, the gradient cannot reach the signal position.

In[11]:
Code
import torch.nn as nn


class SimpleRNN(nn.Module):
    def __init__(self, vocab_size, embed_dim, hidden_size, n_classes):
        super().__init__()
        self.embed = nn.Embedding(vocab_size + 1, embed_dim)
        self.rnn = nn.RNN(embed_dim, hidden_size, batch_first=True)
        self.classifier = nn.Linear(hidden_size, n_classes)

    def forward(self, x):
        emb = self.embed(x)
        out, _ = self.rnn(emb)
        return self.classifier(out[:, -1, :])


embed_dim = 16
hidden_size = 32
n_classes = vocab_size

model_short = SimpleRNN(vocab_size, embed_dim, hidden_size, n_classes)
model_long = SimpleRNN(vocab_size, embed_dim, hidden_size, n_classes)
In[12]:
Code
import torch
import torch.optim as optim


def train_model(model, X_train, y_train, X_test, y_test, n_epochs=60, lr=0.01):
    optimizer = optim.Adam(model.parameters(), lr=lr)
    criterion = nn.CrossEntropyLoss()
    train_losses = []
    test_accs = []

    for epoch in range(n_epochs):
        model.train()
        logits = model(X_train)
        loss = criterion(logits, y_train)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_losses.append(loss.item())

        if (epoch + 1) % 5 == 0:
            model.eval()
            with torch.no_grad():
                test_logits = model(X_test)
                preds = test_logits.argmax(dim=1)
                acc = (preds == y_test).float().mean().item()
                test_accs.append(acc)

    return train_losses, test_accs


train_loss_short, test_acc_short = train_model(
    model_short, X_short, y_short, X_short_test, y_short_test
)
train_loss_long, test_acc_long = train_model(
    model_long, X_long, y_long, X_long_test, y_long_test
)
Out[13]:
Console
Task: predict which token appeared 5 steps ago
  Final test accuracy: 1.000
  Baseline (random): 0.125

Task: predict which token appeared 40 steps ago
  Final test accuracy: 0.110
  Baseline (random): 0.125
Out[14]:
Visualization
Line plot of training cross-entropy loss decreasing over 60 epochs for short-delay task.
Training loss curve for the short-delay memory task (5 steps). The model converges quickly and achieves high accuracy, confirming the RNN can learn the dependency when it falls within the effective gradient distance.
Line plot of training cross-entropy loss remaining high over 60 epochs for long-delay task.
Training loss curve for the long-delay memory task (40 steps). The loss barely decreases and accuracy remains near the random baseline, which demonstrates that vanilla RNNs cannot learn dependencies beyond the effective gradient distance.

The training curves show a clean contrast. The short-delay model reduces its loss consistently and achieves high accuracy. The long-delay model struggles: its loss barely decreases and its accuracy hovers near the random baseline. The only difference between the two tasks is where the relevant information sits in the sequence. The vanilla RNN architecture provides no mechanism to bridge the gap.

This result is not a function of insufficient training time or a poorly chosen learning rate. We could train for 600 epochs instead of 60, and the long-delay model would still fail. The gradient reaching the signal position is so small that no amount of gradient descent can accumulate useful weight updates.

Measuring Per-Timestep Gradient Norms During Training

We can also look directly at the gradient norms assigned to each timestep by extracting gradients from the computation graph after a backward pass.

In[15]:
Code
def measure_gradient_norms_training(model, X, y):
    """
    Run one forward-backward pass and collect gradient norms
    for the hidden state at each timestep.
    """
    model.train()
    model.zero_grad()
    embed_out = model.embed(X)

    h = torch.zeros(1, X.size(0), model.rnn.hidden_size)
    hiddens = []

    for t in range(X.size(1)):
        xt = embed_out[:, t : t + 1, :]
        _, h = model.rnn(xt, h)
        h.retain_grad()
        hiddens.append(h)

    logits = model.classifier(hiddens[-1].squeeze(0))
    loss = nn.CrossEntropyLoss()(logits, y)
    loss.backward()

    norms = []
    for h_t in hiddens:
        if h_t.grad is not None:
            norms.append(h_t.grad.norm().item())
        else:
            norms.append(0.0)
    return norms


model_for_grad_short = SimpleRNN(vocab_size, embed_dim, hidden_size, n_classes)
model_for_grad_long = SimpleRNN(vocab_size, embed_dim, hidden_size, n_classes)

grad_norms_short = measure_gradient_norms_training(
    model_for_grad_short, X_short[:64], y_short[:64]
)
grad_norms_long = measure_gradient_norms_training(
    model_for_grad_long, X_long[:64], y_long[:64]
)
Out[16]:
Visualization
Bar chart of gradient norms per timestep for short-delay task, with visible signal at early positions.
Per-timestep gradient norms for the short-delay memory task (5 steps). Gradient signal remains measurable at timestep 0 (the signal position, marked in red), allowing the network to learn the dependency through weight updates.
Bar chart of gradient norms per timestep for long-delay task, showing near-zero values at early timesteps.
Per-timestep gradient norms for the long-delay memory task (40 steps). Gradient signal is concentrated near the final timestep and decays to near zero at timestep 0 (the signal position, marked in red), meaning the relevant weights receive virtually no training signal.

These bar plots provide the direct empirical evidence. In the short-delay case, gradient norms are spread across the sequence and remain measurable at timestep 0 where the signal appeared. In the long-delay case, essentially all gradient signal is concentrated in the last few steps. The gradient at timestep 0, where the signal lives, is negligible. The network has no gradient to guide it toward learning the dependency.

Looking at these plots, you can almost feel the network's blindness. The bar chart for the long-delay task shows a tall column at the last timestep, a few smaller bars at the preceding steps, and then essentially nothing for the first 40 timesteps. The signal is there in the data. The network processes it during the forward pass. But the backward pass cannot reach it. The 40 steps of blank tokens between the signal and the query are not just noise: they are a 40-step gradient barrier.

Attempts to Mitigate Vanishing Gradients Without Architecture Changes

Before the LSTM became the standard solution, several techniques were proposed to mitigate vanishing gradients without fundamentally changing the architecture. Understanding why these partial solutions fail is instructive.

Careful Initialization

One approach was to initialize WhW_h to be close to the identity matrix or to have spectral radius exactly 1. This is called identity initialization or orthogonal initialization. With an identity-initialized WhW_h, the gradient product starts at the identity and decays only due to the nonlinearity damping factors. This delays vanishing but does not prevent it.

The practical limitation is that the weight matrix must change during training to learn useful representations. As soon as weight updates begin, the spectral radius moves away from 1, and gradient decay resumes. Constraining the spectral radius during training requires projecting the weight matrix onto the set of orthogonal matrices after every update, which is computationally expensive and disrupts the optimization landscape.

Irene Sutskever and colleagues experimented with careful initialization strategies in the early 2010s and found that they could improve the performance of vanilla RNNs on certain tasks. But the gains were limited: a well-initialized vanilla RNN could match an LSTM on short-sequence tasks but still failed on long sequences where the gradient decay problem was fundamental.

Truncated Backpropagation Through Time

A pragmatic workaround is truncated BPTT: instead of propagating gradients through the full sequence, you stop the backward pass after kk steps. This makes training faster and avoids the numerical instability of very long gradient chains, but it does not solve the problem. It simply admits defeat by explicitly limiting the temporal horizon. The network cannot learn dependencies longer than kk steps by construction.

Truncated BPTT is still widely used as an optimization technique even with LSTM networks, because it reduces memory usage and improves training speed. With LSTMs, the cell state provides a separate gradient path that persists even when the hidden state gradient is truncated, so truncated BPTT is less damaging in practice than it is for vanilla RNNs.

The truncation length kk is a hyperparameter that creates a tradeoff between computational cost and temporal range. Setting kk to 20 means the network can potentially learn dependencies up to 20 steps, but no further. Setting kk to 100 allows longer dependencies but requires holding 100 steps of activations in memory and computing 100 backward steps per update, which is expensive. Most practitioners using vanilla RNNs chose small kk values to keep training tractable, which inadvertently reinforced the impression that RNNs are fundamentally local models.

Gradient Clipping as a Partial Fix

Gradient clipping addresses the exploding gradient problem but has no effect on vanishing gradients. Clipping prevents the gradient from becoming too large, but it cannot inflate a gradient that has already shrunk to near zero. The two problems are not symmetric.

Some practitioners mistakenly apply gradient clipping hoping to stabilize training when they are experiencing vanishing gradients. The loss may still appear to decrease (because local, short-range updates are still occurring), and the absence of NaN errors suggests training is healthy. The silent failure mode of vanishing gradients means these practitioners may train for a long time without realizing that long-range dependencies are never being learned.

Leaky Integration and Echo State Networks

A more radical approach is to abandon gradient-based learning for the recurrent weights entirely. Echo State Networks (ESNs) and Liquid State Machines fix the recurrent weights randomly and only train the output layer via linear regression. This completely sidesteps the vanishing gradient problem by eliminating the recurrent gradient chain. The fixed recurrent weights create a complex dynamical system (the "reservoir") whose state encodes the recent history, and the output layer learns to read out the relevant information.

ESNs can capture some long-range dependencies through the dynamics of the reservoir, but the reliance on random weights limits their flexibility. The reservoir must be large enough and the dynamics complex enough to implicitly represent all the dependencies the task requires, which is not guaranteed. ESNs found niche applications but never became the dominant approach to sequence modeling.

Historical Context: Why This Problem Went Unsolved for So Long

The vanishing gradient problem was not discovered suddenly. It accumulated gradually through the late 1980s and early 1990s as researchers attempted to train recurrent networks on increasingly complex sequence tasks. Sepp Hochreiter identified and formalized the problem in his 1991 diploma thesis. This provides the mathematical analysis we have largely covered in this chapter. The formal analysis in English attracted relatively little attention until the LSTM paper in 1997.

Part of the reason the problem persisted without a reliable solution for several years was that exploding gradients received more attention. Exploding gradients were easy to observe and directly fixable with clipping. Vanishing gradients were difficult to observe and required an architectural solution rather than a training trick.

Another factor was the prevailing belief that training issues with RNNs were due to poor optimization, insufficient data, or bad initialization rather than a fundamental architectural flaw. The culture of the field emphasized that neural networks were universal approximators and that with the right training setup, any network could learn any function. The idea that an architecture could be provably limited in what it could learn via gradient descent, even if theoretically capable of representing the target function with the right weights, was subtle and not immediately accepted.

Hochreiter and Schmidhuber's 1997 LSTM paper was the turning point. It provided the theoretical analysis and a complete architectural solution that was empirically validated on the exact tasks where vanilla RNNs failed. The success of LSTMs on long-range dependency benchmarks demonstrated that the vanishing gradient problem was the bottleneck and that architectural changes could overcome it.

The two-decade gap between the RNN's invention and the LSTM's adoption illustrates a general pattern in deep learning: fundamental limitations are often recognized empirically before they are understood theoretically, and solutions often precede complete theoretical understanding of why they work. The gradient flow analysis we have covered in this chapter was largely worked out by Hochreiter in 1991, but it took the empirical success of LSTMs to convince the broader community that the analysis was pointing to a real and solvable problem.

The Vanishing Gradient Problem in Deep Feedforward Networks

Before leaving this topic, it is worth connecting the RNN vanishing gradient problem to an analogous problem in deep feedforward networks. In a feedforward network with many layers, the gradient must propagate backward through each layer in sequence. If each layer applies a saturating nonlinearity, the gradient is repeatedly multiplied by derivative factors less than 1, producing the same exponential decay we see in RNNs.

This is why very deep feedforward networks were difficult to train before the introduction of batch normalization (2015) and residual connections (2015). A 20-layer network with sigmoid activations would experience the same gradient collapse over 20 backward passes through layers that an RNN experiences over 20 backward steps through time. The problems are mathematically identical.

The solutions are also analogous. Residual connections in feedforward networks create gradient shortcuts that bypass the multiplicative chain, just as the LSTM cell state creates a gradient highway through time. Batch normalization keeps activations away from saturation zones, reducing the damping factor at each step, just as proper initialization can reduce damping in RNNs.

This connection is not a coincidence. Both problems arise from the same root cause: repeated multiplication of Jacobian matrices through a chain of composed functions, where each Jacobian has spectral properties that lead to exponential decay. The solutions in both cases involve creating additive pathways that allow gradients to bypass the multiplicative chain.

Vanishing Gradients and the Depth-Time Analogy

The correspondence between depth in feedforward networks and time in recurrent networks is precise. A feedforward network with LL layers and a recurrent network with sequence length TT both require gradient signals to traverse LL or TT multiplicative factors, respectively. This analogy guided the development of residual connections: researchers who had solved the depth problem in feedforward networks recognized the same structure in the time dimension of RNNs and applied similar architectural ideas.

The connection between RNN vanishing gradients and deep network vanishing gradients also explains why ReLU activations helped feedforward networks train more easily. Unlike sigmoid and tanh, the ReLU function max(0,z)\max(0, z) has a derivative of exactly 1 for positive inputs and 0 for negative inputs. For active neurons (positive pre-activation), ReLU contributes no damping to the gradient. This eliminates the saturation problem in feedforward networks. However, ReLU does not directly help with vanishing gradients in the time dimension of RNNs, because the issue there is the recurrent weight matrix, not the nonlinearity alone.

The Path to LSTM: What the Architecture Needs

The vanishing gradient problem has practical consequences. It is the reason vanilla RNNs are rarely used in modern NLP despite their elegant formulation. The failure is architectural: there is no mechanism in the basic RNN to independently control how much information is retained versus discarded across time, or how much gradient signal is allowed to flow backward.

Any solution to the vanishing gradient problem must address this root cause. The architecture needs a way to:

  • Preserve information over long distances without the information being transformed (and potentially diluted) at every step.
  • Selectively update which information in memory is relevant to the current input.
  • Control gradient flow such that gradients can propagate backward without being repeatedly multiplied by the same shrinking factors.

The LSTM architecture, introduced by Hochreiter and Schmidhuber in 1997, addresses all three requirements through a combination of a separate memory cell and learnable gate mechanisms. Rather than passing the hidden state through a nonlinearity at every step, the LSTM maintains a cell state ctc_t that can change by addition rather than multiplication. Because addition does not shrink gradient magnitudes the way multiplication does, gradients can flow backward through the cell state pathway with minimal attenuation.

Why Addition Solves the Problem

To see intuitively why addition helps, consider the gradient through an additive update. Suppose the cell state evolves as ct=ct1+ftc_t = c_{t-1} + f_t for some input-dependent function ftf_t. The gradient of cTc_T with respect to ctc_t is then:

cTct=ct(ct+k=t+1Tfk)=1\frac{\partial c_T}{\partial c_t} = \frac{\partial}{\partial c_t} \left( c_t + \sum_{k=t+1}^{T} f_k \right) = 1

The gradient is identically 1, regardless of sequence length. Information from any timestep is equally accessible via the cell state pathway. The LSTM's actual update is slightly more complex because the forget gate modulates ct1c_{t-1} before the addition, but the key insight remains: an additive update path creates a near-constant gradient that does not decay with distance.

This is the conceptual heart of LSTM and, later, of residual connections in deep networks. The additive pathway is a gradient highway, allowing the loss at the final timestep to reach and update weights at any earlier position. The gates in LSTM control what information enters the highway and what exits it, but the highway itself is always open.

We will explore the LSTM architecture in detail in the next chapter, and then examine the mathematics of LSTM gradient flow in the chapter after that. The key insight to carry forward from this chapter is that the vanishing gradient problem is a consequence of the multiplicative gradient chain, and any solution must break or bypass this chain for long-distance signals.

Limitations and Practical Impact

The vanishing gradient problem identified a fundamental tension in sequence modeling that influenced architecture design for decades. Even with LSTMs and GRUs, the problem is mitigated rather than eliminated. Gradients still decay over very long sequences in gated architectures, just much more slowly than in vanilla RNNs. The cell state in LSTM provides a nearly constant gradient path, but the gate activations (which are computed through sigmoid functions) do introduce some damping. In practice, LSTMs can reliably learn dependencies spanning hundreds of steps, compared to a few dozen for vanilla RNNs.

The residual connections in modern transformers address a related problem in deep feedforward networks. The analogy between LSTM's additive cell state and ResNet's skip connections is not coincidental: both architectures create gradient highways that allow signals to bypass the multiplicative chain. This connection is developed further in the Transformer Blocks chapter.

Gradient clipping is a standard companion technique to gated architectures. Even though LSTMs suppress the vanishing problem, exploding gradients remain possible in practice, especially in deep or stacked RNN configurations. Monitoring gradient norms during training remains good practice. A common heuristic is to log the global gradient norm every N steps and watch for sudden spikes or sustained elevation above the typical range.

The vanishing gradient analysis also explains why depth in RNNs is more limited than depth in feedforward networks. A deep RNN must propagate gradients both through time and through layers, compounding the decay problem. A two-layer RNN experiences vanishing in the time dimension (across steps) and the depth dimension (across layers), with both decay processes running simultaneously. Residual connections and highway connections were proposed specifically to make deep RNNs more trainable, though in practice the transformer architecture has superseded most deep RNN designs.

The practical impact on the NLP research community between 1997 and 2017 was enormous. The introduction of LSTMs made previously intractable tasks feasible: machine translation, speech recognition, sequence-to-sequence generation, and question answering all saw significant progress with LSTM-based architectures. Much of the neural NLP work of the early 2010s was built on LSTMs. The limitations that LSTMs did not fully overcome, particularly for very long sequences and for tasks requiring non-local structural reasoning, ultimately motivated the development of attention mechanisms and the transformer architecture.

Understanding the vanishing gradient problem is essential for reading this history. Every architectural innovation from LSTM through GRU through transformers can be understood as a successive response to the gradient propagation challenges that vanilla RNNs exposed. The problem was more than a technical obstacle; it was a conceptual clarification that forced the field to think carefully about what learning across time requires and what properties an architecture must have to support it.

Summary

The vanishing gradient problem in RNNs arises because BPTT requires computing a product of TtT - t Jacobian matrices, one per timestep between the current position and the position of the loss. Each Jacobian is bounded in spectral radius by the product of the weight matrix and the activation derivative, which is less than 1 for saturating nonlinearities like tanh and sigmoid. The product of many such factors shrinks exponentially with sequence length.

The key takeaways from this chapter are:

  • The gradient product bound: kDkWh(γWh)Tt\|\prod_{k} D_k W_h\| \leq (\gamma \cdot \|W_h\|)^{T-t} decays exponentially when γWh<1\gamma \cdot \|W_h\| < 1, which holds for all practical initializations with saturating nonlinearities.
  • Sigmoid is worse than tanh: sigmoid's maximum derivative of 0.25 accelerates gradient decay compared to tanh's maximum of 1. In a chain of 10 sigmoid steps, the gradient decays by at least a factor of 10610^6.
  • Exploding vs vanishing: exploding gradients are detectable and fixable with gradient clipping; vanishing gradients are silent and architecturally catastrophic. The asymmetry makes vanishing the harder problem.
  • Effective gradient distance: vanilla RNNs can only reliably learn dependencies spanning at most a few dozen timesteps, far too short for many practical NLP tasks.
  • The credit assignment failure: vanishing gradients cause the network to assign zero credit to distant timesteps, systematically biasing it toward local patterns even when global dependencies are what matter.
  • Partial solutions fall short: careful initialization, truncated BPTT, and echo state networks all address symptoms without solving the underlying architectural problem.
  • LSTM motivation: the vanishing gradient analysis defines exactly what the LSTM must provide, which is an additive update path for a separate memory cell that allows gradients to bypass the multiplicative decay. Addition distributes gradient uniformly, unlike multiplication which amplifies or shrinks it.

The next chapter introduces the LSTM architecture and shows how the cell state and gate mechanisms provide the solution to everything identified here.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about vanishing gradients in RNNs.

Vanishing Gradients Quiz

Question 1 of 70 of 7 completed
What is the primary mathematical reason gradients vanish in vanilla RNNs during backpropagation through time?

Comments

No comments yet. Be the first to share your thoughts!

Reference

Citation details

Cite or share this article.

BIBTEXAcademic
@misc{brenndoerfer2025vanishinggradients, author = {Michael Brenndoerfer}, title = {Vanishing Gradients: Why RNNs Fail on Long Sequences}, year = {2025}, url = {https://mbrenndoerfer.com/writing/vanishing-gradients-rnn-long-range-dependencies}, organization = {mbrenndoerfer.com}, note = {Accessed: 2026-09-15} }
APAAcademic
Michael Brenndoerfer (2025). Vanishing Gradients: Why RNNs Fail on Long Sequences. Retrieved from https://mbrenndoerfer.com/writing/vanishing-gradients-rnn-long-range-dependencies
MLAAcademic
Michael Brenndoerfer. "Vanishing Gradients: Why RNNs Fail on Long Sequences." 2026. Web. September 15, 2026. <https://mbrenndoerfer.com/writing/vanishing-gradients-rnn-long-range-dependencies>.
CHICAGOAcademic
Michael Brenndoerfer. "Vanishing Gradients: Why RNNs Fail on Long Sequences." Accessed September 15, 2026. https://mbrenndoerfer.com/writing/vanishing-gradients-rnn-long-range-dependencies.
HARVARDAcademic
Michael Brenndoerfer (2025) 'Vanishing Gradients: Why RNNs Fail on Long Sequences'. Available at: https://mbrenndoerfer.com/writing/vanishing-gradients-rnn-long-range-dependencies (Accessed: September 15, 2026).
SimpleBasic
Michael Brenndoerfer (2025). Vanishing Gradients: Why RNNs Fail on Long Sequences. https://mbrenndoerfer.com/writing/vanishing-gradients-rnn-long-range-dependencies

About the author

Continue with the full handbook

This chapter is part of Language AI Handbook. Use the handbook page to browse the complete table of contents and continue reading in sequence.

Explore Language AI Handbook
Newsletter

Stay up to date

Get articles, book updates, and news delivered to your inbox.

No spam, unsubscribe anytime.

or

Join the community

Sign in to remove popups, track your reading progress, and join the discussion.