✎ Edit content·DAY 045 · POST 3 OF 5 · How It Works

Recurrent Neural Networks

Deep Learning · 12 slides
DAY 045 · POST 3 OF 5
(REMINDER)
DAY 045
An RNN, Traced Step by Step
@saurav_dnj_24github.com/SauravDnj · linkedin.com/in/sauravdnj
1 / 12

Theme

Palette

Download

4K — sharpest, slowest
🎬 Video options
Preparing preview…
Live preview · loops the “none” effect
All rendering runs in your browser. No server, no cost, no upload. MP4/WebM = full motion + effects · GIF = lightweight loop · PNG/PDF = static for the Instagram & LinkedIn carousel.

Caption (tap to copy)

📖 Deep dive (full written explanation)

The slides stay clean and scannable. Here's the in-depth explanation behind each one — great for the blog version, show notes, or studying the topic properly.
Slide 1 · An RNN, Traced Step by Step

This is the engine-room post. The previous two established what an RNN is and why it mattered; here we replace intuition with explicit mechanics, tracing both the forward recurrence and the backward pass on a small enough example to follow by hand.

The payoff is that two later concepts — backpropagation through time and the vanishing-gradient problem — stop being vocabulary and become things you have actually watched happen. Doing the trace once is worth more than reading ten explanations.

Slide 2 · The recurrence equation

The recurrence equation is the whole forward computation in one line: h_t = tanh(W_x · x_t + W_h · h_{t-1} + b). W_x decides how the new input influences the state, W_h decides how the previous memory persists, the bias shifts the result, and tanh squashes everything into the range [-1, 1] to keep the state bounded.

An optional output y_t = W_y · h_t reads a prediction off the state. That is the complete parameter inventory of a vanilla RNN: three matrices and a bias. Everything the model 'knows' lives in W_x, W_h, W_y, and b.

Slide 3 · The forward pass, in order

Listing the forward pass as ordered steps makes the loop concrete. You begin with h_0 set to zeros — an empty memory. At each step you read the current input and the previous hidden state, combine them through the recurrence to get the new state, optionally emit an output, and continue until the sequence ends.

The critical detail is that h_{t-1} is reused as an input to compute h_t. That single dependency is what threads information through time and what later forces backpropagation to flow backward through every step. Internalize the order now and the backward pass will make sense.

Slide 4 · Forward pass, with cache

This forward-pass code mirrors the steps exactly and adds one production-relevant detail: the cache. As the loop runs, it stores the input, the resulting hidden state, and the pre-activation z at every step. These saved values are not optional bookkeeping — they are required by the backward pass.

This is the same forward-then-backward dependency you would have seen in the backpropagation material: you cannot compute gradients without the intermediate values from the forward pass. Storing them as you go is what makes BPTT possible, and it is also why long sequences cost memory.

Slide 5 · Unrolling turns it into a deep net

The unrolling diagram is the conceptual bridge to training. Although the RNN is physically one cell looping on itself, you can lay each time step out as its own layer, producing a deep feedforward network where every layer shares the identical W_x and W_h.

This reframing is powerful because it means you do not need a new training algorithm — you can apply ordinary backpropagation to the unrolled graph. The 'depth' of this unrolled network equals the sequence length, which foreshadows why very long sequences cause the gradient problems explored two slides later.

Slide 6 · Backprop through time (BPTT)

Backpropagation through time (BPTT) is just backprop applied to the unrolled network, with one twist from weight sharing. Because the same weight matrix appears at every unrolled layer, that weight's true gradient is the SUM of the gradients computed at each individual time step.

This summing is easy to forget and important to get right: a single weight gets a learning signal from every position where it was used. Mechanically, you walk the time steps in reverse, accumulating each weight's contribution as you go, which is exactly what the next code slide implements.

Slide 7 · BPTT, the gradient flow

This snippet makes BPTT explicit. Walking the cached states in reverse, at each step it combines the gradient arriving from this step's output with the gradient passed back from the future step (dh_next). It pushes that through the tanh derivative (1 - h squared), accumulates the contributions to W_x and W_h, and then computes the gradient to hand back to the previous step.

The line dh_next = Wh.T @ dz is the heart of it: the gradient is repeatedly multiplied by W_h as it travels backward through time. That repeated multiplication by the same matrix is the mechanism behind the vanishing and exploding gradient behavior shown next.

Slide 8 · Why gradients vanish over time

The bar chart visualizes vanishing gradients concretely. The gradient signal reaching recent time steps stays strong, but as you trace further back in time it shrinks — noticeably weaker at step 8 and nearly zero by step 20.

The cause is the repeated multiplication by W_h seen in the previous slide: factors smaller than one compound toward zero over many steps. The practical meaning is that a vanilla RNN's learning signal barely reaches distant past inputs, so it effectively cannot learn long-range dependencies. This chart is the visual proof of a limitation the day keeps returning to.

Slide 9 · The vanishing / exploding problem

Here the vanishing/exploding problem is stated as the core failure mode. Because BPTT multiplies by W_h once per step, the magnitude of W_h's influence governs everything: values below one drive the gradient toward zero (vanishing, so distant context is forgotten), and values above one blow it up (exploding, so training destabilizes).

This is not a bug to be patched but an inherent property of the architecture, and it is precisely the problem that motivated LSTMs and GRUs. Their gating mechanisms create a more stable path for gradients to flow over long spans, which is why they dominate when long-range memory matters.

Slide 10 · The full loop, framework version

The final code slide shows that in practice the framework hides all this machinery. nn.RNN runs the forward recurrence, loss.backward() performs BPTT automatically through autograd, and you never write the manual loop from the earlier slides.

The one line you should still add yourself is clip_grad_norm_, which caps the gradient magnitude to prevent the exploding case from wrecking a training run. Seeing the hand-traced version first is what lets you trust and debug the framework version — you now know exactly what backward() is doing under the hood.

Slide 11 · The trace, locked in

This recap pins down the mechanics: the recurrence is h_t = tanh(W_x x_t + W_h h_{t-1} + b); you cache states on the forward pass; unrolling turns the loop into one deep net with shared weights; BPTT sums each weight's gradient across all time steps; and the repeated W_h factor is what causes gradients to vanish or explode.

With the math traced by hand, you are ready to build the real thing. The next post assembles a working, trainable RNN in PyTorch.

Slide 12 · Save this. Follow for Day 46.

The teaser points to the hands-on build. Having traced the forward and backward passes manually, the next post puts it together as a complete PyTorch model — data preparation, model definition, the training loop, and generation — so the mechanics become a working artifact you can run and modify.

🎨 AI image prompt (matches this theme + palette)

Paste into Midjourney, DALL·E, Ideogram, etc. to generate an on-brand image, then upload it on the Edit content page. The prompt updates automatically with the selected theme + palette.