Unit 11, lesson 74

Sequence Models and Recurrent Neural Networks

How a recurrent neural network carries a hidden state along a sequence, how backpropagation through time trains its shared weights, what LSTM and GRU gates do, and how padding, masks and teacher forcing are handled.

  • Video 74
  • Recurrence, Attention and Transformers

A machine logs its status as a stream of events such as ready, move and wait, and the next event depends on what happened before and in which order. Counting the events throws the order away, and a feed-forward network expects a fixed number of inputs, while sessions differ in length. A recurrent network reads the stream one step at a time and carries a summary forward. This lesson traces that computation by hand, shows how its shared weights are trained, introduces the gated cells used in practice, and sets out the bookkeeping of padding, masks and teacher forcing that keeps training honest, with sequences and weights constructed for teaching.

Key terms

Recurrent neural network and hidden state

Definition A recurrent neural network (RNN) reads a sequence of input vectors x1,…,xT\mathbf{x}_1, \dots, \mathbf{x}_T in Rd\mathbb{R}^d in order. Starting from an initial hidden state h0\mathbf{h}_0 in Rdh\mathbb{R}^{d_h}, usually the zero vector, the simple recurrent cell computes for t=1,…,Tt = 1, \dots, T

at=Wxxt+Whht−1+b,ht=tanh⁡(at),\begin{aligned} \mathbf{a}_t &= W_x \mathbf{x}_t + W_h \mathbf{h}_{t-1} + \mathbf{b} , \\[0.4em] \mathbf{h}_t &= \tanh(\mathbf{a}_t) , \end{aligned}

with WxW_x of shape dh×dd_h \times d, WhW_h of shape dh×dhd_h \times d_h, b\mathbf{b} in Rdh\mathbb{R}^{d_h}, and tanh applied to each entry. The hidden state ht\mathbf{h}_t depends only on h0\mathbf{h}_0, the parameters and the inputs x1,…,xt\mathbf{x}_1, \dots, \mathbf{x}_t. An output layer reads it, for example KK next-symbol scores zt=Wyht+by\mathbf{z}_t = W_y \mathbf{h}_t + \mathbf{b}_y with WyW_y of shape K×dhK \times d_h, followed by a softmax. The same parameters are used at every step, so their number, dh(d+dh+1)d_h(d + d_h + 1) for the cell, does not depend on TT, and one network handles sequences of any length. A whole sequence, such as one machine session, is one example, and its steps are dependent parts of that example, not separate independent examples.

In plain words The hidden state is the network’s running summary of everything it has read so far. Each step folds the new input into the previous summary with the same weights. The summary has a fixed size and is learned, not a record of every past event, so information that a later prediction needs can be lost. The state starts fresh at the beginning of each independent sequence. Carrying it from one machine’s session into another’s mixes unrelated examples, unless the task deliberately treats them as one continuous stream.

Example Take scalar inputs and states, d=dh=1d = d_h = 1, with wx=1w_x = 1, wh=0.5w_h = 0.5, b=0b = 0 and h0=0h_0 = 0, and give three observed statuses the chosen codes 11, 00 and −1-1. The codes are a convenience for hand calculation, not a claim that the statuses are ordered. Then

h1=tanh⁡(1)≈0.7616,h2=tanh⁡(0.3808)≈0.3634,h3=tanh⁡(−0.8183)≈−0.6741.\begin{aligned} h_1 &= \tanh(1) \approx 0.7616 , \\[0.4em] h_2 &= \tanh(0.3808) \approx 0.3634 , \\[0.4em] h_3 &= \tanh(-0.8183) \approx -0.6741 . \end{aligned}

The second input is 0, yet h2h_2 is not, because the earlier state still contributes. The same three inputs in the order 00, 11, −1-1 end at h3≈−0.5506h_3 \approx -0.5506, so the final state depends on the order and not only on which inputs occurred. The reversed order −1-1, 00, 11 happens to be the negative of the original sequence, and because tanh is odd and b=h0=0b = h_0 = 0, every state changes sign and the sequence ends at about 0.67410.6741.

