vanilla RNNs和LSTM和GRU公式推导相关

1、 vanilla RNNs 

文章转自https://blog.csdn.net/dchen1993/article/details/53885490

相比于LSTM、GRU,vanilla RNNs 是最简单的循环神经网络。

RNN结构

RNN的一个特点是所有隐层共享参数(U, W, V),整个网络只用这一套参数,能大大减少计算量。

RNN前向传导

s_{t}=f\left ( Ux_{t}+Ws_{t-1} \right ),其中,f\left ( \cdot \right )可以是sigmoid函数、tanh函数、relu函数;

o_{t}=softmax(Vs_{t})

s_{t}为 t 时刻隐层的状态值,为向量。

o_{t}为 t 时刻的输出值。上图中,每一个time step都会有一个输出,但是这个不是必要的,可以根据任务而定。例如:(1)如果我们想要预测句子中下一个单词,则o_{t}是一个概率向量,该向量的维度是词表大小。(2)当只关心句子的语意信息时,只需要最后一个输出就行了。

RNN后向传播

构造训练数据

构造过程:

1、生成词典vocab。(分词、去掉低频词)

2、将语料中的句子转为word_id序列,并在头尾加上开始和结束符id。

3、生成训练数据:对于每一个句子,输入为前len(sentence)-1的序列,输出为后len(sentence)-1的序列(也就是输入一个词就预测下一个词)。

如:“我 在 沙滩 上 玩耍”输入的向量为[0, 5, 85, 485, 416, 55],输出的向量为[5, 85, 485, 416, 55, 1]。

假如我们的词汇有8000个,采用one-hot向量,则每个输入x_{t}为8000维,对应的位置为1,其他为0。

隐层设置100个神经元,则列出网络所有参数和输入输出的shape,方便推导:

x_{t}\in \mathbb{R}^{8000}

o_{t}\in \mathbb{R}^{8000}

s_{t}\in \mathbb{R}^{100}

U\in \mathbb{R}^{100\times 8000}

V\in \mathbb{R}^{8000\times 100}

W\in \mathbb{R}^{100\times 100}

总参数量为2HC+H^{2},即1610000。

损失函数采用交叉熵:E_{t}\left ( y_{t}, \hat{y}_{t} \right )=- y_{t}log\hat{y}_{t}E\left ( y, \hat{y} \right )=\Sigma _{t}E\left ( y_{t}, \hat{y}_{t} \right )=-\Sigma _{t} y_{t}log\hat{y}_{t},其中y_{t}为 t 时刻正确的词语,\hat{y}_{t}为 t 时刻预测的词语。

求解误差E关于所有参数(U, V, W)的梯度,即\frac{\partial E}{\partial U}\frac{\partial E}{\partial V}\frac{\partial E}{\partial W}

如下图所示,每个时刻 t 预测的词都有相应的误差,我们需要求这些误差关于参数的所有梯度,最后进行参数的下降调整操作(由于目标是降低Loss function,所以是梯度下降,如果目标是最大似然,则为梯度上升)。

这里计算E_{3}关于参数的梯度为例(其他E_{t}都需要计算):

\frac{\partial E_{3}}{\partial V}=\frac{\partial E_{3}}{\partial \hat{y_{3}}}\frac{\partial \hat{y_{3}}}{\partial V} =\frac{\partial E_{3}}{\partial \hat{y_{3}}}\frac{\partial \hat{y_{3}}}{\partial z_{3}}\frac{\partial z_{3}}{\partial V}=\left ( \hat{y_{3}}-y_{3}\right )\times s_{3}8000\times 100的向量,其中z_{3}=Vs_{3},用到了softmax的求导公式。可见关于V的梯度用不到上一层的状态值,所以不需要累计。

BPTT(Backpropagation Through Time)

下面来求解关于W的梯度:

\frac{\partial E_{3}}{\partial W}=\frac{\partial E_{3}}{\partial \hat{y_{3}}}\frac{\partial \hat{y_{3}}}{\partial s_{3}}\frac{\partial s_{3}}{\partial W}

由于s_{3}=tanh\left ( Ux_{3}+Ws_{2} \right )依赖s_{2},而s_{2}依赖W和s_{1},以此类推。

下图为链式关系:

所以,

\frac{\partial E_{3}}{\partial W}=\sum_{k=0}^{3}\frac{\partial E_{3}}{\partial \hat{y}_{3}}\frac{\partial \hat{y}_{3}}{\partial s_{3}}\frac{\partial s_{3}}{\partial s_{k}}\frac{\partial s_{k}}{\partial W}

