tensorflow中tf.dynamic_rnn使用,outputs和state理解

tf.dynamic_rnn

tensorflow 的dynamic_rnn,我们用一个小例子来说明其用法,假设你的RNN的输入input是[2,3,4],其中2是batch_size,3是文本最大长度,一般叫num_steps或者seq_length,4是embedding_size。我们假设第二个文本长度只有2,剩下的1个是使用0-padding方法填充的。dynamic_rnn返回的是两个参数:outputs,last_states,其中outputs是[2,3,4],也就是每一个迭代隐状态的输出,它包括了训练中所有隐层状态,而last_states是由(c,h)组成的tuple,大小均为[batch,hidden_size]也就是[2,2]。

到这里并没有什么不同,但是dynamic有个参数:sequence_length,这个参数用来指定每个example的长度,比如上面的例子中,我们令 sequence_length为[3,2],表示第一个example有效长度为3,第二个example有效长度为2,当我们传入这个参数的时候,对于第二个batch,TensorFlow对于2以后的padding就不计算了,其last_states将重复第2步的last_states直至第3步,而outputs中超过第2步的结果将会被置零。

具体看代码和输出:


import tensorflow as tf
import numpy as np

# 产生2个batch数据,句子length为3,embedding大小为4
X = np.random.randn(2, 3, 4)

# 第二个batch长度为2
X[1,2:] = 0
X_lengths = [3, 2]
print(X)
# cell = tf.contrib.rnn.BasicLSTMCell(num_units=64, state_is_tuple=True)
cell=tf.nn.rnn_cell.BasicLSTMCell(num_units=2,state_is_tuple=True)

outputs, last_states = tf.nn.dynamic_rnn(
    cell=cell,
    dtype=tf.float64,
    sequence_length=X_lengths,
    inputs=X)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    o=sess.run(outputs)
    s=sess.run(last_states)
    print('output\n',o)
    print('last_o\n',o[:,-1,:])# 从output中取最后一次输出

    print('--------------------')
    print('s\n',s)
    print('s.c\n',s.c)    # 这是门控单元的权重,这里不需要
    print('s.h\n',s.h)    #s.h就是最后一次输出的状态

产生以下输出:

首先能看到第二个句子最后一行全是0,说明句子长度为2,后面的0相当于pading上的。

然后经过LSTM产生两个输出,output和state

在output中,发现第二个句子经过训练后,最后产生的状态全是0,但是在state中用s.h能找到其最后一次输出不是0,而是与output中最后一次不是0的一致,如下面加上高亮的几个数,这些输出是一样的。所以如果想用dynamic_rnn得到输出后,只需要最后一次的状态输出,直接调用s.h即可。






猜你喜欢

转载自blog.csdn.net/qq_35203425/article/details/79572514