Saving Keras model fails after renaming layers - keras

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?

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

tensorflow model.load problems

I was working on tensorflow and tried to save and load a model. model resides in below file
model = keras.Sequential()
model.add(keras.layers.Dense(785, activation ='sigmoid' ))
model.add(keras.layers.Dense(25, activation = 'sigmoid'))
model.add(keras.layers.Dense(10, activation = 'sigmoid'))
model.compile(optimizer=tf.train.GradientDescentOptimizer(0.01),
loss='mse',
metrics=['mae'])
model.fit(X,Y,epochs = 20, callbacks=[history])
f = h5py.File(r'C:\Users\akash\Desktop\Big Data\Model\model1', "w")
tf.keras.models.save_model(
model,
f,
overwrite=True,
include_optimizer=True
)
and my load file is as below
model1 = tf.keras.models.load_model(
r'C:\Users\akash\Desktop\Big Data\Model\model1',
custom_objects=None,
compile=True
)
model1.compile(optimizer=tf.train.GradientDescentOptimizer(0.01),
loss='mse',
metrics=['mae'])
I had to compile my model again as tensorflow requires you to do so and does not allow optimisers to be saved
and due to this im getting the below error
Using TensorFlow backend.
WARNING:tensorflow:No training configuration found in save file: the model was *not* compiled. Compile it manually.
Traceback (most recent call last):
File "C:/Users/akash/Desktop/Big Data/scripts/load_model.py", line 21, in <module>
metrics=['mae'])
File "C:\Python\lib\site-packages\tensorflow\python\training\checkpointable\base.py", line 426, in _method_wrapper
method(self, *args, **kwargs)
File "C:\Python\lib\site-packages\tensorflow\python\keras\engine\training.py", line 525, in compile
metrics, self.output_names)
AttributeError: 'Sequential' object has no attribute 'output_names'
Maybe this helps you:
# MLP for Pima Indians Dataset Serialize to JSON and HDF5
from keras.models import Sequential
from keras.layers import Dense
from keras.models import model_from_json
import numpy
import os
# fix random seed for reproducibility
numpy.random.seed(7)
# load pima indians dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
# serialize model to JSON
model_json = model.to_json()
with open("model.json", "w") as json_file:
json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("model.h5")
print("Saved model to disk")
# later...
# load json and create model
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# load weights into new model
loaded_model.load_weights("model.h5")
print("Loaded model from disk")
# evaluate loaded model on test data
loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
score = loaded_model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))

Keras fit_generator raise You must compile your model before using it Error

