§10.3–10.6Bidirectional · Encoder–Decoder · Deep · Recursive Nets

Part II DL pp. 394–400 · ~7 min read

  • bidirectional rnn
  • encoder-decoder (sequence-to-sequence)
  • context vector
  • deep rnn
  • recursive neural network

§10.3 Bidirectional RNNs

Every RNN so far is causal: the state at step tt sees only the past x(1),,x(t)x^{(1)}, \dots, x^{(t)}. But many tasks need the whole input to predict y(t)y^{(t)}. In speech recognition, the right phoneme for the current sound can depend on the next few phonemes (co-articulation) — even the next few words. If two readings of a word are both acoustically plausible, you may have to look far ahead and behind to disambiguate.

Bidirectional RNNs (Schuster & Paliwal 1997) solve this by combining a sub-RNN that runs forward (state h(t)h^{(t)}) with one that runs backward (state g(t)g^{(t)}). The output o(t)o^{(t)} then draws on a summary of the past (via hh) and the future (via gg) — without any fixed-size look-ahead window:

Fig 10.11 — a bidirectional RNN. The h recurrence flows forward in time (→); the g recurrence flows backward (←). Each output o⁽ᵗ⁾ combines both, so it sees a summary of the past AND the future around t.
x⁽t−1⁾h⁽t−1⁾g⁽t−1⁾o⁽t−1⁾y⁽t−1⁾x⁽t⁾h⁽t⁾g⁽t⁾o⁽t⁾y⁽t⁾x⁽t+1⁾h⁽t+1⁾g⁽t+1⁾o⁽t+1⁾y⁽t+1⁾forward →← backward

The idea extends naturally to 2-D data such as images: use four RNNs, one each going up, down, left, and right. At each grid point, the output captures mostly local information but can also depend on long-range inputs. Versus a convolutional network this is more expensive, but it allows long-range lateral interactions across a feature map (the bottom-up input is itself a convolution).

§10.4 Encoder–decoder sequence-to-sequence architectures

We have now seen an RNN map a sequence → fixed vector (fig 10.5), a fixed vector → sequence (fig 10.9), and a sequence → equal-length sequence (figs 10.3/10.10/10.11). The missing case — the one behind machine translation and question answering — is a sequence → sequence of a different length.

The encoder–decoder (a.k.a. sequence-to-sequence) architecture (Cho 2014; Sutskever 2014) is disarmingly simple: an encoder RNN reads the input and emits a context CC (usually its final hidden state); a decoder RNN, conditioned on CC, generates the output. Slide the two lengths apart — nothing forces them equal:

Fig 10.12 (interactive) — encoder–decoder. The encoder reads nₓ inputs into a fixed context C; the decoder unrolls C into nᵧ outputs. Drag the sliders: nₓ and nᵧ can differ — the innovation over same-length RNNs.
EncoderDecoderx1x2x3x4Ccontexty1y2y3

The encoder compresses 4 inputs into the single fixed context C; the decoder unrolls it into 3 outputs. Because C sits between them, the two lengths need not match (here nₓ=4 ≠ nᵧ=3) — the advance over same-length RNNs.

The two RNNs are trained jointly to maximize the average of logP(y(1),,y(ny)x(1),,x(nx))\log P(y^{(1)}, \dots, y^{(n_y)} \mid x^{(1)}, \dots, x^{(n_x)}) over all pairs. The encoder’s last state serves as CC; there is no constraint that encoder and decoder share a hidden-layer size.

The fixed-C bottleneck → attention

One clear limitation: if CC has too small a dimension to summarize a long input, performance suffers (Bahdanau 2015 saw exactly this in translation). The fix is to make CC a variable-length sequence rather than a single vector, and add an attention mechanism that learns to associate elements of CC with elements of the output. That is the seed of attention, developed in §12.4.5.

§10.5 Deep recurrent networks

Most RNN computation decomposes into three blocks: input→hidden, hidden→hidden, and hidden→output. In the workhorse RNN each block is a single weight matrix — a shallow transformation (one affine map + one nonlinearity). Would depth in each help? Experiments (Graves 2013; Pascanu 2014a) say yes:

Fig 10.13 — three ways to make an RNN deep. (a) break the hidden state into stacked, hierarchical groups; (b) put a whole MLP inside each of the three blocks; (c) add skip connections to counter the path-lengthening that (b) causes.
(a) hierarchical hiddenxyhz(b) MLP in each blockxyMLP(c) + skip connectionsxyMLPskip

Adding depth boosts capacity, but there is a cost: it lengthens the shortest path from a variable at step tt to one at step t+1t+1. A single hidden layer in the state-to-state transition, for instance, doubles that path length versus the ordinary RNN — and shorter paths are easier to optimize. The mitigation (fig 10.13c) is skip connections in the hidden-to-hidden path.

§10.6 Recursive neural networks

A recursive neural network generalizes the RNN differently: its computational graph is a deep tree, not a chain (Pollack 1990). A variable-size sequence is folded up the tree to a fixed-size representation, with one shared set of weight matrices at every node. Drag τ\tau to see why the tree shape matters:

Fig 10.14 (interactive) — a recursive net folds τ inputs up a balanced binary tree. The longest input→output path (composed nonlinearities) is O(log τ), versus O(τ) for the recurrent chain.
o (root)τ = 8 leaves (inputs x⁽¹⁾…x⁽τ⁾)
Recurrent chain — depth O(τ)8
Recursive tree — depth O(log τ)3

The longest path from an input leaf to the output — the number of composed nonlinearities a gradient must traverse — is 8 for the chain but only 3 = ⌈log₂ 8⌉ for the balanced tree. Fewer compositions means gradients vanish/explode less, which can help with long-term dependencies.

For a sequence of length τ\tau, the depth — the number of composed nonlinear operations — drops from τ\tau to O(logτ)O(\log \tau), which can ease long-term dependency learning. The open question is how to structure the tree. Options: a data-independent shape (a balanced binary tree); an externally supplied shape (e.g. the parse tree of a sentence, Socher 2011/2013); or — ideally — a tree the learner discovers for each input. Node computations need not be the usual affine-plus-nonlinearity either: Socher (2013) uses tensor/bilinear operations to model relationships between concept embeddings.

Next: why long-range learning is hard in the first place — the challenge of long-term dependencies, echo state networks, and leaky units.

Check yourself — bidirectional, encoder-decoder, deep, and recursive nets

1.Why were bidirectional RNNs invented, and how are they structured?

2.How does the bidirectional idea extend to 2-D data such as images?

3.What is the key innovation of the encoder-decoder (sequence-to-sequence) architecture over the RNNs earlier in the chapter?

4.What limitation of the basic encoder-decoder motivates the attention mechanism?

5.In a deep RNN, depth can be added to the input→hidden, hidden→hidden, and hidden→output blocks. What is the trade-off?

6.How does a recursive neural network differ from a recurrent one, and what advantage does that bring?

6 questions