Using LSTM in Keras and tensorflow for time series predictions - python-3.x

I want to define a LSTM layers using tensorflow in keras. The code as following:
model = Sequential()
inputs = Input(shape=(time_steps, 1))
cell = tf.nn.rnn_cell.LSTMCell(n_neurons)
multi_cell = tf.nn.rnn_cell.MultiRNNCell([cell] * n_layers)
lstm_outputs, states = tf.nn.dynamic_rnn(multi_cell, inputs, dtype=tf.float32)
outputs = TimeDistributed(Dense(1))(lstm_outputs)
model = Model(inputs=inputs, outputs=outputs)
adam = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(loss='mean_squared_error', optimizer=adam)
print(model.summary())
when running, an error occurred:
Using TensorFlow backend.
Traceback (most recent call last):
File "/Users/zhjmdcjk/Desktop/Untitled.py", line 81, in <module>
model = Model(inputs=inputs, outputs=outputs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/topology.py", line 1734, in __init__
build_map_of_graph(x, finished_nodes, nodes_in_progress)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/topology.py", line 1724, in build_map_of_graph
layer, node_index, tensor_index)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/topology.py", line 1695, in build_map_of_graph
layer, node_index, tensor_index = tensor._keras_history
AttributeError: 'Tensor' object has no attribute '_keras_history'
I am not clear about these, can anyone give me some advice. Thanks a lot!

Is there any particular reason you're using Tensorflow's LSTM in Keras? You can directly use Keras LSTM layers.
inputs = Input(shape=(time_steps, 1))
lstm1 = LSTM(n_neurons, return_sequences=True)(inputs)
lstm_outputs = LSTM(n_neurons, return_sequences=True)(lstm1)
outputs = TimeDistributed(Dense(1))(lstm_outputs)
model = Model(inputs=inputs, outputs=outputs)
Also, you don't need to use model = Sequential() in case of Keras' functional API.

Related

Keras Flatten layer in Functional API?

model = Sequential()
model.add(Flatten(input_shape=(1,) + (52,)))
model.add(Dense(100))
model.add(Activation('relu'))
model.add(Dense(2))
model.add(Activation('linear'))
print(model.summary())
I want to change this keras code in sequential version to same code with functional version like the following.
input = Input(shape=(1,) + (52,))
i = Flatten()(input)
h = Dense(100, activation='relu')(i)
o = Dense(2, activation='linear')(h)
model = Model(inputs=i, outputs=o)
model.summary()
But it got error
File "C:\Users\SDS\Anaconda3\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\Users\SDS\Anaconda3\lib\site-packages\keras\engine\network.py", line 93, in __init__
self._init_graph_network(*args, **kwargs)
File "C:\Users\SDS\Anaconda3\lib\site-packages\keras\engine\network.py", line 237, in _init_graph_network
self.inputs, self.outputs)
File "C:\Users\SDS\Anaconda3\lib\site-packages\keras\engine\network.py", line 1430, in _map_graph_network
str(layers_with_complete_input))
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_1:0", shape=(?, 1, 52), dtype=float32) at layer "input_1". The following previous layers were accessed without issue: []
Your model definition is incorrect, the inputs parameter of Model should go to your Input layer, like this:
input = Input(shape=(1,) + (52,))
i = Flatten()(input)
h = Dense(100, activation='relu')(i)
o = Dense(2, activation='linear')(h)
model = Model(inputs=inputs, outputs=o)
I believe you cannot put any tensor other than the Input layer as input to a model.
The input for model should be input layer(first layer without any dense layer).
So it should be like :
model = Model(inputs=input, outputs=o)

Unable to load keras model with lambda function using a custom distance function

