tensorflow - 在 TensorFlowdynamic_rnn 中使用sequence_length参数时如何处理填充

标签 tensorflow machine-learning deep-learning sequence recurrent-neural-network

我正在尝试使用 Tensorflow 中的 dynamic_rnn 函数来加快训练速度。经过一些阅读后,我的理解是,加速训练的一种方法是显式地将值传递给此函数中的 sequence_length 参数。经过更多阅读,发现 this所以解释,看来我需要传递的是一个向量(可能由 tf.placeholder 定义),其中包含批处理中每个序列的长度。

这就是我感到困惑的地方:为了利用这一点,我是否应该将每个批处理填充到批处理内的最长长度序列,而不是训练集中的最长长度序列? Tensorflow 如何处理任何较短序列中剩余的零/填充标记?另外,这里的主要优势真的是速度吗?还是只是额外保证我们在训练期间屏蔽 pad-token?任何帮助/上下文将不胜感激。

最佳答案

should I pad each of my batches to the longest-length sequence within the batch instead of the longest-length sequence in the training set?

批处理内的序列必须对齐,即必须具有相同的长度。所以你的问题的一般答案是"is"。但是不同批处理不必具有相同的长度,因此您可以将输入序列分层为具有大致相同大小的组,并相应地填充它们。这种技术称为分桶,您可以在 this tutorial 中阅读相关内容。 .

How does Tensorflow handle the remaining zeros/pad-tokens in any of the shorter sequences?

非常直观。 tf.nn.dynamic_rnn返回两个张量:outputstates。假设实际序列长度为t,填充序列长度为T

然后,output 将在 i > t 之后包含零,并且 states 将包含第 t 个单元格状态,忽略尾随单元格的状态。

这是一个例子:

import numpy as np
import tensorflow as tf

n_steps = 2
n_inputs = 3
n_neurons = 5

X = tf.placeholder(dtype=tf.float32, shape=[None, n_steps, n_inputs])
seq_length = tf.placeholder(tf.int32, [None])

basic_cell = tf.nn.rnn_cell.BasicRNNCell(num_units=n_neurons)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, 
                                    sequence_length=seq_length, dtype=tf.float32)

X_batch = np.array([
  # t = 0      t = 1
  [[0, 1, 2], [9, 8, 7]], # instance 0
  [[3, 4, 5], [0, 0, 0]], # instance 1
  [[6, 7, 8], [6, 5, 4]], # instance 2
])
seq_length_batch = np.array([2, 1, 2])

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  outputs_val, states_val = sess.run([outputs, states], feed_dict={
    X: X_batch, 
    seq_length: seq_length_batch
  })
  print(outputs_val)
  print()
  print(states_val)

请注意,实例 1 已填充,因此 outputs_val[1,1] 是零向量,并且 states_val[1] ==outputs_val[1,0]:

[[[ 0.76686853  0.8707901  -0.79509073  0.7430128   0.63775384]
  [ 1.          0.7427926  -0.9452815  -0.93113345 -0.94975543]]

 [[ 0.9998851   0.98436266 -0.9620067   0.61259484  0.43135557]
  [ 0.          0.          0.          0.          0.        ]]

 [[ 0.99999994  0.9982034  -0.9934515   0.43735617  0.1671598 ]
  [ 0.99999785 -0.5612586  -0.57177305 -0.9255771  -0.83750355]]]

[[ 1.          0.7427926  -0.9452815  -0.93113345 -0.94975543]
 [ 0.9998851   0.98436266 -0.9620067   0.61259484  0.43135557]
 [ 0.99999785 -0.5612586  -0.57177305 -0.9255771  -0.83750355]]

Also, is the main advantage here really speed, or just extra assurance that we're masking pad-tokens during training?

当然,批处理比逐个输入序列更有效。但指定长度的主要优点是可以从 RNN 中获得合理的状态,即填充项不会影响结果张量。如果您不设置长度,但手动选择正确的状态,您将获得完全相同的结果(和相同的速度)。

关于tensorflow - 在 TensorFlowdynamic_rnn 中使用sequence_length参数时如何处理填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48469779/

相关文章:

python - 威 bool 分布 Scipy

machine-learning - 一小组标记数据上的随机森林分类器

python - Tensorflow:提要字典错误:您必须为占位符张量提供一个值

tensorflow - 测试精度提高,同时损耗增加

python - ValueError : Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=4, 发现 ndim=2。收到的完整形状 : [None, 2584]

python - tf.data.Dataset 可馈送迭代器,用于训练和推理

python - 如何在自定义 tf.keras.layers.Layer 中支持 mask

python - 如何抑制 Tensorflow (Python) 中的特定警告

machine-learning - TensorFlow Deep MNIST 中的卷积和池化

python - feature_columns 的项目必须是 _FeatureColumn