Cannot load keras model with custom metric - keras

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.

Related

How to remove the pickling error while doing k-model cross validation using scikit learn through the keras library

This was the code for building the artificial neural network and the classifier. It was simple churn modelling for determining whether a customer will leave a bank or not.
#Building the ANN
import keras
from keras.models import Sequential
from keras.layers import Dense
#Initializing the ANN
classifier = Sequential()
#Adding input layer and hidden layer iinto ANN
classifier.add(Dense(6, kernel_initializer = 'glorot_uniform', activation = 'relu', input_shape =
(11,)))
#Adding second hidden layer
classifier.add(Dense(6, kernel_initializer = 'glorot_uniform', activation = 'relu'))
#Adding the output/final layer
classifier.add(Dense(1, kernel_initializer = 'glorot_uniform', activation = 'sigmoid'))
#Compiling the ANN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics=('accuracy'))
#Fitting the ANN on trainig set using fit method
classifier.fit(X_train, y_train, batch_size = 10, epochs = 100)
#Making prediction and analyzing the dataset
y_prediction = classifier.predict(X_test)
#Converting the probablities into definite results for model validation
y_prediction = (y_prediction > 0.5)
#Making confusion matrix for evaluating the resuts
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_prediction)
#Evaluating, improving and tuning the ANN
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from keras.models import Sequential
from keras.layers import Dense
def build_classifier():
classifier = Sequential()
classifier.add(Dense(6, kernel_initializer = 'glorot_uniform', activation = 'relu', input_shape =
(11,)))
classifier.add(Dense(6, kernel_initializer = 'glorot_uniform', activation = 'relu'))
classifier.add(Dense(1, kernel_initializer = 'glorot_uniform', activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics=('accuracy'))
return classifier
classifier = KerasClassifier(build_fn = build_classifier(), batch_size = 10, epochs = 100)
accuracies = cross_val_score(estimator = classifier, X = X_train, y = y_train, cv = 10, n_jobs = -1)
---
And this was the error
RemoteTraceback:
"""
Traceback (most recent call last):
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib\externals\loky\backend\queues.py", line 153, in _ feed
obj = dumps(obj, reducers=reducers)
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib\externals\loky\backend\reduction.py", line 271,
in dumps
dump(obj, buf, reducers=reducers, protocol=protocol)
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib\externals\loky\backend\reduction.py", line 264,
in dump
_LokyPickler(file, reducers=reducers, protocol=protocol).dump(obj)
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib\externals\cloudpickle\cloudpickle_fast.py",
line 563, in dump
return Pickler.dump(self, obj)
TypeError: cannot pickle 'weakref' object
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\BSNL\Documents\Deep_Learning_A_Z\Volume 1 - Supervised Deep Learning\Part 1 -
Artificial Neural Networks (ANN)\Section 4 - Building an ANN\ANN.py", line 78, in
accuracies = cross_val_score(estimator = classifier, X = X_train, y = y_train, cv = 10, n_jobs = -1)
File "C:\Users\BSNL\anaconda3\lib\site-packages\sklearn\utils\validation.py", line 72, in inner_f
return f(**kwargs)
File "C:\Users\BSNL\anaconda3\lib\site-packages\sklearn\model_selection_validation.py", line 401, in
cross_val_score
cv_results = cross_validate(estimator=estimator, X=X, y=y, groups=groups,
File "C:\Users\BSNL\anaconda3\lib\site-packages\sklearn\utils\validation.py", line 72, in inner_f
return f(**kwargs)
File "C:\Users\BSNL\anaconda3\lib\site-packages\sklearn\model_selection_validation.py", line 242, in
cross_validate
scores = parallel(
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib\parallel.py", line 1061, in call
self.retrieve()
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib\parallel.py", line 940, in retrieve
self._output.extend(job.get(timeout=self.timeout))
File "C:\Users\BSNL\anaconda3\lib\site-packages\joblib_parallel_backends.py", line 542, in
wrap_future_result
return future.result(timeout=timeout)
File "C:\Users\BSNL\anaconda3\lib\concurrent\futures_base.py", line 432, in result
return self.__get_result()
File "C:\Users\BSNL\anaconda3\lib\concurrent\futures_base.py", line 388, in __get_result
raise self._exception
PicklingError: Could not pickle the task to send it to the workers.
putting n_jobs = 1 worked because I had also did a mistake of putting brackets in Kerasclassifier's build_fn argument i.e. use build_classifier instead of build_classifier().

ValueError: An `initial_state` was passed that is not compatible with `cell.state_size`

i m trying to add a custom layer to my model but i m having this illogic error ,what do i need to change ?
if the code of the custom layer is needed let me know
it will mean the world to me if you help me understand what i m doing wrong.and how to fix it ?
from keras.models import Sequential , Model
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization
from keras.layers import Input ,Activation, Dense , Flatten ,RNN
import tensorflow as tf
from layers.se3 import SE3CompositeLayer # this is the layer that i want to add
batch_size = 500
seq = Sequential()
seq.add(ConvLSTM2D(filters=128, kernel_size=(3, 3),
batch_input_shape=(500,4,34, 17, 768),
padding='same', return_sequences=True,stateful=True,dropout=0.2))
seq.add(BatchNormalization())
seq.add(Activation('relu'))
seq.add(ConvLSTM2D(filters=32, kernel_size=(3, 3),padding='same',dropout=0.2))
seq.add(BatchNormalization())
seq.add(Activation('relu'))
output1 = Flatten()(seq.layers[11].output)
branch1= Dense(64,activation ='relu')(output1)
branch1= Dense(4)(branch1)
branch2= Dense(64,activation='relu')(output1)
branch2= Dense(3)(branch2)
output_conv_lstm =tf.concat([branch2,branch1] ,1)
output_conv_lstm = tf.expand_dims(output_conv_lstm , axis=0)
init_s=tf.placeholder_with_default(tf.eye(4, batch_shape=[batch_size]) , shape=(None, 4 ,4))
l_se3comp = SE3CompositeLayer()
se3_outputs, se3_state =keras.layers.RNN(cell=l_se3comp , dtype=tf.float32 ,unroll=True)(output_conv_lstm ,initial_state=init_s)
model = Model(inputs= seq.layers[0].input ,outputs=se3_outputs )
model.summary()
File "main.py", line 59, in <module>
se3_outputs, se3_state =keras.layers.RNN(cell=l_se3comp , dtype=tf.float32 ,unroll=True)(output_conv_lstm ,initial_state=init_s)
File "/home/ridha/.local/lib/python3.6/site-packages/keras/layers/recurrent.py", line 574, in __call__
return super(RNN, self).__call__(inputs, **kwargs)
File "/home/ridha/.local/lib/python3.6/site-packages/keras/engine/base_layer.py", line 431, in __call__
self.build(unpack_singleton(input_shapes))
File "/home/ridha/.local/lib/python3.6/site-packages/keras/layers/recurrent.py", line 508, in build
'{}'.format(self.state_spec, self.cell.state_size))
ValueError: An `initial_state` was passed that is not compatible with `cell.state_size`. Received `state_spec`=[InputSpec(shape=(None, 4, 4), ndim=3)]; however `cell.state_size` is (?, 4, 4) ```
Not really an answer but possibly a workaround: tensorflow initializers supposedly can be tensors or callables, but I've only every gotten callables work.
For example, if I wanted to initialize a kernel in an RNN as a 2D vector of all 7's,
kernel_initializer = tf.constant([7.,7.])
has never worked for me, but
init_state_getter = lambda shape, dtype: 7*np.ones(*shape)
...
kernel_initializer = init_state_getter
is ok.

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.

Using LSTM in Keras and tensorflow for time series predictions

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.

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'])

Resources