to custom RNN with LSTMcell

Viewed 243

Background: The LSTM API in Keras doesn't match my project, because the output hidden state of LSTM from the last timestep is used by another layer**(Single Source Attention and Multi Source Attention)** in the next timestep.The idea is from the paper: https://arxiv.org/abs/1711.10061. So I would like to custom a layer with LSTMCell which inherits keras.layer.Layer.

enter image description here

I would like to test my idea with the following code. But I have no idea how to set the states the LSTMCell needs. I have tried 3 kinds of cases:

  • tuple with two tensors (case 1)

  • a list with two tensors just one (case 2)

  • concatenated tensor. (case 3)

But the error still occurs.

case 1:



from keras.layers import RNN,LSTMCell,Input
import keras.backend as K
import keras 
import tensorflow as tf
class MinimalRNNCell(keras.layers.Layer):

    def __init__(self, units, state_size,**kwargs):
        self.units = units 
        self.state_size = state_size 
        self.cell = keras.layers.LSTMCell(self.units)
     
        super(MinimalRNNCell, self).__init__(**kwargs)

    def build(self, input_shape):
        pass
        

    def call(self, inputs, states):
      
        print(states)
        #states_0 = tf.reshape(states[0],(1,32))
        #states_1 = tf.reshape(states[1],(1,32))
        #states= tf.concat([states_0,states_1],0)


        h,new_state = self.cell([inputs,states])

        return h, [h,new_state]


cell = MinimalRNNCell(32,(32,32))
x = Input((None, 5))
layer = RNN(cell)
y = layer(x)

exit()
cells = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cells)
y = layer(x)

the error: ValueError: Layer lstm_cell_1 was called with an input that isn't a symbolic tensor. Received type: <class 'tuple'>. Full input: [<tf.Tensor 'rnn_1/strided_slice_1:0' shape=(None, 5) dtype=float32>, (<tf.Tensor 'rnn_1/Tile:0' shape=(None, 32) dtype=float32>, <tf.Tensor 'rnn_1/Tile_1:0' shape=(None, 32) dtype=float32>)]. All inputs to the layer should be tensors.

case2:

from keras.layers import RNN,LSTMCell,Input
import keras.backend as K
import keras 
import tensorflow as tf
class MinimalRNNCell(keras.layers.Layer):

    def __init__(self, units, state_size,**kwargs):
        self.units = units
        self.state_size = state_size 
        self.cell = keras.layers.LSTMCell(self.units)
     
        super(MinimalRNNCell, self).__init__(**kwargs)

    def build(self, input_shape):
        pass
        

    def call(self, inputs, states):
        print(states)
        #states_0 = tf.reshape(states[0],(1,32))
        #states_1 = tf.reshape(states[1],(1,32))
        #states= tf.concat([states_0,states_1],0)


        h,new_state = self.cell([inputs,[states[0],states[1]]])

        return h, [h,new_state]



cell = MinimalRNNCell(32,(32,32))
x = Input((None, 5))
layer = RNN(cell)
y = layer(x)


exit()
cells = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cells)
y = layer(x)

The error:

ValueError: Layer lstm_cell_1 was called with an input that isn't a symbolic tensor. Received type: <class 'list'>. Full input: [<tf.Tensor 'rnn_1/strided_slice_1:0' shape=(None, 5) dtype=float32>, [<tf.Tensor 'rnn_1/Tile:0' shape=(None, 32) dtype=float32>, <tf.Tensor 'rnn_1/Tile_1:0' shape=(None, 32) dtype=float32>]]. All inputs to the layer should be tensors.

case 3

from keras.layers import RNN,LSTMCell,Input
import keras.backend as K
import keras 
import tensorflow as tf
class MinimalRNNCell(keras.layers.Layer):

    def __init__(self, units, state_size,**kwargs):
        self.units = units # 输出32
        self.state_size = state_size # 状态也是64
        self.cell = keras.layers.LSTMCell(self.units)
     
        super(MinimalRNNCell, self).__init__(**kwargs)

    def build(self, input_shape):
        self.recurrent_kernel = self.add_weight(
            shape=(None, 64),
            initializer='uniform',
            name='recurrent_kernel')
        

    def call(self, inputs, states):
        # states 作为元组,列表,tensor输入,都会报错
        print(states)
        #states_0 = tf.reshape(states[0],(1,32))
        #states_1 = tf.reshape(states[1],(1,32))
        #states= tf.concat([states_0,states_1],0)


        h,new_state = self.cell([inputs,states])

        return h, [h,new_state]


cell = MinimalRNNCell(32,64)
x = Input((None, 5))
layer = RNN(cell)
y = layer(x)


cells = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cells)
y = layer(x)

The error:

ValueError: Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor.
0 Answers
Related