Tensorflow:tf.nn.dynamic_rnn():无法从动态时间主要的最后一个维度收集输出值

时间:2017-01-27 10:49:36

标签: tensorflow lstm recurrent-neural-network

我正在尝试使用RNN对新闻文章进行分类。由于新闻文章的篇幅不固定,我使用的是tf.nn.dynamic_rnn()。

# ....{Some Code Above}.....
with graph.as_default():
    sentences = tf.placeholder(tf.float32, shape=(batch_size, None, emmbedding_dimension))
    sequence_length = tf.placeholder(tf.float32, shape=batch_size)
    labels = tf.placeholder(tf.float32, shape=(batch_size, 2))

    lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=lstm_size)
    stacked_lstm = tf.nn.rnn_cell.DropoutWrapper(lstm_cell, output_keep_prob=1)
    stacked_lstm = tf.nn.rnn_cell.MultiRNNCell([stacked_lstm] * no_of_lstm_layers)
    outputs, states = tf.nn.dynamic_rnn(cell=stacked_lstm,
                                        inputs=sentences,
                                        sequence_length=sequence_length,
                                        initial_state=stacked_lstm.zero_state(batch_size, tf.float32))
# ....{Some Code Below}.....

上面代码中“输出”的张量形状是(batch_size,?,lstm_size)。

我想收集句子末尾的输出,这是动态的。我正在使用以下命令

outputs = tf.transpose(outputs, [1, 0, 2])
last = tf.gather(outputs, int(outputs.get_shape()[0]) - 1)

我收到以下错误,

Traceback (most recent call last):
  File "./rnn_fitness_level1_0.py", line 127, in <module>
    last = tf.gather(outputs, int(outputs.get_shape()[0]) - 1)
TypeError: __int__ returned non-int (type NoneType)

我认为这个错误是因为time_major(sentence_major)的输出的动态形状。

换句话说,“outputs.get_shape()[0]”的结果是“?”(无)

当我们使用固定的time_major(句子长度)时,获得最后输出的上述技术有效。

有没有办法实现动态time_major(句子长度)?

截至目前,我正在做以下

last = tf.reduce_mean(outputs, [0])

但我的理解是,通过做time_major(句子长度)的平均值,我没有使用RNN找到序列模式的潜力。 请让我知道您对此的看法。

1 个答案:

答案 0 :(得分:1)

一般来说,get_shape()是最好的努力。在图表运行之前,Tensorflow并不总是知道Tensor的形状。

你可以尝试很多东西。一种是在不使用get_shape的情况下自己计算最后一个索引的偏移量;如果您知道输入的大小,这应该不难。

另一种选择是使用Tensorflow的切片功能,它支持Numpy风格的“-1”索引来表示最后一个元素。例如,如果x是3D张量,x[:, -1, :]应该切出中间维度的最后一个元素。

有关更多文档,请参阅此处的tf.Tensor.__getitem__文档: https://www.tensorflow.org/api_docs/python/framework/core_graph_data_structures#Tensor

希望有所帮助!