How to deploy cnn file - tensorflow

I have trained a model using this code...
https://github.com/shantanuo/pandas_examples/blob/master/tensorflow/simages_train_waiting.ipynb
My file is ready, but how do I deploy it?
https://s3.ap-south-1.amazonaws.com/studentimages162a/cnn.h5
I tried to use hosted solution panini.ai but it does not accept h5 files. I tried to convert it to csv but that did not work. I also tried to use flask
https://github.com/mtobeiyf/keras-flask-deploy-webapp
I got this error while trying to run the docker container...
# docker run -v /tmp/:/tmp/ -p 5000:5000 keras_flask_app
Using TensorFlow backend.
Traceback (most recent call last):
File "app.py", line 26, in <module>
model = load_model(MODEL_PATH)
File "/usr/local/lib/python2.7/site-packages/keras/engine/saving.py", line 419, in load_model
model = _deserialize_model(f, custom_objects, compile)
File "/usr/local/lib/python2.7/site-packages/keras/engine/saving.py", line 221, in _deserialize_model
model_config = f['model_config']
File "/usr/local/lib/python2.7/site-packages/keras/utils/io_utils.py", line 302, in __getitem__
raise ValueError('Cannot create group in read only mode.')
ValueError: Cannot create group in read only mode.
In other words how to use cnn.h5 file?
I am trying to use this code...
from keras.models import Sequential
from keras.layers import Dense, Activation
def build_model():
model = Sequential()
model.add(Dense(output_dim=64, input_dim=100))
model.add(Activation("relu"))
model.add(Dense(output_dim=10))
model.add(Activation("softmax"))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
return model
model2 = build_model()
model2.load_weights('cnn.h5')
And got the error:
ValueError: You are trying to load a weight file containing 4 layers into a model with 2 layers.

Concerning the first error, I the problem is that the flask app tries to load the complete model (i.e. with configuration):
model = load_model(MODEL_PATH)
whereas after the training you save only weights:
cnn.save_weights('cnn.h5')
Try to use cnn.save('cnn.h5') instead.
In the second case, your model definition does not match the trained model. Indeed, it is a completely different model with no Convolution layers at all. The corresponding model definition would be:
def build_model():
model = Sequential()
model.add(Conv2D(filters=32,
kernel_size=(2,2),
strides=(1,1),
padding='same',
input_shape=(IMG_SIZE,IMG_SIZE,NB_CHANNELS),
data_format='channels_last'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2),
strides=2))
model.add(Dropout(0.4))
model.add(Conv2D(filters=64,
kernel_size=(2,2),
strides=(1,1),
padding='valid'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2),
strides=2))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
return model

You can load the model in following way:
from tensorflow.keras.models import load_model
model = load_model('cnn.h5')
The training/test data can be loaded with the following code:
import h5py
import numpy as np
hf = h5py.File('cnn.h5', 'r')

Your trained model and the model you are trying to load differ.
Replace
cnn = Sequential()
with
cnn = build_model()

Related

trying to add a layer for transfer learning, getting ValueError: A merge layer should be called on a list of inputs [duplicate]

