循环神经网络(Recurrent Neural Network,RNN)是一个非常经典的面向序列的模型,可以对自然语言句子或是其他时序信号进行建模。进一步讲,它只有一个物理RNN单元,但是这个RNN单元可以按照时间步骤进行展开,在每个时间步骤接收当前时间步的输入和上一个时间步的输出,然后进行计算得出本时间步的输出。
下面我们举个例子来讨论一下,如图1所示,假设我们现在有这样一句话:”我爱人工智能”,经过分词之后变成”我,爱,人工,智能”这4个单词,RNN会根据这4个单词的时序关系进行处理,在第1个时刻处理单词”我”,第2个时刻处理单词”爱”,依次类推。
RNN - 图1
图1 RNN网络结构图
图1上可以看出,RNN在每个时刻𝑡均会接收两个输入,一个是当前时刻的单词𝑥𝑡,一个是来自上一个时刻的输出ℎ𝑡−1,经过计算后产生当前时刻的输出ℎ𝑡。例如在第2个时刻,它的输入是”爱”和ℎ1,它的输出是ℎ2;在第3个时刻,它的输入是”人工”和ℎ2, 输出是ℎ3,依次类推,直到处理完最后一个单词。
总结一下,RNN会从左到右逐词阅读这个句子,并不断调用一个相同的RNN Cell来处理时序信息,每阅读一个单词,RNN首先将本时刻𝑡t的单词𝑥𝑡和这个模型内部记忆的状态向量ℎ𝑡−1融合起来,形成一个带有最新记忆的状态向量ℎ𝑡。

Tip:当RNN读完最后一个单词后,那RNN就已经读完了整个句子,一般可认为最后一个单词输出的状态向量能够表示整个句子的语义信息,即它是整个句子的语义向量,这是一个常用的想法。

公式推导

ℎ𝑡=𝑡𝑎𝑛ℎ(𝑊𝑥𝑡+𝑉ℎ𝑡−1+𝑏)
即在时刻𝑡,RNN单元会对两个输入𝑥𝑡和ℎ𝑡−1进行线性变换,然后将结果使用𝑡𝑎𝑛ℎ激活函数进行处理,得到当前时刻𝑡的输出ℎ𝑡。

这里需要注意一下,tanh函数是一个值域(-1,1)的函数,如图2所示,可以长期维持内部记忆在一个固定的数值范围内,防止因多次迭代更新导致的数值爆炸,同时,tanh的导数是一个平滑的函数,让神经网络的训练变得更加简单。 RNN - 图2 图2 tanh函数图像

缺陷

当阅读很长的序列时,网络内部的信息会逐渐变得越来越复杂,以至于超过网络的记忆能力,使得最终的输出信息变得混乱无用。

几种常见模式

序列到类别模式

在RNN读完一个句子的最后一个单词后,该单词对应的输出便可以看做能够代表整个句子的语义向量,根据这个语义向量可以进一步计算一些任务,比如文本分类,假设通过这个语义向量能够将”我爱人工智能”这句话划分为”科技”类别,那这就是一个完整的序列到类别模式的应用。
序列到类别模式是将一串输入映射为一个向量,如图3所示。在这种模式下,模型的输入是一个序列=[𝑥1,𝑥2,𝑥3,..,𝑥𝑛]=[x1,x2,x3,..,xn],最终使用的模型输出是一个向量ℎ𝑛hn(图3中输出的绿色向量),可以根据这个输出向量ℎ𝑛hn进一步做一些任务。
RNN - 图3
图3 序列到类别模式图
除了将最后时刻的状态作为整个序列的语义向量之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态作为整个序列的语义向量,如图4所示。
RNN - 图4
图4 序列到类别模式图

同步的序列到序列模式

同步的序列到序列模式是将一串输入𝑥=[𝑥1,𝑥2,..,𝑥𝑛]映射为一串输出向量ℎ=[ℎ1,ℎ2,…,ℎ𝑛],并且每个输入和输出是一一对应的,如图5所示。同步的序列到序列模式主要用于序列标注(Sequence Labeling)任务上。
RNN - 图5
图5 同步的序列到序列模式
词性标注(Part-of-Speech Tagging)为例,该任务期望得到一个句子中每个单词的词性,因此它的输入就是一个句子中的单词,它的输出就是每个单词对应的词性。

异步的序列到序列模式

异步的序列到序列模式也成为编码器-解码器模型(encoder-decoder),它同样是将一串输入映射𝑥=[𝑥1,𝑥2,..,𝑥𝑛]为一串输出向量ℎ=[ℎ1,ℎ2,…,ℎ𝑚],但是输入序列和输出序列不要求有严格的一一对应关系,也不需要保持相同的长度,如图6所示。例如在机器翻译-英译汉任务中,输入为中文的单词序列,输出为英文的单词序列。
RNN - 图6
图6 异步的序列到序列模式
在这个模式下,一般先将输入序列传到一个RNN(encoder,图6橙色单元)中,然后再将encoder的输出向量作为另一个RNN(解码器,图6黄色单元)的输入,由解码器进行序列解码。在解码器的解码过程中,往往会将前一个时刻输出的单词作为当前时刻输入的单词,采用这种自回归的方式进行解码。