Backpropagation through time

Definition Backpropagation through time (BPTT) computes the gradient of a sequence loss by unrolling the recurrence into one computation graph, with one copy of the cell per step, and applying the chain rule backward from the last step to the first. A shared parameter is used at every step, so its gradient is the sum of the contributions of all its uses. For the cell above and a loss L=∑tℓtL = \sum_t \ell_t, let gt=∂ℓt/∂ht\mathbf{g}_t = \partial \ell_t / \partial \mathbf{h}_t be the direct derivative of the step loss, the zero vector for a step without a loss, and set δT+1=0\boldsymbol{\delta}_{T+1} = \mathbf{0}. Going backward for t=T,…,1t = T, \dots, 1, the gradient of LL with respect to at\mathbf{a}_t is

δt=(1−ht⊙ht)⊙(gt+Wh⊤δt+1),\begin{aligned} \boldsymbol{\delta}_t &= \bigl(\mathbf{1} - \mathbf{h}_t \odot \mathbf{h}_t\bigr) \\[0.4em] &\quad \odot \bigl(\mathbf{g}_t + W_h^{\top} \boldsymbol{\delta}_{t+1}\bigr) , \end{aligned}

where ⊙\odot is the entrywise product, and the parameter gradients are

∂L∂Wh=∑t=1Tδtht−1⊤,∂L∂Wx=∑t=1Tδtxt⊤,∂L∂b=∑t=1Tδt.\begin{gathered} \frac{\partial L}{\partial W_h} = \sum_{t=1}^{T} \boldsymbol{\delta}_t \mathbf{h}_{t-1}^{\top} , \\[0.4em] \frac{\partial L}{\partial W_x} = \sum_{t=1}^{T} \boldsymbol{\delta}_t \mathbf{x}_t^{\top} , \\[0.4em] \frac{\partial L}{\partial \mathbf{b}} = \sum_{t=1}^{T} \boldsymbol{\delta}_t . \end{gathered}

Truncated BPTT stops the backward pass after a fixed number of steps. It saves memory and time, but no gradient then reaches back across the cut, although the state values still do.

In plain words The unrolled network looks like a deep network with one layer per time step, except that every layer has the same weights. Each copy produces its own gradient for those weights, and the true gradient is their sum. A gradient that keeps only the last step’s direct use misses every path through earlier states. Along a long path the derivative is a product of many factors, so it can shrink toward zero or grow out of control, which is why long-range dependencies are hard to learn and why gradient clipping is often used to limit the size of an update.

Example For an exact hand calculation, drop the tanh and use the scalar linear recurrence ht=aht−1+wxth_t = a h_{t-1} + w x_t with h0=0h_0 = 0, inputs x1=2x_1 = 2 and x2=1x_2 = 1, a=0.5a = 0.5, w=0.4w = 0.4 and the loss L=12(h2−1)2L = \tfrac12 (h_2 - 1)^2. Then h1=0.8h_1 = 0.8, h2=0.5⋅0.8+0.4=0.8h_2 = 0.5 \cdot 0.8 + 0.4 = 0.8 and L=0.02L = 0.02. Since h2=w(ax1+x2)h_2 = w(a x_1 + x_2),

∂L∂w=(h2−1)(ax1+x2)=−0.2⋅2=−0.4.\begin{aligned} \frac{\partial L}{\partial w} &= (h_2 - 1)(a x_1 + x_2) \\[0.4em] &= -0.2 \cdot 2 = -0.4 . \end{aligned}

