LSTM 结构解析如图所示
但是这样的结构说是有一个缺陷,当前的状态 Ct 不能影响输入门和遗忘门在下一时刻的输出,使得整个结构对上个序列的处理丢失了部分信息。所以增加了 窥孔连接。
如图:黑线条即是窥视孔连接
TensorFlow 中的 RNN 类:
tf.contrib.rnn.BasicRNNCell(num_units,activation = tanh,reuse = None)
最基本的 RNN 实现,没有状态,没有遗忘门,unm_units 为 hidden_node
tf.contrib.rnn.BasicLSTMCell(num_units,forget_bias = 1.0,activation = tanh,reuse = None)
LSTM 实现的一个 basic 版本,forget_bias 添加到遗忘门的偏置
tf.contrib.rnn.LSTMCell(num_units,use_peepholes = False,initializer = None,forget_bias = 1.0,activation = tanh,reuse = None)
LSTM 实现的一个高级版本,use_peepholes 表示是否启动 窥孔连接,initializer 指定初始化函数
tf.contrib.rnn.GRUCell(num_units,activation = tanh)
GRU 的定义,比 LSTM 简单些,它将忘记门 和 输入门合成了一个单一的更新门。
tf.contrib.rnn.MultiRNNCell(cells)
cells 是一个 cell 列表,将列表中的 cell 一个个堆叠起来,如果使用 [cell1,cell2] 就是一共有两层。
搭建 rnn 神经网络
在定义好 cell 类后,我们还需要将它们连接起来构成 RNN 网络,TensorFlow 中有几种现成的构建网络模式。
静态 RNN 构建:
tf.nn.static_rnn(cell,inputs,initial_state = None,dtype = None,sequence_length = None,scope = None)
cell :生成好的 cell 类对象
inputs:输入数据,一定是list 或者二维张量,list 的顺序就是时间序列,元素就是每一个序列的值。
dtype:期望输出和初始化 state 的类型
sequence_length: 每一个输入的序列长度
scope: 命名空间
动态 RNN 构建
tf.nn.dynamic_rnn(cell,inputs,sequence_length = None,initial_state = None,dtype = None,time_major = False,scope = None)
time_major 为默认 False 时,inputs 的shape 为 [batch_size,max_time,...] 三维,为 True 时,inputs 的shape 为 [max_time,batch_size,...] 三维。 ... 代表具体数据
动态 RNN 还有个更高级的功能就是可以处理变长序列,方法就是:在准备样本的同时,将样本对应的长度也作为初始化参数,一起创建动态 RNN 。