无法在 Python TensorFlow 中用 LSTMBlockFusedCell 替换 LSTMBlockCell [英] Cannot replace LSTMBlockCell with LSTMBlockFusedCell in Python TensorFlow
问题描述
将 LSTMBlockCell
替换为LSTMBlockFusedCell
在 static_rnn 中抛出 TypeError`.我正在使用从源代码编译的 TensorFlow 1.2.0-rc1.
Replacing LSTMBlockCell
with LSTMBlockFusedCell
throws a TypeError in static_rnn`. I'm using TensorFlow 1.2.0-rc1 compiled from source.
完整的错误信息:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-2986e054cb6b> in <module>()
19 enc_cell = tf.contrib.rnn.LSTMBlockFusedCell(rnn_size)
20 enc_layers = tf.contrib.rnn.MultiRNNCell([enc_cell] * num_layers, state_is_tuple=True)
---> 21 _, enc_state = tf.contrib.rnn.static_rnn(enc_layers, enc_input_unstacked, dtype=dtype)
22
23 with tf.variable_scope('decoder'):
~/Virtualenvs/scikit/lib/python3.6/site-packages/tensorflow/python/ops/rnn.py in static_rnn(cell, inputs, initial_state, dtype, sequence_length, scope)
1139
1140 if not _like_rnncell(cell):
-> 1141 raise TypeError("cell must be an instance of RNNCell")
1142 if not nest.is_sequence(inputs):
1143 raise TypeError("inputs must be a sequence")
TypeError: cell must be an instance of RNNCell
重现代码:
import tensorflow as tf
batch_size = 8
enc_input_length = 1000
dtype = tf.float32
rnn_size = 8
num_layers = 2
enc_input = tf.placeholder(dtype, shape=[batch_size, enc_input_length, 1])
enc_input_unstacked = tf.unstack(enc_input, axis=1)
with tf.variable_scope('encoder'):
enc_cell = tf.contrib.rnn.LSTMBlockFusedCell(rnn_size)
enc_layers = tf.contrib.rnn.MultiRNNCell([enc_cell] * num_layers)
_, enc_state = tf.contrib.rnn.static_rnn(enc_layers, enc_input_unstacked, dtype=dtype)
_like_rnncell
看起来像:
def _like_rnncell(cell):
"""Checks that a given object is an RNNCell by using duck typing."""
conditions = [hasattr(cell, "output_size"), hasattr(cell, "state_size"),
hasattr(cell, "zero_state"), callable(cell)]
return all(conditions)
原来 LSTMBlockFusedCell
没有 LSTMBlockCell
实现的 output_size
和 state_size
属性.
Turns out LSTMBlockFusedCell
doesn't have the output_size
and state_size
properties that LSTMBlockCell
implements.
这是一个错误,还是有一种方法可以使用我缺少的 LSTMBlockFusedCell
.
Is this a bug, or is there a way to use LSTMBlockFusedCell
that I'm missing.
推荐答案
LSTMBlockFusedCell
继承自 FusedRNNCell
而不是 RNNCell
,所以你不能使用标准 tf.nn.static_rnn
或 tf.nn.dynamic_rnn
,其中它们需要 RNNCell
实例(如您的错误消息所示).
LSTMBlockFusedCell
is inherited from FusedRNNCell
instead of RNNCell
, so you cannot use standard tf.nn.static_rnn
or tf.nn.dynamic_rnn
in which they require RNNCell
instance (as shown in your error message).
但是,在文档中,可以直接调用获取完整输出和状态的单元格.
However, in the documentation, you can directly call the cell to get the complete outputs and state.
inputs = tf.placeholder(tf.float32, [time_len, batch_size, input_size])
fused_rnn_cell = tf.contrib.rnn.LSTMBlockFusedCell(num_units)
outputs, state = fused_rnn_cell(inputs, dtype=tf.float32)
# outputs shape is (time_len, batch_size, num_units)
# state: LSTMStateTuple where c shape is (batch_size, num_units)
# and h shape is also (batch_size, num_units).
LSTMBlockFusedCell
对象调用 gen_lstm_ops.block_lstm
内部,这应该相当于一个普通的 LSTM 循环.
The LSTMBlockFusedCell
object calls gen_lstm_ops.block_lstm
internally, which should be equivalent to a normal LSTM loop.
另外,请注意任何 FusedRNNCell
实例的输入都应该是时间优先的,这可以通过在调用单元格之前转置张量来完成.
Also, notice that the inputs to any FusedRNNCell
instance should be time-major, this can be done by just transposing the tensor before calling the cell.
这篇关于无法在 Python TensorFlow 中用 LSTMBlockFusedCell 替换 LSTMBlockCell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!