The use of ww at step 1 contributes (h2−1)ax1=−0.2(h_2 - 1) a x_1 = -0.2 and its use at step 2 contributes (h2−1)x2=−0.2(h_2 - 1) x_2 = -0.2, so keeping only the direct use at the last step would give half the gradient. For aa, the use at step 2 gives (h2−1)h1=−0.16(h_2 - 1) h_1 = -0.16, and the use at step 1 adds nothing because h0=0h_0 = 0. Central differences confirm both values. In this recurrence the derivative of h20h_{20} with respect to h0h_0 is a20a^{20}, about 9.5×10−79.5 \times 10^{-7} for a=0.5a = 0.5 and about 3325 for a=1.5a = 1.5.

Long short-term memory

Definition A long short-term memory (LSTM) cell carries two vectors of width dhd_h, a cell state ct\mathbf{c}_t and a hidden state ht\mathbf{h}_t. Let ut\mathbf{u}_t be the vector that stacks xt\mathbf{x}_t on top of ht−1\mathbf{h}_{t-1}. In the common form with a forget gate, the cell computes three gates and a candidate,

ft=σ(Wfut+bf),it=σ(Wiut+bi),ot=σ(Wout+bo),c~t=tanh⁡(Wcut+bc),\begin{gathered} \mathbf{f}_t = \sigma(W_f \mathbf{u}_t + \mathbf{b}_f) , \\[0.4em] \mathbf{i}_t = \sigma(W_i \mathbf{u}_t + \mathbf{b}_i) , \\[0.4em] \mathbf{o}_t = \sigma(W_o \mathbf{u}_t + \mathbf{b}_o) , \\[0.4em] \tilde{\mathbf{c}}_t = \tanh(W_c \mathbf{u}_t + \mathbf{b}_c) , \end{gathered}

and then updates

ct=ft⊙ct−1+it⊙c~t,ht=ot⊙tanh⁡(ct).\begin{aligned} \mathbf{c}_t &= \mathbf{f}_t \odot \mathbf{c}_{t-1} \\[0.4em] &\quad + \mathbf{i}_t \odot \tilde{\mathbf{c}}_t , \\[0.4em] \mathbf{h}_t &= \mathbf{o}_t \odot \tanh(\mathbf{c}_t) . \end{aligned}

Here σ\sigma is the logistic sigmoid applied to each entry, so every gate entry lies strictly between 0 and 1, and each of the four matrices has shape dh×(d+dh)d_h \times (d + d_h). The forget gate ft\mathbf{f}_t scales the old cell state, the input gate it\mathbf{i}_t scales the candidate, and the output gate ot\mathbf{o}_t controls how much of the cell state appears in the hidden state. All gates are learned functions of the current input and the previous hidden state. In this form an LSTM cell has 4dh(d+dh+1)4 d_h (d + d_h + 1) parameters, four times as many as a simple recurrent cell of the same widths.

In plain words The cell state is a lane that runs through time with only entrywise scaling and addition. A forget gate near 1 keeps a value, a forget gate near 0 erases it, and the input gate decides how much new content enters. The direct path from ct−1\mathbf{c}_{t-1} to ct\mathbf{c}_t multiplies by the forget gate entries and nothing else, so gradients along it can travel much further than through repeated multiplication by WhW_h and tanh derivatives. That helps without guaranteeing anything, because the gates are learned and can close or saturate, and the memory a cell of fixed width can hold is limited.

Example Take one coordinate with old cell value 2, forget gate 0.8, input gate 0.1 and candidate −1-1. The new cell value is 0.8⋅2+0.1⋅(−1)=1.50.8 \cdot 2 + 0.1 \cdot (-1) = 1.5, and with output gate 0.5 the hidden value is 0.5tanh⁡(1.5)≈0.45260.5 \tanh(1.5) \approx 0.4526. If the forget gate stayed at 0.9 and the input gate at 0 for 20 steps, the value 2 would decay to 2⋅0.920≈0.24322 \cdot 0.9^{20} \approx 0.2432, so retention is soft rather than perfect. With a forget gate near 0 and an input gate near 1 the old value is almost erased and replaced by the candidate.

