DL-专题-RNN

Index

RNN 的基本结构

  • RNN 本质上是一个递推函数

  • 考虑当前输入 x(t)

  • 以上计算公式可展开为如下计算图(无输出单元)

  • RNN 的前向传播公式

    一般 h(0) 会初始化为 0 向量;并使用 tanh 作为激活函数 f

RNN 常见的几种设计模式(3)

RNN 一般包括以下几种设计模式

  • 每个时间步都有输出,且隐藏单元之间有循环连接

    • 即通常所说 RNN
    • 这种结构会在每个时间步产生一个输出,所以通常用于“Seq2Seq”任务中,比如序列标注、机器翻译等。这些任务通常都比较复杂。
  • 每个时间步都有输出,但是隐藏单元之间没有循环连接,只有当前时刻的输出到下个时刻的隐藏单元之间有循环连接

    • 这种模型的表示能力弱于第一种,但是它更容易训练
    • 因为每个时间步可以与其他时间步单独训练,从而实现并行化
    • 具体来说,就是使用 y(t) 代替 o(t) 输入下一个时间步。
  • 隐藏单元之间有循环连接,但只有最后一个时间步有输出

    • 忽略模式 1 中的中间输出,即可得到这种网络;
    • 这种网络一般用于概括序列。具体来说,就是产生固定大小的表示,用于下一步处理;
    • 在一些“Seq2One”中简单任务中,这种网络用的比较多;因为这些任务只需要关注序列的全局特征。

其中前两种 RNN 分别被称为 Elman network 和 Jordan network;通常所说的 RNN 指的是前者

Recurrent neural network - Wikipedia

RNN 的反向传播(BPTT) TODO

RNN 相关问题

RNN 相比前馈网络/CNN 有什么特点?

  • 前馈网络/CNN 处理序列数据时存在的问题:

    • 一般的前馈网络,通常接受一个定长向量作为输入,然后输出一个定长的表示;它需要一次性接收所有的输入,因而忽略了序列中的顺序信息;
    • CNN 在处理变长序列时,通过滑动窗口+池化的方式将输入转化为一个定长的向量表示,这样做可以捕捉到序列中的一些局部特征,但是很难学习到序列间的长距离依赖
  • RNN 处理时序数据时的优势:

    • RNN 很适合处理序列数据,特别是带有时序关系的序列,比如文本数据;
    • RNN 把每一个时间步中的信息编码到状态变量中,使网络具有一定的记忆能力,从而更好的理解序列信息。
    • 由于 RNN 具有对序列中时序信息的刻画能力,因此在处理序列数据时往往能得到更准确的结果。
  • 展开后的 RNN无输出

    • 一个长度为 T 的 RNN 展开后,可以看做是一个 T 层的前馈网络;同时每一层都可以有新的输入

    • 通过对当前输入 x_t 和上一层的隐状态 h_{t-1} 进行编码,t 层的隐状态 h_t 记录了序列中前 t 个输入的信息。

      普通的前馈网络就像火车的一节车厢,只有一个入口,一个出口;而 RNN 相当于一列火车,有多节车厢接收当前时间步的输入信息并输出编码后的状态信息(包括当前的状态和之前的所有状态)。

    • 最后一层隐状态 x_T 编码了整个序列的信息,因此可以看作整个序列的压缩表示

    • 常见的文本分类任务中,将 h_T 通过一个 Softmax 层,即可获得作为每个类别的概率:

      其中

    • U 为输入层到隐藏层的权重矩阵

    • W 为隐藏层从上一时刻到下一时刻的状态转移权重矩阵

    • f 为隐藏层激活函数,通常可选 tanhReLU

    • g 为输出层激活函数,可以采用 SoftmaxSigmoid 或线性函数(回归任务)

    • 通常 h_{-1} 初始化为 0 向量。

RNN 为什么会出现梯度消失/梯度爆炸?

  • 最大步长为 T 的 RNN 展开后相当于一个共享参数的 T 层前馈网络

    • RNN 的前向传播过程

    • 展开前一层

    • RNN 的梯度计算公式

      其中

      上标 (t) 表示时间步,下标 n 表示隐藏层的单元数(维度);diag() 为对角矩阵

RNN 中能否使用 ReLU 作为激活函数?

RNN中为什么要采用tanh而不是ReLu作为激活函数? - 知乎

  • 答案是肯定的。但是会存在一些问题。

    其实 ReLU 最早就是为了解决 RNN 中的梯度消失问题而设计的。