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.
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.