Gated recurrent unit

Definition A gated recurrent unit (GRU) keeps a single state ht\mathbf{h}_t and uses two gates. With ut\mathbf{u}_t stacking xt\mathbf{x}_t and ht−1\mathbf{h}_{t-1}, one common form computes the update gate zt=σ(Wzut+bz)\mathbf{z}_t = \sigma(W_z \mathbf{u}_t + \mathbf{b}_z) and the reset gate rt=σ(Wrut+br)\mathbf{r}_t = \sigma(W_r \mathbf{u}_t + \mathbf{b}_r), then a candidate from the input and the reset previous state,

h~t=tanh⁡(Wnvt+bn),\tilde{\mathbf{h}}_t = \tanh(W_n \mathbf{v}_t + \mathbf{b}_n) ,

where vt\mathbf{v}_t stacks xt\mathbf{x}_t and rt⊙ht−1\mathbf{r}_t \odot \mathbf{h}_{t-1}, and finally the blend

ht=(1−zt)⊙ht−1+zt⊙h~t.\begin{aligned} \mathbf{h}_t &= (\mathbf{1} - \mathbf{z}_t) \odot \mathbf{h}_{t-1} \\[0.4em] &\quad + \mathbf{z}_t \odot \tilde{\mathbf{h}}_t . \end{aligned}

Each coordinate of the new state lies between the old state and the candidate, and in this convention zt\mathbf{z}_t is the share given to the candidate. The original GRU and several software libraries write ht=zt⊙ht−1+(1−zt)⊙h~t\mathbf{h}_t = \mathbf{z}_t \odot \mathbf{h}_{t-1} + (\mathbf{1} - \mathbf{z}_t) \odot \tilde{\mathbf{h}}_t instead, so that their zt\mathbf{z}_t is the share kept from the old state. Because 1−σ(s)=σ(−s)1 - \sigma(s) = \sigma(-s), negating the weights and bias of the update gate turns one convention into the other, and both describe the same family of models. In the form written here a GRU cell has 3dh(d+dh+1)3 d_h (d + d_h + 1) parameters.

In plain words The update gate decides, coordinate by coordinate, how much of the state to replace, and the reset gate decides how much of the old state the candidate may use. When the update gate is near 0, this page’s convention copies the state almost unchanged, which lets information and gradients pass many steps. A GRU has one state instead of two and fewer parameters than an LSTM of the same width, and neither cell is better on every task. Because the two conventions name the gate in opposite ways, read the formula rather than the gate’s name.

Example With old state 0.4, candidate −0.6-0.6 and update gate 0.25, the new state is 0.75⋅0.4+0.25⋅(−0.6)=0.150.75 \cdot 0.4 + 0.25 \cdot (-0.6) = 0.15, a quarter of the way from the old state to the candidate. Reading the same value 0.25 in the other convention gives 0.25⋅0.4+0.75⋅(−0.6)=−0.350.25 \cdot 0.4 + 0.75 \cdot (-0.6) = -0.35, three quarters of the way. For d=4d = 4 and dh=6d_h = 6 a simple recurrent cell has 6⋅11=666 \cdot 11 = 66 parameters, a GRU cell 3⋅66=1983 \cdot 66 = 198 and an LSTM cell 4⋅66=2644 \cdot 66 = 264.

Sequence padding and sequence mask

Definition Sequence padding appends placeholder positions to sequences of unequal lengths L1,…,LBL_1, \dots, L_B so that a batch fits one array of shape B×T×dB \times T \times d with T≥max⁡iLiT \ge \max_i L_i. In this batch-first layout the hidden states form an array of shape B×T×dhB \times T \times d_h. Some libraries put the time axis first, so the layout has to be checked, not guessed. The sequence mask is the B×TB \times T array with mit=1m_{it} = 1 when step tt of sequence ii holds a real observation and mit=0m_{it} = 0 at padding. For per-step losses ℓit\ell_{it} the masked mean is

