在TensorFlow dynamic中使用序列长度参数时如何处理填充

在TensorFlow dynamic中使用序列长度参数时如何处理填充,tensorflow,machine-learning,deep-learning,sequence,recurrent-neural-network,Tensorflow,Machine Learning,Deep Learning,Sequence,Recurrent Neural Network,我正在尝试使用Tensorflow中的动态\u rnn功能来加速训练。在阅读了一些内容之后,我的理解是加快训练的一种方法是显式地将值传递给此函数中的sequence\u length参数。经过一番阅读,并找到了这样的解释,似乎我需要传递的是一个向量(可能由tf.placeholder定义),它包含一个批中每个序列的长度 这里是我困惑的地方:为了利用这一点,我是否应该将每个批次填充到批次中最长的长度序列,而不是训练集中最长的长度序列?Tensorflow如何处理任何较短序列中剩余的零/填充令牌?此

我正在尝试使用Tensorflow中的
动态\u rnn
功能来加速训练。在阅读了一些内容之后,我的理解是加快训练的一种方法是显式地将值传递给此函数中的
sequence\u length
参数。经过一番阅读,并找到了这样的解释,似乎我需要传递的是一个向量(可能由
tf.placeholder
定义),它包含一个批中每个序列的长度

这里是我困惑的地方:为了利用这一点,我是否应该将每个批次填充到批次中最长的长度序列,而不是训练集中最长的长度序列?Tensorflow如何处理任何较短序列中剩余的零/填充令牌?此外,这里的主要优势是速度,还是我们在训练中屏蔽垫标识的额外保证?如有任何帮助/背景,将不胜感激

我是否应该将每个批次填充到批次中的最长长度序列,而不是训练集中的最长长度序列

批次中的序列必须对齐,即必须具有相同的长度。所以对你的问题的一般回答是“是”。但是不同的批不必具有相同的长度,因此您可以将输入序列分成大小大致相同的组,并相应地填充它们。这项技术称为扣合,您可以在中阅读

Tensorflow如何处理任何较短序列中剩余的零/填充令牌

非常直观。返回两个张量:
输出
状态
。假设实际序列长度为
t
,填充序列长度为
t

然后,
输出
将在
i>t
之后包含零,
状态
将包含
t
-th单元格状态,忽略后续单元格的状态

下面是一个例子:

将numpy导入为np
导入tensorflow作为tf
n_步数=2
n_输入=3
n_神经元=5
X=tf.placeholder(dtype=tf.float32,shape=[无,n个步骤,n个输入])
seq_length=tf.placeholder(tf.int32,[None])
基本细胞=tf.nn.rnn细胞.基本细胞(数量单位=n个神经元)
输出,状态=tf.nn.dynamic(基本单元,X,
序列长度=序列长度,数据类型=tf.float32)
X_batch=np.array([
#t=0 t=1
[0,1,2],[9,8,7],#实例0
[3,4,5],[0,0,0]],#实例1
[6,7,8],[6,5,4],#实例2
])
seq_length_batch=np.数组([2,1,2])
使用tf.Session()作为sess:
sess.run(tf.global\u variables\u initializer())
输出值,状态值=sess.run([outputs,states],feed_dict={
X:X_批次,
序号长度:序号长度批量
})
打印(输出值)
打印()
打印(状态值)
请注意,实例1是填充的,因此
输出值[1,1]
是零向量,并且
状态值[1]==输出值[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]]
此外,这里的主要优势是速度,还是我们在训练中屏蔽垫标识的额外保证


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

Hi,@Maxim,我已经尝试了您的示例代码,但是
seq\u length\u batch
的赋值触发了一些错误,即ValueError:使用序列设置数组元素。我想知道我们是否应该为
seq_length_batch
分配一个数组np.array[1,2,1]。