Md. Asif Uddin

    Proposition 1I.10.P0133 of 100 in the corpus

    A gate gives the gradient a road home that no weight matrix stands on.

    The LSTM carries a second state, the cell state, along a line with one multiplication and one addition. Holding the gates fixed, the derivative from one step of that line to the next is a diagonal of forget-gate values.

    An LSTM cell and its uninterrupted carry lineA horizontal line across the top carries the cell state from left to right, crossed only by one multiplication, by the forget gate, and one addition, of the candidate scaled by the input gate. A branch from the line passes through tanh and is multiplied by the output gate to give the hidden state. All three gates and the candidate read the preceding hidden state and the current input.the carry linec(t−1)c(t)×+forget gate fσ → (0, 1)×input gate iσ → (0, 1)candidate c̃tanh → (−1, 1)tanh×h(t)output gate oσ → (0, 1)h(t−1), x(t): every gate and the candidate read the same two vectorsHolding the gates fixed, the carry line's derivative is diag(f). No weight matrix stands on it.
    Fig. 1 — Type E · Architecture — An LSTM cell. The carry line crosses only a multiplication by the forget gate and an addition of what the input gate admits, so with the forget gate near one the gradient has a route home that no weight matrix attenuates. The output gate decides how much of the cell becomes visible.

    What the last chapter left broken

    In I.9 the temporal Jacobian of a tanh cell was At=diag⁡(1−ht2)W\mat A_t=\operatorname{diag}(1-\vec h_t^2)\mat W. A distant loss reaches an early state only through a product of such factors. Every factor contains the recurrent matrix, and every factor contains a tanh derivative no larger than one. When their norms stay below some r<1r<1, the signal shrinks at least as fast as rT−sr^{T-s}.

    A better initialisation of W\mat W cannot remove the tanh factor, and it cannot keep the trajectory in the unsaturated region. A repair has to change the path itself: give the state a route from one step to the next on which neither factor appears. The long short-term memory, or LSTM, is that route plus the machinery to decide what travels on it.

    Two states and four vectors

    The LSTM carries two vectors of width HH: the hidden state ht\vec h_t, as before, and a cell state ct\vec c_t. At each step it computes three gates and one candidate from the same two inputs:

    it=σ(Uixt+Wiht−1+bi),ft=σ(Ufxt+Wfht−1+bf),ot=σ(Uoxt+Woht−1+bo),c~t=tanh⁡(Ucxt+Wcht−1+bc).\begin{aligned} \vec i_t&=\sigma(\mat U_i\vec x_t+\mat W_i\vec h_{t-1}+\vec b_i),\\ \vec f_t&=\sigma(\mat U_f\vec x_t+\mat W_f\vec h_{t-1}+\vec b_f),\\ \vec o_t&=\sigma(\mat U_o\vec x_t+\mat W_o\vec h_{t-1}+\vec b_o),\\ \tilde{\vec c}_t&=\tanh(\mat U_c\vec x_t+\mat W_c\vec h_{t-1}+\vec b_c). \end{aligned}
    (I.10.1)

    Each gate reads the current input and the preceding hidden state through its own weights.

    Each U\mat U is HH by DD, each W\mat W is HH by HH, and each bias has HH entries. The logistic function σ\sigma of I.3 puts every gate coordinate strictly between zero and one; the candidate lies strictly between minus one and one. The state update is

    ct=ft⊙ct−1+it⊙c~t,ht=ot⊙tanh⁡(ct).\begin{aligned} \vec c_t&=\vec f_t\odot\vec c_{t-1}+\vec i_t\odot\tilde{\vec c}_t,\\ \vec h_t&=\vec o_t\odot\tanh(\vec c_t). \end{aligned}
    (I.10.2)

    The cell state changes by one elementwise multiply and one elementwise add.

    Read the four vectors by what they do. The forget gate ft\vec f_t decides how much of each coordinate of the old cell state survives. The candidate c~t\tilde{\vec c}_t proposes new content, and the input gate it\vec i_t decides how much of it is written. The output gate ot\vec o_t decides how much of the squashed cell state becomes visible as ht\vec h_t, which is what a readout and the next step’s gates see. Both c0\vec c_0 and h0\vec h_0 must be specified; for an independent sequence both are usually zero.

    PyTorch writes the candidate as gt\vec g_t and stacks the four blocks in the order input, forget, candidate, output, so its input weight matrix is 4H4H by DD. It also keeps two bias vectors, one added with the input product and one with the recurrent product. Equation (I.10.1) uses their sum. That difference matters when counting parameters and when setting a bias, as the next proposition shows.

    The carry line

    Now hold the gate values and the candidate fixed and differentiate the cell update with respect to the preceding cell state:

    ∂ct∂ct−1∣gates fixed=diag⁡(ft),∏k=s+1Tdiag⁡(fk)=diag⁡(fs+1⊙⋯⊙fT).\begin{aligned} \frac{\partial\vec c_t}{\partial\vec c_{t-1}}\bigg|_{\text{gates fixed}} &=\operatorname{diag}(\vec f_t),\\ \prod_{k=s+1}^{T}\operatorname{diag}(\vec f_k) &=\operatorname{diag}(\vec f_{s+1}\odot\cdots\odot\vec f_T). \end{aligned}
    (I.10.3)

    Holding the gates fixed, the carry line's derivative is a diagonal of forget values.

    Compare this with (I.9.5). Two things have gone. There is no weight matrix on the path, so its norm and direction play no part. There is no tanh derivative either, because the cell state is not squashed before it is passed on. What remains is one number per coordinate per step, between zero and one, and the coordinates do not mix: the signal returning along coordinate jj is scaled only by that coordinate’s own forget values.

    The figure draws this path. A forget value near one passes the signal almost unchanged. A forget value near zero stops it, and that is not a pathology: the network has decided that this coordinate’s past is no longer needed, and a gradient that does not reach a discarded memory is the correct gradient.

    The qualifier gates fixed matters. The gates themselves depend on ht−1\vec h_{t-1}, and ht−1\vec h_{t-1} depends on ct−1\vec c_{t-1}, so the full derivative has further terms. The carry line is a path that exists in every LSTM, not the whole derivative. The next proposition counts the rest.

    The 1997 LSTM had no forget gate. Its cell kept a self-connection with weight fixed at one, so the update was ct=ct−1+it⊙c~t\vec c_t=\vec c_{t-1}+\vec i_t\odot\tilde{\vec c}_t and the carry-line derivative was exactly one. Hochreiter and Schmidhuber called this the constant error carousel: an error signal travelling along it is neither attenuated nor amplified, however many steps it crosses. The input gate protected the stored value from irrelevant writes; the output gate protected the rest of the network from irrelevant reads. Their training procedure also truncated the gradient leaving the cell through its gate and input connections, so the long-range signal travelled along the carousel alone.

    The price was that nothing ever erased the cell. Gers, Schmidhuber and Cummins found that on long continual input streams, presented without resets between subsequences, the cell state could grow without bound and the network broke down. Their remedy was the forget gate, which turned the fixed factor of one into a learned factor ftf_t. Every LSTM in current use descends from that version. I.10.X03 measures the growth they were fixing.

    Write, keep, read

    A scalar example shows the three roles separately. Set every recurrent weight to zero and make the gates constants through their biases: bi=0b_i=0, bf=bo=ln⁡3b_f=b_o=\ln3, so i=1/2i=1/2 and f=o=3/4f=o=3/4. Let the candidate be tanh⁡(xtln⁡3)\tanh(x_t\ln3), so an input of one proposes 0.80.8 and an input of zero proposes nothing.

    Feed the inputs (1,0,0)(1,0,0) from zero states. The first step writes half of 0.80.8, giving c1=0.4c_1=0.4. The next two steps write nothing and keep three quarters each time: c2=0.3c_2=0.3 and c3=0.225c_3=0.225. The visible states are ht=0.75tanh⁡(ct)h_t=0.75\tanh(c_t), or 0.2849620.284962, 0.2184840.218484 and 0.1659590.165959. With f=0.99f=0.99 instead, the third cell state is 0.4⋅0.992=0.392040.4\cdot0.99^2=0.39204. The value was written once; the forget gate alone decides how long it lasts. I.10.B01 works the example.

    Gates are soft, and they read the input

    Three consequences of (I.10.1) are easy to lose.

    A sigmoid never reaches zero or one. A forget bias of ten gives f=0.9999546f=0.9999546, which still loses about ninety-nine per cent of the carry-line signal over a hundred thousand steps (I.10.X01). A gate is a multiplier the network can push close to an extreme, not a switch.

    The gates are recomputed at every step from the input and the visible state. The network can therefore keep a coordinate through one stretch of a sequence and clear it at a particular event. That decision is learned through the same backward pass as everything else.

    The output gate can hide the cell. If ot\vec o_t is small, ht\vec h_t says little about ct\vec c_t, yet the cell still carries its value forward. A readout of ht\vec h_t is therefore not a readout of everything the network remembers (I.10.X04). For the same reason a padded step must freeze both states. Freezing ht\vec h_t alone lets the cell move (I.10.X05).

    Reproduce three steps

    from math import exp, log, tanh
    
    def sig(a):
        return 1/(1 + exp(-a))
    
    def lstm_step(x, c, h, u, w, b):
        a = {k: u[k]*x + w[k]*h + b[k] for k in "ifoc"}
        i, f, o = sig(a["i"]), sig(a["f"]), sig(a["o"])
        c = f*c + i*tanh(a["c"])
        return c, o*tanh(c)
    
    u = {"i": 0.0, "f": 0.0, "o": 0.0, "c": log(3)}
    w = dict.fromkeys("ifoc", 0.0)
    b = {"i": 0.0, "f": log(3), "o": log(3), "c": 0.0}
    c = h = 0.0
    for x in (1.0, 0.0, 0.0):
        c, h = lstm_step(x, c, h, u, w, b)
        print(f"{c:.6f} {h:.6f}")

    It prints the three cell and hidden states above. The chapter’s reproduction script, attached to I.10.B01, runs the same cell and then checks a full two-unit LSTM backward pass against finite differences.

    Sources