L=∑i,tmitℓit∑i,tmit,L = \frac{\sum_{i,t} m_{it} \ell_{it}}{\sum_{i,t} m_{it}} ,

defined when at least one position is valid. It weights every valid step equally, so long sequences count more than short ones, and averaging within each sequence first is a different choice that has to be declared. Padded positions never become targets. A recurrence whose final state is used either stops at each sequence’s length or keeps the state unchanged at masked steps, hit=hi,t−1\mathbf{h}_{it} = \mathbf{h}_{i,t-1} when mit=0m_{it} = 0.

In plain words Padding exists only to make the arrays rectangular. The mask records which cells are real, and every loss, average and final state has to respect it. Dividing by all cells would make the reported loss depend on how much padding a batch happens to contain.

Example Pad two sequences of lengths 3 and 1 to T=3T = 3. The mask rows are (1,1,1)(1, 1, 1) and (1,0,0)(1, 0, 0), so there are 4 valid targets, not 6. With valid losses 0.2, 0.4, 0.6 and 0.8 the masked mean is 2/4=0.52/4 = 0.5, while dividing by all 6 cells would report about 0.333 without any prediction changing. Now feed the short sequence, input 1 followed by two padding zeros, to the scalar network of the first card. The state after the real step is tanh⁡(1)≈0.7616\tanh(1) \approx 0.7616. Running the recurrence through the padding would continue to tanh⁡(0.3808)≈0.3634\tanh(0.3808) \approx 0.3634 and then tanh⁡(0.1817)≈0.1797\tanh(0.1817) \approx 0.1797, while the masked update keeps 0.76160.7616 as the final state.

Teacher forcing

Definition Teacher forcing trains a next-symbol model by feeding it the observed previous symbols. For an observed sequence y1,…,yTy_1, \dots, y_T preceded by a start symbol y0y_0, the input at step tt is yt−1y_{t-1}, the target is yty_t, and the training loss is

−∑t=1Tln⁡Pθ(yt∣y<t),-\sum_{t=1}^{T} \ln P_{\boldsymbol{\theta}}(y_t \mid y_{<t}) ,

where y<ty_{<t} stands for y0,…,yt−1y_0, \dots, y_{t-1}. This is the negative log-likelihood of the sequence under the factorization of P(y1,…,yT∣y0)P(y_1, \dots, y_T \mid y_0) into the product of the conditionals P(yt∣y<t)P(y_t \mid y_{<t}), so teacher forcing is maximum likelihood estimation for such a model. The model must be causal, meaning the prediction for step tt may depend only on y<ty_{<t}. At generation time the observed symbols do not exist, and the input at each step is the model’s own previous output.

In plain words During training the model always sees the true history and is graded one step at a time. During generation it sees its own guesses, and one wrong guess changes every later input and state. The teacher-forced loss therefore measures one-step prediction from correct histories. If generation is the intended use, generated sequences need their own evaluation, including how the model stops and how early mistakes spread. A bidirectional network, whose states also read later positions, would see the very symbol it is asked to predict and cannot be trained this way for next-symbol prediction.

Example For the constructed session START, READY, MOVE, STOP, the inputs are START, READY and MOVE and the targets are READY, MOVE and STOP, shifted by one position. Feeding READY at the step that must predict READY would hand the model the answer, and the training loss would look excellent while teaching nothing usable. At generation time, if the model’s first output were WAIT instead of READY, its second input would be WAIT, a history that teacher-forced training on this session never supplied.

Check yourself

  1. A batch holds three sequences padded to five steps, with input width 4, hidden width 6 and true lengths 5, 3 and 2. In the batch-first layout with the simple recurrent cell, give the shapes of the input array, the hidden-state array, WxW_x and WhW_h, the number of cell parameters, and the denominator of the masked mean loss with one target per real step.
