Deep Learning2019beginner20 min read

Recurrent Neural Networks (RNNs): A Gentle Introduction and Overview

الشبكات العصبية المتكررة: من ذاكرة تتلاشى إلى الانتباه

Schmidt, R. M. — arXiv

The problem

Feedforward networks take a fixed-size input and have no memory, so they cannot handle text, speech or time series whose meaning depends on order and whose length varies. Recurrent networks fix that with a carried from step to step, but training them means multiplying gradients through every step of the , and those products vanish or explode over long sequences. The field produced a long line of fixes, from gated cells to , scattered across many papers with different notations, and newcomers had no single place to follow the thread.

The contribution

A tutorial-style survey that builds RNNs from first principles in one consistent notation. It writes out the recurrence (Eq. 1–2), derives and shows where the repeated product ∂Ht/∂Hk\partial \mathbf{H}_t / \partial \mathbf{H}_k comes from (Eq. 9–12), explains Truncated BPTT, and then walks through the architectural fixes in order: gates (Eq. 13–18), deep and bidirectional RNNs (Eq. 19–24), encoder–decoder models, attention with six score functions, Pointer Networks (Eq. 29) and the , with step-by-step figures in the appendices.

The impact

As a survey, its value is as a map rather than a new result. It condenses the path from the vanilla to the Transformer into one readable document, written as an entry point to sequence models. It closes by pointing to AlphaStar, the StarCraft II agent that combines LSTMs, Transformers and Pointer Networks, as a place where all of these pieces meet.

Picture yourself reading a novel one page at a time, allowed to keep only a single index card of notes. After every page you partly rewrite the card: you rub out a little of what was there and add a little of the new page. And it is always the same you, with the same habits, doing the reading.

That is a recurrent network. Its weakness lives in the rewriting. The first chapter is diluted a little more with every page, until by the end of the book almost nothing of it is left on the card. Everything in this paper is an answer to one question: how do you keep chapter one alive?

A network that remembers by carrying its state forward

A feedforward network sees its whole input at once and forgets it as soon as it answers. That is fine for a photo, but useless for a sequence: a sentence, a genome, a stock price, handwriting. There, the meaning of each element depends on what came before it, and sequences do not come in one fixed length.

A recurrent neural network solves this with . It reads one element per time step and keeps a hidden state Ht\mathbf{H}_t, a vector that summarises everything seen so far. At each step the new state is computed from two things: the current input Xt\mathbf{X}_t and the previous state Ht−1\mathbf{H}_{t-1}. Information no longer flows only forward; it loops back.

The crucial detail is that the same weights are used at every step. This is , and it is what lets one network handle a sequence of any length.

Ht=ϕh(XtWxh+Ht−1Whh+bh)Ot=ϕo(HtWho+bo)\mathbf{H}_{t} = \phi_{h}\left(\mathbf{X}_{t}\mathbf{W}_{xh} + \mathbf{H}_{t-1}\mathbf{W}_{hh} + \mathbf{b}_{h}\right) \qquad \mathbf{O}_t = \phi_o\left(\mathbf{H}_t\mathbf{W}_{ho} + \mathbf{b}_o\right)
The recurrence and the output (Eq. 1–2) — The first equation updates the memory; the second reads an answer out of it. The new hidden state mixes the current input (through Wxh\mathbf{W}_{xh}) with the previous state (through Whh\mathbf{W}_{hh}) and squashes the result with an activation ϕh\phi_h, usually tanh. The output at step tt depends only on the state at step tt. None of the matrices carries a time index: the same Wxh\mathbf{W}_{xh}, Whh\mathbf{W}_{hh} and Who\mathbf{W}_{ho} serve every step.
Open in Lab
Switch between the rolled loop and the unrolled copies. Drag w_h and every recurrent edge changes at once, because there is only one. Then move T and watch the parameter count stay put. Finally give each step its own weight and push T past 5: the network has nothing to run on.
The demo wakes as you arrive…

Drawing the loop out, one copy per time step, is called . It adds no new machinery; it is simply the same cell drawn TT times, with each copy handing its state to the next. Unrolled, an RNN looks like a very deep feedforward network whose layers all share their weights, and that picture is the key to training it.

is also a statement about the world. By using one set of weights everywhere, the network assumes that a pattern means the same thing whether it appears at step 3 or step 300. The price is that whatever links an early input to a late output, the , has to be carried through every copy in between. How well that link survives the trip is the subject of the next two sections.

