RNN,也即是递归神经网络,是许多NLP任务的流行处理模型。本部分中将简介RNN。
本部分主要实现此模型– recurrent neural network based language model,模型有两个作用:
- 可以基于出现的概率对句子进行打分,可以对于语法和语义正确性进行评估,从而应用于机器翻译等领域。
- 可以依据概率生成新的语料。
##什么是RNN
RNN背后的核心理念是利用序列的信息。传统的神经网络常常假设输入(输出)是独立于彼此的,这对于某些应用来说是不可行的,例如NLP任务,如果你需要预测下一个单词是什么,你不可能不用到之前的单词的信息。RNN之中的recurrent指的就是循环往复的意思,网络对于序列数据的每个元素进行同样的操作,网络的输出取决于之前的计算。另一种理解RNN的方法则是把它们看成是有记忆的网络,记忆收集从开始到现在被考虑的信息。理论上RNN可以利用任意时间长度的信息,但是实际上这比较困难。以下是RNN的典型结构:
以上的结构将RNN展开成完整的网络。例如,我们需要处理一个5层的序列,那么就需要展开成5层:每层对应一个词。
- $$x_t$$是$$t$$时刻的输入
- $$s_t$$是$$t$$时刻的隐藏状态,代表网络的“记忆”,计算公式为$$s_t = f(Ux_t + Ws_{t-1})$$,其中$$f$$通常是tanh函数或者RELU函数。
- $$o_t$$是$$t$$时刻的输出,如果我们想预测下一个词,那么计算公式为$$o_t = softmax(Vs_t)$$,指的是在整个词表内词的概率值。
对于以上有几点需要提示:
- 我们可以把隐藏状态$$s_t$$看成是网络的“记忆”,其捕捉到在之前所有时间的信息。输出$$o_t$$只取决于在$$t$$时刻的记忆。而在实际上,由于长期依赖问题,$$s_t$$很难捕捉到很长时间以前的信息。
- RNN每个step中的参数($$U,V,W$$)是相同的,这使得学习的代价减小许多。
- 取决于实际任务,我们可能并不需要每个step都有输入和输出。
##RNN的实际应用
以下是RNN在NLP领域的一些实际应用。
###语言模型与生成语句
在给定之前词语的情况下我们希望产生出下一个词语是什么。语言模型的作用就是让我们可以衡量一个句子的可能性,这对于机器翻译是很重要的(可能性越高的更可能正确)。而语言模型的另一个作用则是预测下一个词语是什么,我们可以通过在输出的概率词汇中采样得到,。对于语言模型,输入是一序列的词语(每一个词语都是one-hot表示),输出则是一序列的预测的词语。在训练时我们设置$$o_t = x_{t + 1}$$,因为这一时刻的输出就是下一时刻的输入。
关于语言模型与生成语句的论文:
- Recurrent neural network based language model
- Extensions of Recurrent neural network based language model
- Generating Text with Recurrent Neural Networks
###机器翻译
机器翻译类似于语言模型,其输入为需要翻译的句子,输出则是翻译的目标语言的句子。与语言模型不同的是,我们在输入整个句子之后才输出。
关于机器翻译的论文:
- A Recursive Recurrent Neural Network for Statistical Machine Translation
- Sequence to Sequence Learning with Neural Networks
- Joint Language and Translation Modeling with Recurrent Neural Networks
###语言识别
给予一段说话人语言的声音序列,我们预测出一序列的带有概率的语言成分的序列。
相关论文:
###生成图片描述
与CNN结合,RNN可以为无标签的图片生成描述,模型甚至可以排列好这些描述成更加类似人类语言的形式。
##训练RNN
训练RNN与典型的神经网络类似,值得注意的是Backpropagation Through Time (BPTT),并且通过BPTT训练的vanilla RNN由于梯度弥散或者梯度爆炸,不能有效的解决长期依赖的问题。
##其他的一些RNN
针对vanilla RNN的一些缺陷,近年来许多RNN的变体涌现出来。
双向RNN,主要输入不仅与过去的输入,并且与将来的输入有关的理念。例如我们需要预测一个句子中间缺失的词语。双向RNN的结构很简单,只是把两个RNN在顶部
结合,其输出取决于了两个RNN的隐藏状态。
深度(双向)RNN,与双向RNN类似,只是每个step需要训练多层的网络,这使得模型更为强大(也需要更多的数据来训练)。
LSTM网络,对RNN的隐藏层做了改进以解决长期依赖问题,是近来流行的RNN类型。LSTM可以通过gate决定网络需要记住和遗忘多长时间之前的记忆,以此联合之前的状态、记忆和输入。对于LSTM的详细知识可以见此:理解LSTM网络。
##结论
到此我们对于RNN有了一个基本的认识,之后我们将对其进行代码的实现。