添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 2019.08.18: 完成初稿
  • RNN 简介

    我们前面接触到的全连接和 CNN 可以很好地完成线性回归和 logistic 回归,或者去识别特定的对象。但是,在处理我们日常用的自然语言时,前面两种模型就有点吃力了。为了要能够捕捉序列化数据中的信息,RNN 应运而生(最早由 Elman 在 1990 年 提出 )。RNN 与之前的模型最大的不同就是打破了只往一个方向传递计算结果的套路,允许神经元的输出再次作为自己的输入,对比如下图所示:

    这样的网络结构单个比较容易画出来,一旦序列长度增加,指向自己的箭头不好处理,所以我们一般会沿着时间方向对模型进行展开:

    RNN 有啥优点呢:

  • 利用了数据的序列信息
  • 降低了参数个数
  • 给 NLP 提供了很大支持
  • BPTT

    BPTT 是 Back-propagation through Time 的缩写,也就是用来为 RNN 设计的反向传播技术,这个和之前的反向传播的不同之处在于:

  • 对于 RNN 来说,不同 timesteps 共享相同的参数,我们根据每个训练样本/批次的所有 timesteps 的梯度之和来更新这些参数(在 CNN 和全连接中,每一层都有独立的参数)
  • 对于 RNN 来说,timesteps 会根据序列长度的变化而变化(在 CNN 和全连接中,网络的层数是确定的)
  • 这里我们关注下第二点,如果我们的序列非常长(比如是一片文章,有 1000 个词),那么整个反向传播的计算量会非常大,与此同时可能造成梯度爆炸或梯度消失。更多关于 BPTT 的介绍可以参考 这里

    为了避免对所有的 timesteps 进行参数更新,我们常常会限制 timesteps 的个数,称为 truncated BPTT。这个方法一方面加速了计算,但另一方面降低了 RNN 的学习能力(相当于只能往回看指定的 timesteps,而不是全部的信息)。

    在 Tensorflow 中,我们需要在开始训练前就指定好具体的 timesteps 数量,也就是我们需要事先确定序列的长度。因此,要么把长度分成桶然后分桶训练,要么设定一个长度进行截取或填充。

    Gated Recurrent Unit

    在实践中,RNN 在捕捉长效依赖上非常差劲(大概就是句子的最后和开头相关,因为 timesteps 的限制,RNN 无法捕捉到这样的信息)。为了解决长效依赖的问题,人们开始使用 LSTM,有趣的是,LSTM 其实在上世纪 90 年代就已提出,只是现在因为计算力的增长,才重新开始受人关注。

    关于 LSTM 结构的图很多,下面这张是比较清晰的( 来源

    一个 LSTM Cell 包含 4 个门,一般来说记为 $i,o,f,c^\sim$,分别代表 输入门(input)、输出门(output)、遗忘门(forget)和候选门(candidate/new memory)。具体的公式这里就不详细列出,网上有很多相关资源。简单来说,我们可以认为这些门是用来控制信息流通的,每个门都有相同的维度:

  • 输入门:当前输入有多少可以通过
  • 遗忘门:上一个 state 有多少会进入下一个 state
  • 输出门:当前的输出有多少会传递到下一个 state
  • 候选门:根据上一 state 和当前输入计算出当前 state
  • 最终输出:把前面所有的组合起来,作为给下一个 state 的输出
  • LSTM 的目标是捕捉长效依赖,GRU 则是 LSTM 的一个简化版本,虽然从理论上来说 GRU 可以大幅降低计算量,但是实际使用时相对 LSTM 并没有特别大的提升。GRU 和 LSTM 的对比如下:

    在 Tensorflow 我们更倾向于使用 GRU,因为 LSTM 实在太笨重了,GRU 的输出只有一个 state,而 LSTM 有俩,处理起来就要多花一点时间。

    语言建模

    语言建模常用的方法有:

  • N-gram
  •