Training means unrolling, then running backprop through every copy

Once the network is unrolled, ordinary backpropagation almost works. The paper calls the result Backpropagation Through Time (BPTT). The loss is summed over the time steps, L(O,Y)=∑t=1Tℓt(Ot,Yt)\mathcal{L}(\mathbf{O},\mathbf{Y}) = \sum_{t=1}^{T}\ell_t(\mathbf{O}_t,\mathbf{Y}_t) (Eq. 5). The gradient for the output weights Who\mathbf{W}_{ho} is easy, because each output depends only on its own step (Eq. 6).

The recurrent weights are harder. A change to Whh\mathbf{W}_{hh} affects H1\mathbf{H}_1, which affects H2\mathbf{H}_2, and so on, so the loss at step tt depends on Whh\mathbf{W}_{hh} through every earlier step kk. The then produces a sum over all those paths, and each path carries the factor ∂Ht/∂Hk\partial \mathbf{H}_t / \partial \mathbf{H}_k: how much the state at step kk still moves the state at step tt.

∂L∂Whh=∑t=1T∂ℓt∂Ot⋅∂Ot∂ϕo⋅Who∑k=1t∂Ht∂Hk⋅∂Hk∂Whh\frac{\partial \mathcal{L}}{\partial \mathbf{W}_{hh}} = \sum_{t=1}^{T} \frac{\partial \ell_t}{\partial \mathbf{O}_t}\cdot\frac{\partial \mathbf{O}_t}{\partial \phi_o}\cdot\mathbf{W}_{ho}\sum_{k=1}^{t}\frac{\partial \mathbf{H}_t}{\partial \mathbf{H}_k}\cdot\frac{\partial \mathbf{H}_k}{\partial \mathbf{W}_{hh}}
The gradient of the recurrent weights (Eq. 9) — This is the whole difficulty of training an RNN in one line. The outer sum collects the loss from every step. The inner sum walks back over every earlier step kk that could have caused it. The factor to watch is ∂Ht/∂Hk\partial \mathbf{H}_t / \partial \mathbf{H}_k, the sensitivity of a late state to an early one. It is itself a product of t−kt-k one-step Jacobians, so its size depends on the distance between the two steps. Eq. 10 has the same shape for Wxh\mathbf{W}_{xh}.

The paper then simplifies this product to a matrix power, (Whh⊤)t−k\left(\mathbf{W}_{hh}^{\top}\right)^{t-k} (Eq. 11–12). Keep this form in mind, because it quietly drops something: the derivative of the activation ϕh\phi_h at every step. It is the linear picture of the recurrence, and the interactive in the next section starts from exactly this form before adding the activation back.

Computing all these paths for a long sequence is expensive, and powers of Whh\mathbf{W}_{hh} are numerically unstable. The practical answer the paper describes is : put an upper bound on how many steps the gradient may flow back. Think of it as a moving window over the past. Anything before the cut-off step is simply not taken into account, which is the same as limiting the number of layers in the unrolled network.

Long chains of multiplication either shrink to nothing or blow up

The paper names the central problem of RNNs plainly. The factor ∂Ht/∂Hk\partial \mathbf{H}_t / \partial \mathbf{H}_k means multiplying matrices over a potentially very long sequence. If the values involved are smaller than 1, the gradient shrinks at every step and eventually disappears: the . States from far in the past then stop contributing to learning. If the values are larger than 1, the product grows instead, the , and a single update can throw the weights far off.

Vanishing is the quieter and more damaging failure. Training does not crash; the network simply never learns a , because the signal that should teach it never arrives. This difficulty had been analysed years before the survey, most famously in Bengio, Simard and Frasconi's 1994 paper on why gradient descent struggles with long-range dependencies.

One more detail matters in practice. With a activation, every step also multiplies by its derivative, which is at most 1 and close to 0 when the unit is saturated. The paper's Eq. 11 leaves that factor out. Put it back, and the picture changes.

Open in Lab
Click the four presets in order. In the paper's linear form, w = 0.9 and w = 1.1 end up four orders of magnitude apart after 50 steps. Then switch to tanh: w = 1.1 now vanishes too, and w = 3 vanishes even faster. Finally, turn on clipping and truncation and see which problem each one touches.
The demo wakes as you arrive…

