RNN简介
RNN(递归神经网络)包括Recurrent Neural Network和Recursive Neural Network两种,分别为时间递归神经网络和结构递归神经网络。
Recurrent Neural Network
给定输入序列x[i:j],RNN的输入为与x[i:j]对应的x[1:n]和一个状态向量s,x按单词顺序输入RNN,输出为一组状态向量s[1:n]和输出y[1:n],其数学形式如下:
函数O用于将状态向量映射到输出向量。RNN的图形表示如下:
将递归函数展开得到如下表达:
RNN训练目标
1. Acceptor
参考维基百科中对Acceptor的描述。训练出的RNN为一般的分类器。
2. Encoder
RNN的输出被视为是对输入序列的编码,监督数据用于使RNN能够输出这样的编码,可以用于进行文本摘要等。
3. Transducer
对输入的每一个元素都进行对应的输出,可用于序列标注,语言建模(给定前i个输入,预测第i+1个词的分布)
4. Encoder-Decoder
两个独立的RNN分别用于encode和decode,encoder的输出作为decoder的辅助性输入。监督数据只在decoder上训练,但梯度却反向传播到encoder的RNN中。结合LSTM的RNN可用于机器翻译。另外也可用于序列转导(encoder的输出作为transducer的初始状态输入,结合序列数据用来预测每个词的标签)。
几个RNN的变种
1. Multi-layer(stacked) RNN
将多个RNN堆叠成多层RNN,每层RNN的输入为上一层RNN的输出,如下图所示,这种结构在某些任务(机器翻译)上有好的表现。
2. BI-RNN
由于单向RNN在计算第i个单词的输出时只考虑了前i个单词的信息,没有考虑之后的单词信息,加入反向的RNN可以使模型能够考虑两个方向上任意长的单词序列的信息。具体地说,每个RNN都有自己的状态表示,总的状态信息由二者组合而成。第i个位置的输出也由两个RNN在相应位置的输出组成,如下图所示:
3. 用RNN表示栈(stack)结构
在transition-based dependency parsing中,神经网络的输入由某一时刻栈顶前n个元素变化而来,由于RNN具有将任意长的向量表示为固定长度向量的能力,因此可以用RNN来对某一时刻整个栈的内容进行编码,但是栈的内容是动态变化的,因此不太适用于按序列顺序进行输入的RNN。所以采用持久化栈来代替普通的栈结构,持久化栈将栈表示为指向链表头节点的指针。push操作将指针指向新的头节点,pop操作将指针后退一步。因此被pop的数据得以保留,如下图所示:
构建这样的树状结构RNN时,节点的误差在反向传播时会影响到所有节点,上图的RNN结构如下图所示:
具体的RNN结构
1. 简单RNN
简单RNN描述为如下:
即,第i个位置的状态由第i个位置的输入和之前状态线性组合而成,输入则由当前位置的状态变换而来。
2. LSTM(Long-Short-Term-Memory)
简单RNN由于梯度消失的问题而难以进行有效的训练,LSTM可以解决这个问题。LSTM的思想为在状态信息中加入记忆单元(向量),对记忆单元的访问由门控单元控制,门控单元为模拟逻辑门的平滑函数。输入数据时,门控单元决定由多少新数据将被写入记忆单元,以及多少当前数据将被遗忘。具体来说,门控为值为0~1的向量。LSTM结构如下所示:
LSTM图形化表示c为记忆内容,h为输出,i为输入门,f为遗忘门,o为输出门,g为更新操作的候选操作。
f控制有多少已有数据被保留下来(c * f),输入门控制有多少新数据被保留下来(g * i),最终的输出h由当前记忆内容和门控的输出决定。
3. GRU(Gated Recurrent Unit)
GRU是LSTM的一个有力的竞争对手。GRU有与LSTM类似的门控单元,但是数量较少,也没有记忆单元,如下所示:
GRU图形化表示r门用于调控之前的状态,并计算h。新的状态由之前状态和h的插值确定,插值比例由z确定。
Recursive Neural Network
RNN适用于序列建模,而许多NLP问题需要处理树状结构,因此提出了RecNN的概念。与RNN将前序句子编码成状态向量类似,RecNN将每个树节点编码成状态向量。RecNN中的每棵子树都由一个向量表示,其值由其子节点的向量表示递归确定。
RecNN接受的输入为一个有n个单词的句子的语法分析树,每个单词都表示为一个向量,语法分析树表示为一系列的生成式规则。
The boy saw her duck的分析树 对应的生成式规则(无标签+有标签)RecNN的输出为句子的内部状态向量(inside state vectors),每一个状态向量都对应一个树节点。RecNN的递归函数如下所示:
s为状态向量,q为生成式规则。R函数通常是个简单的线性变换,或外加一个非线性的激活函数g:
这种R函数不包含树的标签,对于有标签的情况,一种方法是嵌入标签v(A),将每一个非终结符对应到一个向量:
另一种方法是根据非终结符来扩充权重矩阵:
RecNN也可作为编码器,其内部状态向量可作为对子树的编码。
网友评论