I'm trying to build a system to check sentence similarities using a siamese LSTM model using Manhattan distance as the distance function while merging two layers.
I'm using the code found in this article
https://medium.com/mlreview/implementing-malstm-on-kaggles-quora-question-pairs-competition-8b31b0b16a07
The issue is that after I've built and saved the model in a json file I'm unable to load the model as an error gets thrown saying
name 'exponent_neg_manhattan_distance' is not defined
Here's the code:
# Model variables
n_hidden = 50
gradient_clipping_norm = 1.25
batch_size = 64
n_epoch = 5
def exponent_neg_manhattan_distance(left, right):
''' Helper function for the similarity estimate of the LSTMs outputs'''
return K.exp(-K.sum(K.abs(left-right), axis=1, keepdims=True))
# The visible layer
left_input = Input(shape=(max_seq_length,), dtype='int32')
right_input = Input(shape=(max_seq_length,), dtype='int32')
embedding_layer = Embedding(len(embeddings), embedding_dim, weights=[embeddings], input_length=max_seq_length, trainable=False)
# Embedded version of the inputs
encoded_left = embedding_layer(left_input)
encoded_right = embedding_layer(right_input)
# Since this is a siamese network, both sides share the same LSTM
shared_lstm = LSTM(n_hidden)
left_output = shared_lstm(encoded_left)
right_output = shared_lstm(encoded_right)
# Calculates the distance as defined by the MaLSTM model
malstm_distance = Merge(mode=lambda x: exponent_neg_manhattan_distance(x[0], x[1]), output_shape=lambda x: (x[0][0], 1))([left_output, right_output])
# Pack it all up into a model
malstm = Model([left_input, right_input], [malstm_distance])
# Adadelta optimizer, with gradient clipping by norm
optimizer = Adadelta(clipnorm=gradient_clipping_norm)
malstm.compile(loss='mean_squared_error', optimizer=optimizer, metrics=['accuracy'])
# Start training
training_start_time = time()
malstm_trained = malstm.fit([X_train['left'], X_train['right']], Y_train, batch_size=batch_size, nb_epoch=n_epoch,
validation_data=([X_validation['left'], X_validation['right']], Y_validation))
print("Training time finished.\n{} epochs in {}".format(n_epoch, datetime.timedelta(seconds=time()-training_start_time)))
malstm.save('malstm.h5')
model_json = malstm.to_json()
with open ('malstm.json', 'w') as file:
file.write(model_json)
malstm.save_weights('malst_w.h5')
Now when I try to load the model I get the following error:
model = model_from_json(open('malstm.json').read(), custom_objects = {"exponent_neg_manhattan_distance":exponent_neg_manhattan_distance})
C:\Users\archi\Miniconda3\lib\site-packages\keras\engine\topology.py:1271: UserWarning: The `Merge` layer is deprecated and will be removed after 08/2017. Use instead layers from `keras.layers.merge`, e.g. `add`, `concatenate`, etc.
return cls(**config)
Traceback (most recent call last):
File "<ipython-input-12-4c72a4db6c29>", line 1, in <module>
model = model_from_json(open('malstm.json').read(), custom_objects = {"exponent_neg_manhattan_distance":exponent_neg_manhattan_distance})
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\models.py", line 349, in model_from_json
return layer_module.deserialize(config, custom_objects=custom_objects)
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\layers\__init__.py", line 55, in deserialize
printable_module_name='layer')
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\utils\generic_utils.py", line 144, in deserialize_keras_object
list(custom_objects.items())))
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\engine\topology.py", line 2524, in from_config
process_node(layer, node_data)
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\engine\topology.py", line 2483, in process_node
layer(input_tensors, **kwargs)
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\engine\topology.py", line 619, in __call__
output = self.call(inputs, **kwargs)
File "C:\Users\archi\Miniconda3\lib\site-packages\keras\legacy\layers.py", line 209, in call
return self.mode(inputs, **arguments)
File "<ipython-input-19-913812c640b3>", line 28, in <lambda>
NameError: name 'exponent_neg_manhattan_distance' is not defined
I've searched online and the issue is probably because of the use of the lambda function. Is there any way I could load this model because it took a crazy amount of time to train. Any help would be appreciated!
First save your model with model.save
Then load with with custom objects
model.save("model_path")
from keras.models import load_model
# Returns a compiled model identical to the previous one model =
load_model('model_path',
custom_objects={
'RAdam':RAdam,
'exponent_neg_manhattan_distance':exponent_neg_manhattan_distance})
Converting comment into answer: you can salvage the weights of the network if you just create it yourself in code again. The error is about creating the network from JSON, but let's follow from:
# ...
# Pack it all up into a model
malstm = Model([left_input, right_input], [malstm_distance])
# ... you don't need compile for only predict
# ... skip training and model saving
# malstm.save_weights('malst_w.h5')
malstm.load_weights('malst_w.h5')
malstm.predict(...)
now, the weights are loaded into the existing model which you created in code.

Saving Keras model fails after renaming layers

I have a problem with renaming layers. Below is the simplest example illustrating the problem:
from keras.layers import Dense, Conv2D, Flatten, Input
from keras.models import Model
inputs = Input(shape=(784,))
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)
# This creates a model that includes
# the Input layer and three Dense layers
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
print(model.summary())
for i, layer in enumerate(model.layers):
layer.name = 'layer' + str(i)
print(model.summary())
model.save('temp')
It fails with the message:
Traceback (most recent call last):
File "scripts/save_load.py", line 24, in <module>
model.save('temp')
File "/lib/python3.6/site-packages/keras/engine/topology.py", line 2416, in save
save_model(self, filepath, overwrite)
File "/lib/python3.6/site-packages/keras/models.py", line 101, in save_model
'config': model.get_config()
File "/lib/python3.6/site-packages/keras/engine/topology.py", line 2281, in get_config
new_node_index = node_conversion_map[node_key]
KeyError: 'layer0_ib-0'
What am I doing wrong?
I know I can pass names to the layer constructor, it seems not to fail in this case, but is there any chance to improve my solution?

Strange keyword 'metirics' in TypeError message - Keras