In the linear case the arithmetic is stark: 0.950≈0.0050.9^{50} \approx 0.005 while 1.150≈1171.1^{50} \approx 117. A weight that looks harmless decides whether step 1 has any say at all. With tanh the surprise is that a weight above 1 does not guarantee survival. The larger the weight, the harder the unit saturates, the smaller tanh′ becomes, and the faster the product dies. That is closer to how real RNNs behave: vanishing is the default, not the exception. (In a single unit, tanh cannot keep exploding; in real networks with many units it still can, which is why remedies for explosion exist.)

Two remedies are shown in the interactive. The first is , which the survey does not discuss: if the gradient's norm exceeds a threshold, rescale it down. It keeps an exploding update from wrecking the weights, but it scales every step by the same factor, so it cannot bring back a vanished signal. The second is the Truncated BPTT window the paper describes. It keeps training stable, but only by declaring the distant past irrelevant.

Gates: learning what to keep and what to forget

The Long Short-Term Memory cell (LSTM) changes the product itself. Next to the hidden state it keeps a second vector, the Ct\mathbf{C}_t, and it controls what flows in and out of it with a . A gate is a vector of numbers between 0 and 1, produced by a from the current input and the previous hidden state, and multiplied element-wise into another vector. Near 0 it blocks; near 1 it lets through.

There are three. The Ft\mathbf{F}_t decides how much of the old cell to keep (Eq. 15). The It\mathbf{I}_t decides how much of a new candidate C~t\tilde{\mathbf{C}}_t, built with tanh, to write in (Eq. 14, 16). The Ot\mathbf{O}_t decides how much of the cell to expose as the new hidden state (Eq. 13, 18). According to the survey, because LSTMs keep the error more constant, they let RNNs learn over far more time steps, "way over 1000".

Ct=Ft⊙Ct−1+It⊙C~tHt=Ot⊙tanh⁡(Ct)\mathbf{C}_t = \mathbf{F}_t \odot \mathbf{C}_{t-1} + \mathbf{I}_t \odot \tilde{\mathbf{C}}_t \qquad \mathbf{H}_t = \mathbf{O}_t \odot \tanh\left(\mathbf{C}_t\right)
The cell-state update and the new hidden state (Eq. 17–18) — The memory is updated by addition, not by being pushed through a squashing function. The forget gate scales the old cell element by element, the input gate scales the new candidate, and the two are added. The hidden state is then a gated, squashed view of that cell. Because the old cell reaches the new one through a multiplication by Ft\mathbf{F}_t alone, the backward path along the cell is multiplied by the forget gate at each step, not by a weight matrix and a tanh′.
One LSTM step, in the paper's notation (Eq. 13–18)python

Simplified to show the idea — not the real implementation.

import numpy as np

def sigmoid(z):
    return 1.0 / (1.0 + np.exp(-z))

def lstm_step(x_t, h_prev, c_prev, W, b):
    # Row vectors times matrices, as in the paper: X_t W_x? + H_(t-1) W_h?
    o = sigmoid(x_t @ W["xo"] + h_prev @ W["ho"] + b["o"])        # output gate (13)
    i = sigmoid(x_t @ W["xi"] + h_prev @ W["hi"] + b["i"])        # input gate  (14)
    f = sigmoid(x_t @ W["xf"] + h_prev @ W["hf"] + b["f"])        # forget gate (15)
    c_tilde = np.tanh(x_t @ W["xc"] + h_prev @ W["hc"] + b["c"])  # candidate   (16)

    # (17) keep part of the old memory, write part of the new candidate.
    # Addition, not a squash: this is the path the gradient travels.
    c = f * c_prev + i * c_tilde

    # (18) expose a gated view of the memory as the new hidden state
    h = o * np.tanh(c)
    return h, c
Open in Lab
A sign is stored at step 1 and noise arrives at every later step. Start with f = 0.9 and watch the LSTM lose the bit as badly as the plain RNN. Move to f = 0.99 and it survives a hundred steps. Then shut the input gate at f = 1: the memory is kept perfectly, and its gradient is exactly 1.
The demo wakes as you arrive…

