Replacing LSTMBlockCell with LSTMBlockFusedCell throws a TypeError in static_rnn`. I'm using TensorFlow 1.2.0-rc1 compiled from source.
The full error message:
---------------------------------------------------------------------------
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
Code to reproduce:
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 looks like:
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)
Turns out LSTMBlockFusedCell doesn't have the output_size and state_size properties that LSTMBlockCell implements.
Is this a bug, or is there a way to use LSTMBlockFusedCell that I'm missing.
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).
The LSTMBlockFusedCell object calls gen_lstm_ops.block_lstm internally, which should be equivalent to a normal LSTM loop.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With