I try to build a CNN + LSTM model by Keras to train a model for video classification task. Firstly, A simple model was built and trained with mock data, 'fit()' api, also it works!
But actually, what is used to train this model is a video dataset, it's so big that can't be loaded into memory. so I need a generator, in this place, I also write a mock generator which generate data with shape same as mock data method. Also, fit_generator API replaces fit.
When I run train_gen function, I get following error:
File "lstm.py", line 48, in <module>
train_gen()
File "lstm.py", line 45, in train_gen
model.fit_generator(data_generator.mock_generator(batch_size=32, num_classes=16), steps_per_epoch=1000, epochs=20)
File "/usr/local/lib/python2.7/dist-packages/keras/legacy/interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1415, in fit_generator
initial_epoch=initial_epoch)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training_generator.py", line 39, in fit_generator
model._make_train_function()
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 485, in _make_train_function
raise RuntimeError('You must compile your model before using it.')
RuntimeError: You must compile your model before using it.
I tried to solve this problem by searching in stack overflow and google, and do not find exact solution. There are some similar questions can be solved by specifying LSTM input_shape and output size, or add model.compile().
The following snippet code is runnable, and completely same as that mentioned above.
import keras
from keras.models import Sequential
from keras.layers import Input, Embedding, LSTM, Dense, Reshape
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.layers.normalization import BatchNormalization
from keras.layers.wrappers import Bidirectional
from keras.optimizers import Adam
import numpy as np
import os, random
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # see issue #152
os.environ["CUDA_VISIBLE_DEVICES"] = ""
use_dropout = True
metrics = ['accuracy']
#mock data generator
def mock_generator(batch_size, input_length, input_dims, num_classes=16):
while True:
yield np.random.random((batch_size, input_length, input_dims)), keras.utils.to_categorical(np.random.randint(num_classes, size=(batch_size, 1)), num_classes=num_classes)
#mock data with shape as data generator
def mock_data(batch_size, input_length, input_dims, num_classes=16):
if True:
return np.random.random((batch_size, input_length, input_dims)), keras.utils.to_categorical(np.random.randint(num_classes, size=(batch_size, 1)), num_classes=num_classes)
#construct model, lstm units is fixed
def bi_lstm(input_shape, num_classes=16):
model = Sequential()
model.add(Bidirectional(LSTM(100, return_sequences=True, activation='relu', input_shape=input_shape), merge_mode='concat'))
model.add(Bidirectional(LSTM(100, activation='relu', input_shape=(input_shape[0],100), return_sequences=False), merge_mode='concat'))
if use_dropout:
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(BatchNormalization())
model.add(Activation('softmax'))
optimizer = Adam(lr=1e-5, decay=1e-6)
model.compile(loss='categorical_crossentropy', optimizer=optimizer,
metrics=metrics)
return model
#fit api run successfully
def train():
input_length=10
input_dims=128
num_classes=10
model = bi_lstm((input_length, input_dims), num_classes)
x_train, y_train = mock_data(32, input_length, input_dims, num_classes)
model.fit(x_train, y_train, epochs=20, batch_size=32)
#fit_generator api raise error!
def train_gen():
input_length=10
input_dims=128
num_classes=10
model = bi_lstm((input_length, input_dims), num_classes)
generator = mock_generator(32, input_length, input_dims, num_classes)
model.fit_generator(generator, steps_per_epoch=1000, epochs=20)
#test mock generator function
def test_mock_gen():
result = mock_generator(32,10,128,16)
for i in range(2):
x, y = result.next()
print x.shape
print y.shape
if __name__ == '__main__':
train()
train_gen()
#test_mock_gen()
The error you are getting couldn't be more explicit: model has been declared as a local object on the train() function and is not know by the function train_gen(). Define your model as a global variable (ex. in main) and it will work.

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.

Loading a pre trained Keras model and predicting

I've cobbled together a simple neural network using some Keras examples, on the basic Kaggle Cat vs Dog data (https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/data). I was able to train and save a model using
model.fit_generator(
#train_generator,
#samples_per_epoch=2000,
#nb_epoch=50,
#validation_data=validation_generator,
#nb_val_samples=800)
model.save('first_model.h5')
But when I try loading the model to predict, I get
Traceback (most recent call last):
File "/Users/me/PycharmProjects/CatVsDog/SampleML.py", line 48, in <module>
print(saved_model.predict_generator(test_generator, 12500))
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/keras/models.py", line 1012, in predict_generator
pickle_safe=pickle_safe)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/keras/engine/training.py", line 1763, in predict_generator
outs = self.predict_on_batch(x)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/keras/engine/training.py", line 1371, in predict_on_batch
self.internal_input_shapes)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/keras/engine/training.py", line 85, in standardize_input_data
'Found: ' + str(data)[:200] + '...')
TypeError: Error when checking : data should be a Numpy array, or list/dict of Numpy arrays. Found: None...
Exception ignored in: <bound method Session.__del__ of <tensorflow.python.client.session.Session object at 0x10c7586d8>>
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/tensorflow/python/client/session.py", line 581, in __del__
UnboundLocalError: local variable 'status' referenced before assignment
Here's where the images are saved in my PyCharm solution. There are 1-12500 .jpg files in the Test directory, 11500 labeled .jpgs in each of the Training set cat and dog directories, and 1000 labeled .jpgs in each of the validate directories.
And here's my code
from __future__ import print_function
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
'train',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
'validate',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
test_generator = train_datagen.flow_from_directory(
'test',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
nb_filters = 32
kernel_size = (3,3)
pool_size = (2, 2)
nb_classes = 2
input_shape = (64, 64, 3)
saved_model = load_model('first_model.h5')
score = saved_model.evaluate_generator(validation_generator, 2000)
print('Test score:', score[0])
print('Test accuracy:', score[1])
print(saved_model.predict_generator(test_generator, 12500))
I believe that what you feed to the predict_generator isn't in the right format.
When you predict values, in opposition with training and evaluation, you don't want to feed the labels.
Therefore I would try to change your test_generator to this :
test_generator = train_datagen.flow_from_directory(
'test',
target_size=(64, 64),
batch_size=32,
#This will not output the targets.
class_mode=None)
You can find documentation about the ImageDataGenerator here.

Resources