总说
这篇主要是如何一步步说明RNN和LSTM的形式的构造,方便对模型有一个更直观的理解。写的比较随意。
RNN
我们知道,卷积是一个输入,得到一个输出。但有时候我们想输出一串,然后得到一串输出呢?并且是这一串都是相互有关联的,比如句子翻译。我们就需要一种能针对历史信息进行融合的单元,比如RNN。其实想想,只要以某种形式,将历史信息与当前输入进行有效融合的方式,应该都可以处理类似的问题。
和CNN的区别是,RNN有一个隐层状态 h t h_t ht,这个状态必须将历史的输入 x 1 , x 2 , . . . , x t − 1 x_1,x_2,...,x_{t-1} x1,x2,...,xt−1和当前的输入 x t x_t xt进行融合。 由于我们RNN是一个迭代的过程,对于第 t t t次,输入只有 x t x_t xt,那历史的输入怎么办呢?这就要用到“历史信息”,也就是 t − 1 t-1 t−1时刻的隐层状态 h t − 1 h_{t-1} ht−1。这个历史信息只要和历史输入挂钩就行。
比如第一次,我们先设置一个 h 0 h_0 h0,那么 h 1 h_1 h1应该是 x 1 x_1 x1和 h 0 h_0 h0的融合。嗯,没错。这样一来, h 2 h_2 h2应该是 x 2 x_2 x2和 h 1 h_1 h1的融合。此时 h 2 h_2 h2的得到不仅融合了历史输入 x 1 x_1 x1还结合了当前输入 x 2 x_2 x2。
我们通过增加了一个隐层状态,从而使得RNN能够将当前输入与历史输入进行有效的融合。隐层状态是历史信息的载体。
对于每次新的输入 x t x_t xt必须要和已有的隐层状态 h t − 1 h_{t-1} ht−1(就是下左图的中间一行的第一个结点的状态)进行融合的。融合方式很简单,我们只需要对 h t − 1 h_{t-1} ht−1和 x t x_t xt分别进行一个变换,好让其输入的维度等于 h t h_t ht的维度就行。所以就有 W 1 W_1 W1和 W 2 W_2 W2,分别表示对当前的输入 x t x_t xt以及历史输入的一个“取舍程度”。
RNN还要有输出,既然是迭代的,显然对于第 t t t次迭代,就会有 y ^ t \hat{y}_t y^t输出。我们不能直接把 h t h_t ht输出吧,为了增加复杂性,乘以一个权重 W 3 W_3 W3吧,用于表示对当前隐层状态 h t h_t ht的一个“取舍”。
所以自然就有下面:
h t = t a n h ( W 1 h t − 1 + W 2 x t ) h_t=tanh(W^1h_{t-1}+W^2x_t) ht=tanh(W1ht−1+W2xt)
y ˉ = W 3 h t \bar{y}=W^3h_t yˉ=W3ht