RNN

特点

输入任意长度

More generally, they can work on sequences of arbitrary lengths, rather than on fixed-sized inputs like all the nets we have discussed so far.

创造性

RNNs can generate music, sentences, image captions, and much more.

基础知识

循环神经元及time step时间步(又叫frame 帧)

理解为下图右侧的某一个循环神经元的位置,就表示时间步。

循环神经元层及按时间展开

注意左侧的每一个循环神经元都是上面的单个循环神经元,而右侧的则是对此单个循环神经元的按时间展开,右侧并非实际的网络结构。

公式

这里的公式维度有参考意义,但是下文开始使用 hh 代替 yy ,因为两者会不相等,会有变化。

memory cells(记忆单元)

将RNN看做起到了记忆的作用。因此将单个循环神经元或是循环神经元层成为记忆单元。而记忆单元的状态记为 h(t)h_{(t)} 。下文开始使用 hh 代替 yy ,因为两者会不相等,会有变化。

RNN的变体(Sequence/Vector)

多个输入/输出叫Sequence,单个输入/输出Vector

Seq to seq (top left), seq to vector (top right), vector to seq (bottom left),delayed seq to seq (bottom right).

encoder与decoder

将上图中右下角的encoder与decoder之间的横线往上转,就可以看到前一个是seq to veq网络,往下转,就可以看到后一个是veq to seq网络。

Lastly, you could have a sequence-to-vector network, called an encoder, followed by a vector-to-sequence network, called a decoder (see the bottom-right network).

构建

不用现成函数,只是用代码实现

1.mini batch内的所有instance的意思就是分开送入网络,但这些instance面对的网络的参数是一样的

2.前面的神经网络里mini batch中的instance都是独立的,而RNN的instance之间是有计算依赖关系的,可以看作是一个整体的instance。所以在计算中特地定义两个占位符,以显示计算依赖关系。

比如下面的0,1,2与9,8,7。

一共五个神经元,每一个都接受3个输入,即1*n_inputs。

使用现成函数

但是之前的方法是自行定义时间步,如果时间步很长,这意味着需要很多占位符,程序就会非常不简洁。

使用static_rnn

BasicRNNCell看成与时间步相对应的一个单元。

static_rnn的运行原理为根据输入占位符数,如下的[X0, X1],创造出相应个数的copy进行连接。

避免输入过多占位符符号,可考虑利用packing sequence的技术,只输入一个占位符

核心代码就是设置一个n_steps的变量,然后将占位符维度,修改为[None, n_steps, n_inputs],None表示mini-batch中的instance个数。

使用dynamic_rnn

但是static_rnn的问题在于还是对每个时间步创造复制,因此内存会是一个大问题。

所以采用dynamic_rnn,但是具体原理没有讲。只说while_loop节省了内存,也无需stackunstack了,很简洁。

变长输入序列

之前讨论的都是同样长度的输入序列(都是two steps long),为了应对不同长度的输入序列,多定义一个占位符,记录instance中输入序列的数目(即所需要时间步的长度)。

训练

所有的输出值都涉及计算梯度下降值;把各个计算出来的梯度下降值,然后再累加。

Note that the gradients flow backward through all the outputs used by the cost function, not just through the final output (for example, in Figure below the cost function is computed using the last three outputs of the network, Y(2)Y(2) , Y(3)Y(3) , and Y(4)Y(4) , so gradients flow through these three outputs, but not through Y(0)Y(0) and Y(1)Y(1) ). Moreover, since the same parameters WW and bb are used at each time step, backpropagation will do the right thing and sum over all time steps.

序列分类

时间序列预测

先生成时间序列,这里的逻辑是从全部30的时间内,全部当成训练数据。J这样岂不是有过拟合的倾向。

使用OutputProjectionWrapper控制输出

其在basicRNNCell的基础上进行封装,加一层全连接层,控制输出。

导出模型可以看效果

不使用OutputProjectionWrapper控制输出

预测能力

下面其实就是两种初始化序列的对比:

深度RNN

构建——MultiRNNCell

核心代码就是使用MultiRNNCell,将BasicRNNCell组成的列表作为参数传入进去。

而states则会将每一个RNN单元的输出都会返回。

RNN的dropout

之前的dropout是在一层的前面或后面加一层dropout,而这里提供了一个方法DropoutWrapper可以对的每一层都使用dropout。

核心代码如下,设置一个占位符参数,这样就能起到控制是否training的效果。

RNN中过长时间步(即instance过长)的问题

  • 网络训练缓慢,发生vanishing和exploding问题。

    • 可以采用之前的一些方法进行缓解:good parameter initialization, nonsaturating activation functions (e.g., ReLU), Batch Normalization, Gradient Clipping, and faster optimizers

    • 可以采用truncated backpropagation through time

  • 前几个时间步的信息会丢失。

Last updated

Was this helpful?