可见由于W在所有隐层中共享,许多变量都依赖W,导致求导链变长,这就是BPTT的特点,将每层的影响都累计起来。

下图为各链接之间的导数,在所有层中不会改变,也体现了传播的路径。

跟一般的反向传播一样,这里也定义一个Delta向量:

\delta_{2}^{(3)}=\frac{\partial E_{3}}{\partial s_{3}}\frac{\partial s_{3}}{\partial s_{2}}\frac{\partial s_{2}}{\partial z_{2}}

其中z_{2}=Ux_{2}+Ws_{1},在本例子中为一个100\times 1的向量。

所以\frac{\partial E_{3}}{\partial W}可以写成:

\frac{\partial E_{3}}{\partial W}=\sum_{k=0}^{3}\delta _{k}^{(3)}\frac{\partial z_{k}}{\partial W}100\times 100的矩阵。

同理\frac{\partial E_{3}}{\partial U}可以写成:

\frac{\partial E_{3}}{\partial U}=\sum_{k=0}^{3}\delta _{k}^{(3)}\frac{\partial z_{k}}{\partial U}100\times 8000的矩阵。

至此,关于(U, V, W)的梯度都求解完毕。

2、LSTM

文章转自https://www.jianshu.com/p/9dc9f41f0b29

LSTM网络结构

1、忘记门

在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为忘记门层完成。该门会读取 h_{t-1} 和 x_t,输出一个在 0 到 1 之间的数值给每个在细胞状态 C_{t-1} 中的数字。1 表示“完全保留”,0 表示“完全舍弃”。

2、更新门

下一步是确定什么样的新信息被存放在细胞状态中。这里包含两个部分。第一,sigmoid层称 “输入门层” 决定什么值我们将要更新。然后,一个 tanh 层创建一个新的候选值向量,\tilde{C}_t,会被加入到状态中。下一步,我们会讲这两个信息来产生对状态的更新。

现在是更新旧细胞状态的时间了,C_{t-1} 更新为 C_t。前面的步骤已经决定了将会做什么,我们现在就是实际去完成。

我们把旧状态与 f_t 相乘,丢弃掉我们确定需要丢弃的信息。接着加上 i_t * \tilde{C}_t。这就是新的候选值,根据我们决定更新每个状态的程度进行变化。

3、输出门

最终,我们需要确定输出什么值。这个输出将会基于我们的细胞状态,但是也是一个过滤后的版本。首先,我们运行一个 sigmoid 层来确定细胞状态的哪个部分将输出出去。接着,我们把细胞状态通过 tanh 进行处理(得到一个在 -11 之间的值)并将它和 sigmoid 门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。

LSTM的变体

1、Peephole connection

其中一个流形的 LSTM 变体,就是由 Gers & Schmidhuber (2000) 提出的,增加了 “peephole connection”。是说,我们让 门层 也会接受细胞状态的输入。

上面的图例中,我们增加了 peephole 到每个门上,但是许多论文会加入部分的 peephole 而非所有都加。

2、使用 coupled 忘记和输入门

另一个变体是通过使用 coupled 忘记和输入门。不同于之前是分开确定什么忘记和需要添加什么新的信息,这里是一同做出决定。我们仅仅会当我们将要输入在当前位置时忘记。我们仅仅输入新的值到那些我们已经忘记旧的信息的那些状态 。


3、GRU

另一个改动较大的变体是 Gated Recurrent Unit (GRU),这是由 Cho, et al. (2014) 提出。它将忘记门和输入门合成了一个单一的 更新门。同样还混合了细胞状态和隐藏状态,和其他一些改动。最终的模型比标准的 LSTM 模型要简单,也是非常流行的变体。

这里只是部分流行的 LSTM 变体。当然还有很多其他的,如Yao, et al. (2015) 提出的 Depth Gated RNN。还有用一些完全不同的观点来解决长期依赖的问题,如Koutnik, et al. (2014) 提出的 Clockwork RNN。

要问哪个变体是最好的?其中的差异性真的重要吗?Greff, et al. (2015) 给出了流行变体的比较,结论是他们基本上是一样的。Jozefowicz, et al. (2015) 则在超过 1 万种 RNN 架构上进行了测试,发现一些架构在某些任务上也取得了比 LSTM 更好的结果。


 

发布了97 篇原创文章 · 获赞 40 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/NOT_GUY/article/details/83827975