I'm using KERAS (2.0.8) on python3.5 on Windows 64bit PC.
I'm trying to utilize vgg16 with my own full-connect layers.
But, my model.fit_generator throws TypeError with strange keyword
TypeError: run() got an unexpected keyword argument 'metirics'
Of course, I never use 'metirics' in my code...
Here is my code.
def go_vgg():
train_datagen = ImageDataGenerator(rescale=1.0 /255)
validation_datagen=ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(train_data_dir,
target_size=(image_size,image_size),
batch_size=batch_size,
save_to_dir=check_dir,
save_format='png',
shuffle = False,
class_mode = 'binary')
validation_generator = validation_datagen.flow_from_directory(validation_data_dir,
target_size=(image_size,image_size),
batch_size=batch_size,
save_to_dir=check_dir,
save_format='png',
shuffle=False,
class_mode = 'binary')
bmodel = VGG16(include_top=False, weights='imagenet', input_tensor=None, input_shape=(image_size,image_size,3))
bmodel.summary()
smodel = Sequential()
smodel.add(Flatten(input_shape=(7,7,512)) )
smodel.summary()
smodel.add(Dense(256, activation='relu'))
smodel.add(Dropout(0.5))
smodel.add(Dense(1, activation = 'sigmoid'))
model = Model(input=bmodel.input, outputs = smodel(bmodel.output))
for layer in model.layers[:15]:
layer.trainable = False
model.compile(loss='binary_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metirics = ['accuracy'])
history =model.fit_generator(train_generator, steps_per_epoch=2000,
epochs = np_epoch)
The summary result is as follows (I mostely omitted bmodel.summary())
____________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 224, 224, 3) 0
.
.
.
Epoch 1/2
Traceback (most recent call last):
File "test4.py", line 94, in <module>
main()
File "test4.py", line 86, in main
go_vgg()
File "test4.py", line 80, in go_vgg
epochs = np_epoch)
File "D:\python\lib\site-packages\keras\legacy\interfaces.py", line 87, in wra
pper
return func(*args, **kwargs)
File "D:\python\lib\site-packages\keras\engine\training.py", line 2042, in fit
_generator
class_weight=class_weight)
File "D:\python\lib\site-packages\keras\engine\training.py", line 1762, in tra
in_on_batch
outputs = self.train_function(ins)
File "D:\python\lib\site-packages\keras\backend\tensorflow_backend.py", line 2
273, in __call__
**self.session_kwargs)
TypeError: run() got an unexpected keyword argument 'metirics'
I have no idea where this 'metirics' comes from.
Any help to solve this error would be highly appreciated!
Of course you are using such a keyword, right here:
model.compile(loss='binary_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metirics = ['accuracy'])
The problem is that you misspelled metrics as metirics. Just correct it to metrics:
model.compile(loss='binary_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics = ['accuracy'])

Cannot load keras model with custom metric

Hi I am trying to make a super resolution model on keras.
I am referring to https://github.com/titu1994/Image-Super-Resolution.
But after I compile and save a new model, when I load the model, the metric error is occurred
Traceback (most recent call last):
File "autoencoder2.py", line 56, in <module>
load_model("./ani.model")
File "/home/simmani91/anaconda2/lib/python2.7/site-packages/keras/models.py", line 155, in load_model
sample_weight_mode=sample_weight_mode)
File "/home/simmani91/anaconda2/lib/python2.7/site-packages/keras/engine/training.py", line 665, in compile
metric_fn = metrics_module.get(metric)
File "/home/simmani91/anaconda2/lib/python2.7/site-packages/keras/metrics.py", line 84, in get
return get_from_module(identifier, globals(), 'metric')
File "/home/simmani91/anaconda2/lib/python2.7/site-packages/keras/utils/generic_utils.py", line 14, in get_from_module
str(identifier))
Exception: Invalid metric: PSNRLoss
and here is my code for metric(PSNRLoss), create model, execution
def PSNRLoss(y_true, y_pred):
return -10. * np.log10(K.mean(K.square(y_pred - y_true)))
def create_model():
shape = (360,640,3)
input_img = Input(shape=shape)
x = Convolution2D(64, shape[0],shape[1], activation='relu', border_mode='same', name='level1')(input_img)
x = Convolution2D(32,shape[0],shape[1], activation='relu', border_mode='same', name='level2')(x)
out = Convolution2D(3, shape[0],shape[1], border_mode='same', name='output')(x)
model = Model(input_img, out)
#model.compile(optimizer='adadelta', loss='binary_crossentropy')
adam = optimizers.Adam(lr=1e-3)
model.compile(optimizer=adam, loss='mse', metrics=[PSNRLoss])
return model
path = "./picture/"
if not os.path.exists("./ani.model"):
ani_model = create_model()
ani_model.save("./ani.model")
load_model("./ani.model")
Is there any way to load a model with PSNR metric?
Thank you for reading.
Load the model with load_model("ani.model", custom_objects={"PSNRLoss": PSNRLoss}) instead.

Resources