I am trying to do a transfer learning; for that purpose I want to remove the last two layers of the neural network and add another two layers. This is an example code which also output the same error.
from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model
in_img = Input(shape=(3, 32, 32))
x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
x = Activation('relu', name='relu_conv2')(x)
x = GlobalAveragePooling2D()(x)
o = Activation('softmax', name='loss')(x)
model = Model(input=in_img, output=[o])
model.compile(loss="categorical_crossentropy", optimizer="adam")
#model.load_weights('model_weights.h5', by_name=True)
model.summary()
model.layers.pop()
model.layers.pop()
model.summary()
model.add(MaxPooling2D())
model.add(Activation('sigmoid', name='loss'))
I removed the layer using pop() but when I tried to add its outputting this error
AttributeError: 'Model' object has no attribute 'add'
I know the most probable reason for the error is improper use of model.add(). what other syntax should I use?
EDIT:
I tried to remove/add layers in keras but its not allowing it to be added after loading external weights.
from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model
in_img = Input(shape=(3, 32, 32))
def gen_model():
in_img = Input(shape=(3, 32, 32))
x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
x = Activation('relu', name='relu_conv2')(x)
x = GlobalAveragePooling2D()(x)
o = Activation('softmax', name='loss')(x)
model = Model(input=in_img, output=[o])
return model
#parent model
model=gen_model()
model.compile(loss="categorical_crossentropy", optimizer="adam")
model.summary()
#saving model weights
model.save('model_weights.h5')
#loading weights to second model
model2=gen_model()
model2.compile(loss="categorical_crossentropy", optimizer="adam")
model2.load_weights('model_weights.h5', by_name=True)
model2.layers.pop()
model2.layers.pop()
model2.summary()
#editing layers in the second model and saving as third model
x = MaxPooling2D()(model2.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)
model3 = Model(input=in_img, output=[o])
its showing this error
RuntimeError: Graph disconnected: cannot obtain value for tensor input_4 at layer "input_4". The following previous layers were accessed without issue: []
You can take the output of the last model and create a new model. The lower layers remains the same.
model.summary()
model.layers.pop()
model.layers.pop()
model.summary()
x = MaxPooling2D()(model.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)
model2 = Model(inputs=in_img, outputs=[o])
model2.summary()
Check How to use models from keras.applications for transfer learnig?
Update on Edit:
The new error is because you are trying to create the new model on global in_img which is actually not used in the previous model creation.. there you are actually defining a local in_img. So the global in_img is obviously not connected to the upper layers in the symbolic graph. And it has nothing to do with loading weights.
To better resolve this problem you should instead use model.input to reference to the input.
model3 = Model(input=model2.input, output=[o])
Another way to do it
from keras.models import Model
layer_name = 'relu_conv2'
model2= Model(inputs=model1.input, outputs=model1.get_layer(layer_name).output)
As of Keras 2.3.1 and TensorFlow 2.0, model.layers.pop() is not working as intended (see issue here). They suggested two options to do this.
One option is to recreate the model and copy the layers. For instance, if you want to remove the last layer and add another one, you can do:
model = Sequential()
for layer in source_model.layers[:-1]: # go through until last layer
model.add(layer)
model.add(Dense(3, activation='softmax'))
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy')
Another option is to use the functional model:
predictions = Dense(3, activation='softmax')(source_model.layers[-2].output)
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='adam', loss='categorical_crossentropy')
model.layers[-1].output means the last layer's output which is the final output, so in your code, you actually didn't remove any layers, you added another head/path.
An alternative to Wesam Na's answer, if you don't know the layer names you can simply cut off the last layer via:
from keras.models import Model
model2= Model(inputs=model1.input, outputs=model1.layers[-2].output)

Tensorboard callback doesn't work when calling