The race shows why the forget gate matters so much. Along the cell, the gradient from step TT back to step 1 is simply the product of the forget gates in between. A value of 0.9 looks generous, but 0.999≈3×10−50.9^{99} \approx 3\times10^{-5}, so the bit is erased; 0.99 leaves about a third of it after a hundred steps. The network can learn to hold a gate near 1 for exactly as long as a piece of information is needed.

The extreme case has a name, although the survey does not use it. In the original 1997 LSTM there was no forget gate at all: the cell fed into itself with a fixed weight of exactly 1, a design Hochreiter and Schmidhuber called the . The error signal could circulate unchanged for as long as the gates stayed shut. The forget gate, added by Gers and colleagues in 2000, is what lets the cell clear itself when a memory is no longer needed.

The survey mentions the GRU only once, as an alternative to LSTM inside seq2seq models. For completeness: the of Cho et al. (2014) merges the cell and the hidden state and uses two gates. An zz blends the old state with a new candidate, playing the forget and input roles with one knob, and a decides how much of the old state the candidate may look at. In the race, 1−z1-z plays the part of the forget gate.

Both cells reach the same goal by different routes. What they share is the idea that separates them from the vanilla RNN: the path from one memory to the next is controlled by a learned number close to 1, instead of being forced through a weight matrix and a squashing function at every step.

Deeper, and reading in both directions

Two further extensions change the shape of the network rather than the cell. A deep RNN stacks recurrent layers. The first layer reads the input, Ht(1)=ϕ1(Xt,Ht−1(1))\mathbf{H}_t^{(1)} = \phi_1(\mathbf{X}_t, \mathbf{H}_{t-1}^{(1)}); each higher layer reads the layer below at the same step together with its own previous state, Ht(ℓ)=ϕℓ(Ht(ℓ−1),Ht−1(ℓ))\mathbf{H}_t^{(\ell)} = \phi_\ell(\mathbf{H}_t^{(\ell-1)}, \mathbf{H}_{t-1}^{(\ell)}); and the output comes from the top layer (Eq. 19–21). Depth now runs in two directions: up through the layers and along time.

A adds a second recurrent layer that reads the sequence backwards, from the last element to the first. At every step there are then two states: a forward state H→t\overrightarrow{\mathbf{H}}_t that has seen the past, and a backward state H←t\overleftarrow{\mathbf{H}}_t that has seen the future (Eq. 22–23). The output uses both, concatenated (Eq. 24). This is useful whenever the answer at one position depends on what comes after it, as in filling a gap in a sequence, the example the paper gives.

Open in Lab
Pick a sentence and a mode, then press play. In forward-only mode the guess for the gap appears early, but it has to be made before the word that decides it. Bidirectional mode gets it right, but only once the backward pass has arrived. In sentence 3 the gap is last, and the backward pass adds nothing.
The demo wakes as you arrive…

From one sequence to another, and why one vector is not enough

Many tasks map one sequence to another of a different length: translation, speech recognition, captioning a video. The paper's answer is the architecture, known as sequence to sequence (). An encoder RNN reads the input one element at a time. Its last hidden state, which the paper calls the encoder vector or context, becomes the initial state of a decoder RNN, which then produces the output one element at a time. The paper notes that these RNNs can be LSTMs or GRUs, and lists Google Translate, voice-enabled devices and video labelling among the applications.

The weak point is that single vector. Whatever the length of the input, everything the decoder will ever know about it has to fit into one . The paper names this directly as a bottleneck for long sequences. A short sentence fits; a long one gets compressed until details at the start are lost, which is the analogy's index card all over again.