Show the answer

The input array is 3×5×43 \times 5 \times 4 and the hidden-state array is 3×5×63 \times 5 \times 6. The weight matrices are WxW_x of shape 6×46 \times 4 and WhW_h of shape 6×66 \times 6, and the bias has 6 entries, so the cell has 24+36+6=6624 + 36 + 6 = 66 parameters. That number depends on neither the batch size nor the padded length, because the same parameters serve every sequence and every step.

There are 5+3+2=105 + 3 + 2 = 10 valid targets, so the masked mean divides the summed valid losses by 10, not by the 3⋅5=153 \cdot 5 = 15 cells of the padded array.

  1. A next-event predictor uses, at step tt, the centered average (mt−1+mt+mt+1)/3(m_{t-1} + m_t + m_{t+1})/3 of a measurement mm as a feature for predicting mt+1m_{t+1}. With the measurements 3, 5, 10 and 8, compute the feature at t=3t = 3 and explain what is wrong. How should the windows and the evaluation be fixed?
Show the answer

The feature at t=3t = 3 is (5+10+8)/3=23/3≈7.667(5 + 10 + 8)/3 = 23/3 \approx 7.667. It contains m4=8m_4 = 8, which is exactly the value to be predicted, so the target leaks into the input. At prediction time mt+1m_{t+1} is not yet known, and a model trained with this feature would rely on information it will never have.

The fix is a window whose right edge is the prediction origin, such as the trailing average (mt−2+mt−1+mt)/3(m_{t-2} + m_{t-1} + m_t)/3, which at t=3t = 3 is (3+5+10)/3=6(3 + 5 + 10)/3 = 6. Every window has to be rebuilt this way, the model refitted, and the earlier scores discarded, since they measured the leaky procedure. Overlapping windows from one session should also stay in one data role, with a split by session or by time, because a random split of overlapping windows puts nearly identical inputs on both sides.

  1. Use the linear recurrence ht=aht−1+wxth_t = a h_{t-1} + w x_t with h0=0h_0 = 0, inputs x1=1x_1 = 1 and x2=3x_2 = 3, a=0.5a = 0.5, w=0.2w = 0.2 and the loss L=12h22L = \tfrac12 h_2^2. Find h1h_1, h2h_2 and LL, the derivative of LL with respect to ww split into its two uses, and the derivative with respect to aa. What would a gradient that keeps only the last step’s direct use of ww report?
Show the answer

The states are h1=0.2⋅1=0.2h_1 = 0.2 \cdot 1 = 0.2 and h2=0.5⋅0.2+0.2⋅3=0.7h_2 = 0.5 \cdot 0.2 + 0.2 \cdot 3 = 0.7, so L=12⋅0.49=0.245L = \tfrac12 \cdot 0.49 = 0.245. Since h2=w(ax1+x2)h_2 = w(a x_1 + x_2) and ∂L/∂h2=h2\partial L / \partial h_2 = h_2,

∂L∂w=h2(ax1+x2)=0.7⋅3.5=2.45.\begin{aligned} \frac{\partial L}{\partial w} &= h_2 (a x_1 + x_2) \\[0.4em] &= 0.7 \cdot 3.5 = 2.45 . \end{aligned}

The use at step 1 contributes 0.7⋅0.5⋅1=0.350.7 \cdot 0.5 \cdot 1 = 0.35 and the use at step 2 contributes 0.7⋅3=2.10.7 \cdot 3 = 2.1. The derivative with respect to aa is h2h1=0.7⋅0.2=0.14h_2 h_1 = 0.7 \cdot 0.2 = 0.14, all of it from step 2, because the use of aa at step 1 multiplies h0=0h_0 = 0.

A gradient that keeps only the direct use at step 2 would report 2.1 and miss the 0.35 that flows through h1h_1, about 14 percent of the true value. Central differences agree with 2.45 and 0.14.

How this lesson connects