I am new to Tensorflow and Keras. I just started beginning my Deep learning Journey. I installed Tensorflow 2.4.3 as well as Keras. I was learning Tensorboard. I created a model for imdb dataset as follows
import tensorflow as tf
import keras
from tensorflow.keras import *
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing import sequence
## model making
max_features = 2000
max_len = 500
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
x_test = sequence.pad_sequences(x_test, maxlen=max_len)
model = models.Sequential()
model.add(layers.Embedding(max_features, 128,
input_length=max_len,
name='embed'))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.MaxPooling1D(5))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(1))
model.summary()
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
I used the tensorboard callback here.
callbacks = [
keras.callbacks.TensorBoard(
log_dir='my_log_dir',
histogram_freq=1,
embeddings_freq=1,
)
]
history = model.fit(x_train, y_train,
epochs=3,
batch_size=128,
validation_split=0.2,
callbacks=callbacks)
Then I got the following warning.
C:\Users\ktripat\Anaconda3\envs\tf2\lib\site-packages\keras\callbacks\tensorboard_v2.py:102: UserWarning: The TensorBoard callback does not support embeddings display when using TensorFlow 2.0. Embeddings-related arguments are ignored.
warnings.warn('The TensorBoard callback does not support.'
Please find any solution if you guys have any. Thank you in advance!
You will need to follow this guide.
It describes how to save the weights of your embedding layer in a way that you can visualize it in TensorBoard:
# Set up a logs directory, so Tensorboard knows where to look for files.
log_dir='/logs/imdb-example/'
if not os.path.exists(log_dir):
os.makedirs(log_dir)
# Save Labels separately on a line-by-line manner.
with open(os.path.join(log_dir, 'metadata.tsv'), "w") as f:
for subwords in encoder.subwords:
f.write("{}\n".format(subwords))
# Fill in the rest of the labels with "unknown".
for unknown in range(1, encoder.vocab_size - len(encoder.subwords)):
f.write("unknown #{}\n".format(unknown))
# Save the weights we want to analyze as a variable. Note that the first
# value represents any unknown word, which is not in the metadata, here
# we will remove this value.
weights = tf.Variable(model.layers[0].get_weights()[0][1:])
# Create a checkpoint from embedding, the filename and key are the
# name of the tensor.
checkpoint = tf.train.Checkpoint(embedding=weights)
checkpoint.save(os.path.join(log_dir, "embedding.ckpt"))
# Set up config.
config = projector.ProjectorConfig()
embedding = config.embeddings.add()
# The name of the tensor will be suffixed by `/.ATTRIBUTES/VARIABLE_VALUE`.
embedding.tensor_name = "embedding/.ATTRIBUTES/VARIABLE_VALUE"
embedding.metadata_path = 'metadata.tsv'
projector.visualize_embeddings(log_dir, config)
If you want to visualize during training, you can call this code in a save callback during training every X episodes using this.

How to solve a type error while using RAdam optimizer?

I am building a neural network using keras and tensorflow and I get a error at this place
def create_model():
model = Sequential()
model.add(Dense(4, input_dim=2, kernel_initializer='normal', activation='tanh'))
model.add(Dense(6, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer=RAdam(learning_rate), metrics=['accuracy'])
return model
model = create_model()
And I get the following error when I run my code in jupyter notebook,
TypeError Traceback (most recent call last)
<ipython-input-14-2358feb9246f> in <module>
1 # make a shallow neural network
----> 2 model = create_model()
3 model.summary()
<ipython-input-13-7c6ab8b2130e> in create_model()
10
11 # Compile model
---> 12 model.compile(loss='binary_crossentropy', optimizer=RAdam(learning_rate), metrics=['accuracy'])
13 return model
~\anaconda3\envs\tf\lib\site-packages\keras_radam\optimizers.py in __init__(self, learning_rate, beta_1, beta_2, epsilon, decay, weight_decay, amsgrad, total_steps, warmup_proportion, min_lr, **kwargs)
32 total_steps=0, warmup_proportion=0.1, min_lr=0., **kwargs):
33 learning_rate = kwargs.pop('learning_rate', learning_rate)
---> 34 super(RAdam, self).__init__(**kwargs)
35 with K.name_scope(self.__class__.__name__):
36 self.iterations = K.variable(0, dtype='int64', name='iterations')
TypeError: __init__() missing 1 required positional argument: 'name'
And these are the imports I have used for my code to run. I think I have most of the codes imported to build a shallow neural network
import numpy as np
import keras
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense
from keras import backend as K
from keras.wrappers.scikit_learn import KerasClassifier
from keras_radam import RAdam
For others who may be looking for another solution.
RAdam is not in tensorflow.keras.optimizers and neither in keras by default, but in tensorflow-addons package, which is a better alternative (IMHO) than the external keras_radam library, considerably less prone to errors.
What you are looking for is here: https://www.tensorflow.org/addons/api_docs/python/tfa/optimizers/RectifiedAdam
#pip install tensorflow-addons
import tensorflow_addons as tfa
optimizer = tfa.optimizers.RectifiedAdam(lr=1e-3)
I was able to reproduce your problem. It happened when you have tf. keras but you load keras-radam with old keras. But this implementation supports both versions of keras or tf. keras. To use it with the new version, as also mentioned here, all you need to do as follows:
import os
os.environ['TF_KERAS']='1'
from keras_radam import RAdam
The package will choose the tf. keras compatible version of RAdam()
from .backend import TF_KERAS
__all__ = ['RAdam']
if TF_KERAS:
from .optimizer_v2 import RAdam
else:
from .optimizers import
So, RAdam() will be imported from this script. But there is another issue. In the very latest version of tf, the following import has been updated
# from
from tensorflow.python import os, math_ops, state_ops, control_flow_ops
# to
from tensorflow.python.ops import math_ops, state_ops, control_flow_ops
From this point, you need to modify this import from the source script and it will solve this issue. Just modify the source script by replacing the above imports.
from keras import Sequential
from keras.layers import Dense
def create_model():
model = Sequential()
model.add(Dense(4, input_dim=2, kernel_initializer='normal', activation='tanh'))
model.add(Dense(6, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer=RAdam(learning_rate),
metrics=['accuracy'])
return model
model = create_model()

Create keras model from another trained model

I am trying to create a new keras model from another trained keras model
Sample Code for model training referred from:
#TF version 2.2.0
from tensorflow.python.keras import models, layers
from tensorflow.python.keras.models import Sequential
from tensorflow.python import keras
import tensorflow as tf
from tensorflow.python.keras.layers import Dense
from tensorflow.keras.datasets import boston_housing
(x_train,y_train), (x_test,y_test) = boston_housing.load_data()
model = Sequential()
model.add(Dense(2, activation='relu', input_shape=(13,)))
model.add(Dense(1, activation='softmax'))
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(x_train, y_train,batch_size= 64,epochs= 1,validation_split=0.2)
Saving the model as json
json_obj = model.to_json()
new_model = keras.models.model_from_json(json_obj)
But after creating the new_model the weights are different:
model.get_weights() != new_model.get_weights()
This is the same case if I create new_model using from_config(). The question is, shouldn't the weight be the same for both model and new_model as I am creating new_model from model or my understanding is wrong? Any suggestions are helpful
to_json doesn't save the model's weights, but only the architecture.
Check here: to_json method
I recommend you to use save_model method.
If you want to copy the model to another directly, do the following:
new_model = tf.keras.models.clone_model(model)
new_model.set_weights(model.get_weights())

Keras ValueError trying to load model

I am using Anaconda Navigator, Jupyter to be precised.
import tensorflow as tf
from tensorflow import keras
print(tf.__version__)
>>> 1.14.0
This is my model
def create_model():
model = tf.keras.Sequential([
keras.layers.Dense(86, activation='relu', kernel_regularizer=keras.regularizers.l2(0.0001),input_shape=(129,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(142, activation='relu', kernel_regularizer=keras.regularizers.l2(0.0001)),
keras.layers.Dropout(0.2),
keras.layers.Dense(4, activation='softmax')
])
return model
model = create_model()
# Display the model's architecture
model.summary()
After training,predicting and evaluating my model, I decided to save it using
model.save('/Users/Jennifer/myproject/my_model.h5')
I checked the directory and folder with the h5py file. And I decided to load it using
new_model1 = tf.keras.models.load_model('/Users/Jennifer/myproject/my_model.h5')
I got an Error
ValueError: Unknown entries in loss dictionary: ['class_name', 'config']. Only expected following keys: ['dense_17']
Please help me. What should I do? I have almost spent the whole day trying to solve this issue. Thanks
Here is a bit of a work around that just loads the weights:
#!/usr/bin/env python3
from tensorflow import keras
import os
def create_model():
model = keras.Sequential([
keras.layers.Dense(86, activation='relu', kernel_regularizer=keras.regularizers.l2(0.0001),input_shape=(129,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(142, activation='relu', kernel_regularizer=keras.regularizers.l2(0.0001)),
keras.layers.Dropout(0.2),
keras.layers.Dense(4, activation='softmax')
])
return model
if os.path.exists("junk.h5"):
model = create_model()
model.load_weights("junk.h5")
else:
model = create_model()
model.compile(optimizer=keras.optimizers.Adam(0.0001), loss=keras.losses.CategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
model.save("junk.h5")
Another workaround would be to save the model without the optimizer
model.save("junk.h5", include_optimizer=False)
It looks like the loss function you're using creates a dictionary that has invalid keys. This sounds like a bug in keras/tensorflow. That is why the colab one probably worked because it was using a newer version.