Attention removes the bottleneck by letting the decoder look back at every encoder state, not just the last one. The encoder, typically bidirectional, produces one state per input position, Ht′\mathbf{H}_{t'}, the concatenation of the forward and backward states (Eq. 25). At each output step tt, the decoder computes a fresh Ct\mathbf{C}_t as a weighted average of all of them, and uses it together with its previous state and previous output to form its new state (Eq. 26).

The weights αt,t′\alpha_{t,t'} say how much output step tt should attend to input position t′t'. They come from a score between the decoder's previous state and each encoder state, turned into a probability distribution by a . The paper's running example is the alignment between an English sentence and its French translation.

Ct=∑t′=1Tαt,t′ Ht′αt,t′=exp⁡(score⁡(St−1,Ht′))∑t′=1Texp⁡(score⁡(St−1,Ht′))\mathbf{C}_t = \sum_{t'=1}^{T}\alpha_{t,t'}\,\mathbf{H}_{t'} \qquad \alpha_{t,t'} = \frac{\exp\left(\operatorname{score}(\mathbf{S}_{t-1},\mathbf{H}_{t'})\right)}{\sum_{t'=1}^{T}\exp\left(\operatorname{score}(\mathbf{S}_{t-1},\mathbf{H}_{t'})\right)}
A context vector per output step (Eq. 27–28) — The pair of equations replaces one fixed summary with a summary built on demand. For every output step, the score function rates each encoder state against the decoder's current need, St−1\mathbf{S}_{t-1}. The softmax turns those ratings into weights that are positive and sum to 1. The context vector is the encoder states averaged with those weights, so it can be dominated by one word, or spread over several, depending on what this particular output needs.
Open in Lab
Start in fixed-vector mode: every French word reads the same vector C. Drag the sentence length and watch how many input words a toy memory of that size can still recover. Then switch to attention and click the rows for "zone", "économique" and "européenne": the alignment runs against the diagonal, because French reverses the English word order there.
The demo wakes as you arrive…

The alignment matrix is one of the most readable things a sequence model produces. Each row shows where the model looked while writing one output word. Most rows sit near the diagonal, but where the two languages order words differently the attention bends to follow the meaning, not the position.

The survey collects six ways to compute the score. Content-based attention uses the cosine similarity of the two vectors. , from Bahdanau et al., passes both through a small network, va⊤tanh⁡(Wa[St;Ht′])\mathbf{v}_a^{\top}\tanh(\mathbf{W}_a[\mathbf{S}_t;\mathbf{H}_{t'}]). Location-based attention scores from the decoder state alone. The general form inserts a learned matrix between the two, St⊤WaHt′\mathbf{S}_t^{\top}\mathbf{W}_a\mathbf{H}_{t'}, the dot product drops that matrix, and the scaled dot product divides the dot product by a constant. The last one is what the Transformer uses, and the reason for the division is worth its own interactive below.

Answering by pointing at the input

A seq2seq decoder picks each output from a fixed dictionary. For some problems the right answer is not a word at all but a position in the input: which points form the outline of a shape, in what order to visit a set of cities. If the dictionary is fixed, the number of possible positions is fixed too, and a model trained on ten points has no way to name the eleventh.

A (Ptr-Net) reuses the attention weights as the output itself. Instead of mixing the encoder states into a context vector, it takes the softmax over the scores and reads it as a probability of pointing at each input position. The paper writes it with a simplified additive score (Eq. 29). Because the distribution is over the inputs, the size of the "dictionary" grows and shrinks with the input. The survey reports that Pointer Networks were used to compute planar convex hulls, Delaunay triangulations and solutions to the symmetric planar Travelling Salesman Problem.

Yt=softmax⁡(score⁡(St,Ht′))=softmax⁡(va⊤tanh⁡Wa[St;Ht′])\mathbf{Y}_{t} = \operatorname{softmax}\left(\operatorname{score}(\mathbf{S}_{t},\mathbf{H}_{t'})\right) = \operatorname{softmax}\left(\mathbf{v}_{a}^{\top}\tanh\mathbf{W}_{a}[\mathbf{S}_{t};\mathbf{H}_{t'}]\right)
The output is a distribution over input positions (Eq. 29) — The equation is attention with the last step removed. The additive score compares the decoder state at step tt with each encoder state Ht′\mathbf{H}_{t'}, and the softmax runs over the input positions t′t'. The result is not averaged into anything. It is the answer: the position with the highest probability is the element the model points to at this step.
Open in Lab
Click to add points, or try the random sets. The hull is read out as a list of input positions. With 16 points, the fixed-vocabulary decoder meets a hull point numbered above 10 and has no symbol for it; the pointer decoder simply points. The hull is computed by a standard algorithm and shown as pointers, not by a trained network.
The demo wakes as you arrive…

The Transformer drops recurrence entirely

Attention solved the bottleneck, but the encoder and decoder were still RNNs, and an RNN must process step t−1t-1 before step tt. The Transformer removes the recurrence and keeps only attention. Each position looks directly at every other position of the same sequence through , so a whole sequence can be processed in parallel, and the path between any two positions is a single step instead of a long chain.

The survey describes the original architecture: a stack of six encoders and six decoders. Each encoder has a self-attention sublayer and a feed-forward sublayer; each decoder adds an encoder–decoder attention sublayer between them. Multi-headed attention runs several attentions in parallel so that each can specialise in a different subspace. Skip connections and layer normalisation keep the deep stack trainable, a final softmax over a vocabulary-sized vector of logits produces the output word, and because nothing is recurrent any more, positional encodings built from sine and cosine waves of several frequencies tell the model where each word sits.

The Transformer's attention is the scaled dot product. The paper states the motivation: when the input to the softmax is large, the softmax can have extremely small gradients, which is a problem for learning. Dot products of long vectors are large. If the entries of a query and a key are random with unit variance, their dot product has a spread that grows like the square root of the dimension dkd_k. Dividing by dk\sqrt{d_k} puts the scores back on a fixed scale.

One wording in the survey is worth correcting. It describes the divisor as the number of characters of the current word, and its table writes it as nsource\sqrt{n_{source}}. In the Transformer paper the divisor is dk\sqrt{d_k}, the dimension of the keys, and that is what the interactive uses.

Open in Lab
Leave scaling off and raise the dimension. By 512 one key takes almost all the weight and the softmax gradient is nearly gone. Switch to the scaled version: the weights stay soft at every dimension, and the average curve below stays flat.
The demo wakes as you arrive…

What the survey leaves out

The survey is a map, and it is best read as one. It gives one consistent notation for a line of ideas that were published in many styles, it derives the gradient that causes the trouble, and its appendices draw an LSTM being assembled gate by gate, a seq2seq model with attention step by step, and the waves behind positional encoding. It ends by recommending the original papers for depth, and by pointing to Vinyals et al.'s StarCraft II agent, AlphaStar, which uses LSTMs, Transformers and Pointer Networks together, as a place where all these pieces meet in one system.

What it does not offer is evidence. There are no experiments of its own, and the architectures are never compared on a common task, so it cannot tell you when a GRU beats an LSTM or how much attention helps on a given problem.

Each fix answers the last one's weakness

  1. 1986

    Backpropagation, and training through time

    Rumelhart, Hinton and Williams popularise backpropagation and show how a recurrent net can be trained by unfolding it in time. Werbos gives BPTT its full treatment in 1990.

  2. 1990

    The simple recurrent network

    Elman's "Finding Structure in Time" feeds the hidden state back as context and shows that such networks discover structure in sequences.

  3. 1994

    Long-range dependencies are hard

    Bengio, Simard and Frasconi analyse why gradient descent fails on long-term dependencies, following Hochreiter's 1991 thesis.

  4. 1997

    LSTM and the bidirectional RNN

    Hochreiter and Schmidhuber introduce the LSTM and its Constant Error Carousel. Schuster and Paliwal introduce bidirectional RNNs.

  5. 2000

    The forget gate

    Gers, Schmidhuber and Cummins let the LSTM cell learn to reset itself.

  6. 2014

    Seq2seq, the GRU and attention

    Sutskever, Vinyals and Le map sequences to sequences with LSTMs. Cho et al. introduce the GRU. Bahdanau, Cho and Bengio add attention to translation.

  7. 2015

    Pointer Networks and more score functions

    Vinyals, Fortunato and Jaitly turn attention into the output. Luong et al. compare general, dot-product and location-based scores.

  8. 2017

    Attention is all you need

    Vaswani et al.'s Transformer drops recurrence and uses scaled dot-product self-attention.

  9. 2019

    This survey, and AlphaStar

    Schmidt collects the whole line in one notation. The same year, AlphaStar combines LSTMs, Transformers and Pointer Networks.

Read in order, the architectures form a chain in which each link answers the weakness of the one before. The vanilla RNN, trained with BPTT, could in principle remember but in practice lost the past to a repeated product. The LSTM and the GRU changed that product with gates. Seq2seq used those cells to map one sequence to another, and in doing so created a new bottleneck: the fixed-length vector. Attention removed the bottleneck, Pointer Networks turned attention into the answer, and the Transformer kept attention and discarded the recurrence that had started the story.

The common thread is the one this paper is organised around: how far a signal can travel before it fades. For the wider context of why depth and gradients became the central questions of the field, see the 2015 Nature review of deep learning.

CitationSchmidt. Recurrent Neural Networks (RNNs): A Gentle Introduction and Overview. arXiv:1912.05911, 2019.

Terms in this paper