循环神经网络 Part 1-简介
Tim Chen(motion$) Lv5
  • 本文翻自WILDML

  • 循环神经网络(RNNs)是一个目前在许多的自然语言处理(NLP)任务当中表现了出色的性能的模型。但是,除了它最近的火热之外,我能找到的关于RNNs模型的工作原理和实现的资源非常的有限。所以我才着手写了这个tutorial。我分了几个部分来写RNN的tutorial:

    1. RNNs简介(本tutorial)
    2. 用Python和Theano实现RNN
    3. 理解定时后向传播算法和梯度消失的问题
    4. 实现一个GRU/LSTM RNN
  • 在本tutorial中我们实现了一个基于语言模型的RNN。这个语言模型应用包括两个部分:第一,它允许我们对一个可能出现在现实当中的抽象句子做一个评分,这个分数可以用来评判句子的语法和语义的准确性。这样的模型是典型的机器翻译系统当中的一个部分。第二,一个语言模型允许我们生成一个新的文本(我认为这是一个非常cool的应用)。在Shakespeare(莎士比亚)文章上训练一个语言模型,它可以生成一个新的类莎士比亚的文本。Andrej Karpathy写的贴子很好地阐明了基于RNN的字符level的语言模型能够干什么。

  • 我假设你们对于基本的神经网络都熟悉了。如果你们并不熟悉的话,你可以先去看一下这个贴子,从零开始实现一个神经网络,它会指导你非RNN背后神经网络的思想和实现。

什么是RNNs?

  • RNN的核心思想是利用序列信息。在传统的神经网络中,我们假设所有的inputs和outputs都是彼此独立的。但是在很多的任务当中,这是一个非常不合理的想法。如果你想预测一个句子当中的下一个单词,你最好能知道它前面跟着的是什么单词。RNNs当中的”recurrent”,递归,是因为它对于序列当中的每一个元素都执行了同样的任务,当前的output和之前的计算有依赖关系。RNNs的另一种理解就是它有一个“记忆体”记住了到目前为止所计算的信息。理论上RNNs能够利用任意长序列上的信息,但是实际上它们只是局限于能回看前面几步上的信息(以后会更多)。这就是一个典型的RNN模型图:

  • 上面这张图就是RNN展开成全连接的网络图。展开的意思就是我们把所有的序列写出来。譬如,如果我们关注的序列是包含5个单词的,那么展开的网络图就是5层的网络,每一层对应一个单词。图中的公式参数意义如下:

    • $x_t$是在时间$t$时的输入。譬如,$x_1$可以是序列中对应到第二个单词的one_hot向量。($X_0$是第一个)
    • $s_t$是在时间$t$时的隐层状态。它是网络的“记忆体”。$s_t$是基于前一个隐层状态和当前的输入计算出来的:
    • 这个函数f通常是一个非线性函数,如tanh或者ReLU。$s_{-1}$是用来计算第一个隐层的,通常初始化为全0。
    • $o_t$是在步骤$t$时的输出。譬如,如果我们想去预测句子当中的下一个单词,结果会是一个概率向量,它对应着我们字典中的每一个单词。$o_t=softmax(V*s_t)$
  • 以下是一些我们需要注意的地方:

    • 你可以把$s_t$看作是网络的记忆体。$s_t$捕获了前一步所发生的信息。输出$o_t$是单独基于时间$t$时的记忆算出来的。像以上简单提到的,实际上它有点复杂,因为$s_t$一般不能够捕获太多次之前的信息。
    • 不想传统的深度学习网络,每一层都用了不同的参数,RNN当中的每一层是共享一组参数的($U,V,W$)。这也说明了我们每一层都是做了相同的操作的,只是每次的inputs不同了。这就大大减少了我们要学习的参数的数量。
    • 上面的图当中每一层都有一个输出,但是有些任务当中这些输出并不是必须的。譬如,在做句子的情感分析当中,我们可能就是需要最后一个输出而已,而不是每一层的outputs。简单来说,我们不是每一层都需要输入。RNN的主要特点是它的的隐层状态,它捕获了序列当中的一些信息。

