天天看点

tensorflow-LSTM讲解blog

http://colah.github.io/posts/2015-08-Understanding-LSTMs/​

一些参数:

max_grad_norm = 5       # 用于控制梯度膨胀,如果梯度向量的L2模超过max_grad_norm,则等比例缩小
num_layers = 2          # lstm层数
num_steps = 20          # 单个数据中,序列的长度。
# 对于RNNCell,还有两个类属性比较重要:
    state_size # 隐层的大小
    output_size # 输出的大小
input_size # 表示输入数据单个序列单个时间维度上固有的长度      

比如我们通常是将一个batch送入模型计算,设输入数据的形状为(batch_size, input_size),那么计算时得到的隐层状态就是(batch_size, state_size),输出就是(batch_size, output_size)。

从源码中可以看到,在LSTM单元中,有2个状态值,分别是c和h。其中h在作为当前时间段的输出的同时,也是下一时间段的输入的一部分。

当state_is_tuple=True的时候,state是元组形式,state=(c,h)。如果是False,那么state是一个由c和h拼接起来的张量,state=tf.concat(1,[c,h])。

在rnn中使用dropout的方法和cnn不同。在rnn中进行dropout时,对于rnn的部分不进行dropout,也就是说从t-1时候的状态传递到t时刻进行计算时,这个中间不进行memory的dropout;仅在同一个t时刻中,多层cell之间传递信息的时候进行dropout。在使用tf.nn.rnn_cell.DropoutWrapper时,同样有一些参数,例如input_keep_prob,output_keep_prob等,分别控制输入和输出的dropout概率。(同层cell不进行dropout)

lstm上一时间段的状态会自动参与到当前时间段的输出和状态的计算当中。

TensorFlow提供了一个tf.nn.dynamic_rnn函数,使用该函数就相当于调用了n次call函数。

# inputs: shape = (batch_size, time_steps, input_size)

# cell: RNNCell

# initial_state: shape = (batch_size, cell.state_size)。初始状态。一般可以取零矩阵

outputs, state = tf.nn.dynamic_rnn(cell, inputs, initial_state=initial_state)
'''
此时,得到的outputs就是time_steps步里所有的输出。
它的形状为(batch_size, time_steps, cell.output_size)。
state是最后一步的隐状态,它的形状为(batch_size, cell.state_size)。
'''      
# 源码中BasicRNNCell的call函数实现:

    def call(self, inputs, state):
       """Most basic RNN: output = new_state = act(W * input + U * state + B)."""
       output = self._activation(_linear([inputs, state], self._num_units, True))
       return      
self._forget_bias) + sigmoid(i) * self._activation(j))

new_h = self._activation(new_c) * sigmoid(o)


if self._state_is_tuple:
 new_state = LSTMStateTuple(new_c, new_h)

else:
 new_state = array_ops.concat([new_c, new_h], 1)

return      

继续阅读