Tensorflow 张量流RNN的动态张量形状

Tensorflow 张量流RNN的动态张量形状,tensorflow,recurrent-neural-network,Tensorflow,Recurrent Neural Network,我正在尝试一个非常简单的tensorflow RNN示例。 在该示例中,我使用动态rnn。代码如下: data = tf.placeholder(tf.float32, [None, 10,1]) #Number of examples, number of input, dimension of each input target = tf.placeholder(tf.float32, [None, 11]) num_hidden = 24 cell = tf.nn.rnn_cell.LST

我正在尝试一个非常简单的tensorflow RNN示例。 在该示例中,我使用动态rnn。代码如下:

data = tf.placeholder(tf.float32, [None, 10,1]) #Number of examples, number of input, dimension of each input
target = tf.placeholder(tf.float32, [None, 11])
num_hidden = 24
cell = tf.nn.rnn_cell.LSTMCell(num_hidden,state_is_tuple=True)
val, _ = tf.nn.dynamic_rnn(cell, data, dtype=tf.float32)
val = tf.transpose(val, [1, 0, 2])
last = tf.gather(val, int(val.get_shape()[0]) - 1)
weight = tf.Variable(tf.truncated_normal([num_hidden, int(target.get_shape()[1])]))
bias = tf.Variable(tf.constant(0.1, shape=[target.get_shape()[1]]))
prediction = tf.nn.softmax(tf.matmul(last, weight) + bias)
cross_entropy = -tf.reduce_sum(target * tf.log(tf.clip_by_value(prediction,1e-10,1.0)))
optimizer = tf.train.AdamOptimizer()
minimize = optimizer.minimize(cross_entropy)
mistakes = tf.not_equal(tf.argmax(target, 1), tf.argmax(prediction, 1))
error = tf.reduce_mean(tf.cast(mistakes, tf.float32))
data = tf.placeholder(tf.float32, [None, None,1])
事实上,代码是从这个。 这个RNN网络的输入是一个二进制数序列。每个数字都放入一个数组中。例如,sequence的格式为:
[[1]、[0]、[0]、[1]、[1]、[0]、[1]、[1]、[1]、[0]]
输入的形状是[None,10,1],分别是批量大小、序列大小和嵌入大小。现在,由于dynamic rnn可以接受变量输入形状,我将代码更改如下:

data = tf.placeholder(tf.float32, [None, 10,1]) #Number of examples, number of input, dimension of each input
target = tf.placeholder(tf.float32, [None, 11])
num_hidden = 24
cell = tf.nn.rnn_cell.LSTMCell(num_hidden,state_is_tuple=True)
val, _ = tf.nn.dynamic_rnn(cell, data, dtype=tf.float32)
val = tf.transpose(val, [1, 0, 2])
last = tf.gather(val, int(val.get_shape()[0]) - 1)
weight = tf.Variable(tf.truncated_normal([num_hidden, int(target.get_shape()[1])]))
bias = tf.Variable(tf.constant(0.1, shape=[target.get_shape()[1]]))
prediction = tf.nn.softmax(tf.matmul(last, weight) + bias)
cross_entropy = -tf.reduce_sum(target * tf.log(tf.clip_by_value(prediction,1e-10,1.0)))
optimizer = tf.train.AdamOptimizer()
minimize = optimizer.minimize(cross_entropy)
mistakes = tf.not_equal(tf.argmax(target, 1), tf.argmax(prediction, 1))
error = tf.reduce_mean(tf.cast(mistakes, tf.float32))
data = tf.placeholder(tf.float32, [None, None,1])
基本上,我想使用可变长度序列(当然,同一批中的所有序列长度相同,但批之间不同)。但是,它会抛出错误:

Traceback (most recent call last):
  File "rnn-lstm-variable-length.py", line 48, in <module>
    last = tf.gather(val, int(val.get_shape()[0]) - 1)
TypeError: __int__ returned non-int (type NoneType)
回溯(最近一次呼叫最后一次):
文件“rnn lstm variable length.py”,第48行,在
last=tf.gather(val,int(val.get_shape()[0])-1)
TypeError:\uuuuu int\uuuu返回的非int(类型NoneType)
我知道第二个维度是
None
,不能在
get\u shape()[0]
中使用。然而,我相信一定有办法克服这一点,因为RNN通常接受可变长度输入。
我该怎么做;dr:尝试使用
tf.batch(…,dynamic_pad=True)
对数据进行批处理


@奥巴马的评论是正确的。最终,您的网络需要一个密集的数字矩阵来处理,有几种策略可以将可变长度数据转换为超矩形:

  • 将所有批次填充到固定大小(例如,假设每个输入的最大长度为500个项目,每个批次中的每个项目填充到500个)。这一战略没有什么动态性
  • 将每个批次的填充应用于批次中最长项目的长度(动态填充)
  • 根据长度对输入进行存储,并对每个批次应用填充。这与#2相同,但总体填充较少
  • 还有一些你也可以用的

    要进行此批处理,请使用:

  • tf.train.batch
    -默认情况下,它不进行填充,您需要自己实现它
  • tf.train.batch(…,dynamic_pad=True)
  • tf.contrib.training.bucket\u by\u sequence\u length

  • 我怀疑您也被
    tf.nn.dynamic\u rnn
    的使用弄糊涂了。需要注意的是,
    dynamic\u rnn
    中的
    dynamic
    指的是TensorFlow展开网络重复部分的方式。在
    tf.nn.rnn
    中,递归是在图中静态完成的(没有内部循环,它在图构造时展开)。然而,在
    dynamic\u rnn
    中,TensorFlow使用
    tf.while\u loop
    在运行时在图中迭代。要使用动态填充,您需要使用动态展开,但它不会自动执行。

    tf.gather
    需要一个张量,因此您可以使用
    tf.shape(val)
    val
    的形状获取一个在运行时计算的张量,例如
    tf.gather(val,tf.shape(val)[0]-1)

    签出此帖子。您确定它们是正确的吗?他们使用
    sequence=tf.placeholder(tf.float32,[None,max_length,frame_size])
    ,这意味着序列长度是固定的。出于某种原因,我觉得事情实际上不是动态长度,而是填充的。我的问题不同。实际上,一批中的每个项目都有相同的序列长度。但是,该长度未知,且各批次之间存在差异。因此,我无法指定输入数据占位符的形状。如果我稍后在
    tf.gather(val,int(val.get\u shape()[0])-1)
    中使用[batch\u size,None,None],它会抛出错误
    TypeError:\uuu int\uuuu返回的非int(type NoneType)
    哦,对了,
    tf.gather
    无论如何都需要一个张量,所以你可以使用
    tf.shape(val)
    来获得一个在运行时计算的张量,对于
    val
    -的形状,例如
    tf.gather(val,tf.shape(val)[0]-1)
    。正确,我试过了,效果很好。如果你用这句话来代替答案,我会接受的。非常感谢。@lenhhoxung-done,我将把这个留在这里,以防它对其他人有帮助。