处理变长输入序列
到目前为止,我们只使用固定大小的输入序列(全部正好两个步长)。 如果输入序列具有可变长度(例如,像句子)呢? 在这种情况下,你应该在调用dynamic_rnn()
(或static_rnn()
)函数时设置sequence_length
参数;它必须是一维张量,表示每个实例的输入序列的长度。 例如:
n_steps = 2
n_inputs = 3
n_neurons = 5
reset_graph()
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
seq_length = tf.placeholder(tf.int32, [None])
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32,
sequence_length=seq_length)
例如,假设第二个输入序列只包含一个输入而不是两个输入。 为了适应输入张量X
,必须填充零向量(因为输入张量的第二维是最长序列的大小,即 2)
X_batch = np.array([
# step 0 step 1
[[0, 1, 2], [9, 8, 7]], # instance 1
[[3, 4, 5], [0, 0, 0]], # instance 2 (padded with zero vectors)
[[6, 7, 8], [6, 5, 4]], # instance 3
[[9, 0, 1], [3, 2, 1]], # instance 4
])
seq_length_batch = np.array([2, 1, 2, 2])
当然,你现在需要为两个占位符X
和seq_length
提供值:
with tf.Session() as sess:
init.run()
outputs_val, states_val = sess.run(
[outputs, states], feed_dict={X: X_batch, seq_length: seq_length_batch})
现在,RNN 输出序列长度的每个时间步都会输出零向量(查看第二个时间步的第二个输出):
此外,状态张量包含每个单元的最终状态(不包括零向量):