处理变长输入序列

到目前为止,我们只使用固定大小的输入序列(全部正好两个步长)。 如果输入序列具有可变长度(例如,像句子)呢? 在这种情况下,你应该在调用dynamic_rnn()(或static_rnn())函数时设置sequence_length参数;它必须是一维张量,表示每个实例的输入序列的长度。 例如:

  1. n_steps = 2
  2. n_inputs = 3
  3. n_neurons = 5
  4. reset_graph()
  5. X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
  6. basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
  1. seq_length = tf.placeholder(tf.int32, [None])
  2. outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32,
  3. sequence_length=seq_length)

例如,假设第二个输入序列只包含一个输入而不是两个输入。 为了适应输入张量X,必须填充零向量(因为输入张量的第二维是最长序列的大小,即 2)

  1. X_batch = np.array([
  2. # step 0 step 1
  3. [[0, 1, 2], [9, 8, 7]], # instance 1
  4. [[3, 4, 5], [0, 0, 0]], # instance 2 (padded with zero vectors)
  5. [[6, 7, 8], [6, 5, 4]], # instance 3
  6. [[9, 0, 1], [3, 2, 1]], # instance 4
  7. ])
  8. seq_length_batch = np.array([2, 1, 2, 2])

当然,你现在需要为两个占位符Xseq_length提供值:

  1. with tf.Session() as sess:
  2. init.run()
  3. outputs_val, states_val = sess.run(
  4. [outputs, states], feed_dict={X: X_batch, seq_length: seq_length_batch})

现在,RNN 输出序列长度的每个时间步都会输出零向量(查看第二个时间步的第二个输出):

处理变长输入序列 - 图1

此外,状态张量包含每个单元的最终状态(不包括零向量):

处理变长输入序列 - 图2