RNN能够干什么?

  • RNN在许多的自然语言处理(NLP)任务中当中获得非常好的结果。这里我不得不提到的一个常用到的RNN模型就是LSTMs。相比普通的RNN模型,它能更好的捕获到长期的依赖信息。但是不要担心,LSTMs也是我们这个tutorial中的RNN差不多,只是它的隐层状态的计算会有所不同。我们会在下一个贴子当中详解LSTMs。这里我们只是列举一些RNN在NLP当中应用的例子。

语言建模和生成文本

  • 给定一个序列的单词,我们要预测当给定前一个单词时,下一个单词会出现的概率。语言模型会让我们评判一个什么序列的单词如何才可能是一个句子。这也是机器翻译当中的一个重要的输入(通常概率高的句子都是正确的)。预测下一个单词的另一个作用是我们会得到一个生成模型,这个模型可以通过从输出概率当中进行采样来生成新的文本。利用我们的训练数据,我们可以生成各种各样的单词序列。在语言模型当中,我们的输入通常是一个单词的序列(譬如加密成一个one-hot向量),然后我们的输出就是预测的单词的序列。当我们训练网络时,我们把$o_t=x_{t+1}$,因为我们希望时间$t$时的输出是真实的下一个单词。
  • 语言模型和生成文本的相关论文:

机器翻译

语音识别

生成图片描述

  • 结合卷积神经网络(CNN)和RNN的模型能够对没标签的图片生成描述。这是一个非常惊人的工作。这个组合模型还能把图片当中找到的特征和生成的单词一一对应。

训练RNNs

  • 训练RNN和训练传统的神经网络很相似。我们也用到后向传播(backpropagtion)算法,但是有小小不同。因为参数在整个网络中的每一层是共享的,而每一层输出的梯度不仅仅依赖于当前这一步的计算,还依赖前一步的计算。譬如,为了计算$t=4$时的梯度,我们需要往后传播3层,并且把它们的梯度加起来。这就是定时后向传播(BPTT)。如果这还是没有那么清晰的话,不要担心,我们之后还会有更多的详情。现在,我们要注意到用BPTT来训练普通的RNNs,因为梯度消失的问题,所以很难学习到长期的依赖信息(譬如,每一层之间的信息相差甚远)。但还是有一些模型来解决这个问题的,像特定的RNNs模型(LSTMs)就是特别设计用来解决这些问题的。

RNNs扩展

  • 经过研究者们那么多年的研究,他们已经发展了更为复杂的RNNs模型来解决普通的RNN模型的一些不足。我们接下来的贴子会讲到更多的细节,但是我想在本部分中做一个简单的总结,这样我们才能对RNNs模型的分类更为熟悉。
  • **双向RNNs(Bidirectional RNNs)**就是基于这样的思想:时间$t$的输出可能不仅仅依赖鱼序列当中的前面的元素,还包括了未来的元素。譬如,预测一个序列当中的缺失的单词,你可能要看到前面和后边的内容。双向RNNs非常容易。他们就是把两个RNNs堆叠在一起。输出是基于两个RNNs模型的隐层计算得到的。
  • 深度(Bidirectional)RNNs和双向RNNs很相似,就是我们现在每一个时间点有多层。实际上这给了我们一个更高的学习容量(但是我们也需要大量的训练数据)。
  • LSTM网络现在非常流行。LSTMs和RNNs在架构上没什么大的不同,但是它们利用了不同的函数来计算隐层状态。LSTMs中的记忆体叫做cells,你可以把它们当成一个黑盒子,它吃进了前一个状态$h_{t-1}$和当前的输入$x_t$。这些cells内部决定哪些应该保持,哪些应该删除。然后它们就会合并前一个状态,当前状态和当前的输入。结果证明了这类型的units非常有效地捕获了长期的依赖信息。LSTMs一开始可能很疑惑,但是如果你感兴趣的话,可以读一下这篇详细的解释

总结

  • 目前还是理解的不错的。我希望你现在对RNNs已有了一个基本的理解。在下一个贴子中我们会利用Python和Theano实现我们RNN语言模型的第一个版本,请在留言区留下你的问题。
 评论