[Django]-How to predict in multiple and simultanous Keras classifier sessions in Django?

2πŸ‘

βœ…

My understanding of tensorflow graphs and sessions is:

A tensorflow graph hosts operations, placeholders and Variables. A tensorflow graph lives inside a tensorflow session (that’s why to save a trained model using tensorflow.train.Saver, you need something like Saver.save(sess, the graph)).

Here is a simple example to help you make sense of the relation between a keras model and a tensorflow graph:

import tensorflow as tf 
from keras.layers import Input, Dense
from keras.models import Model 

tf.reset_default_graph()
graph_1, graph_2 = tf.Graph(), tf.Graph()
with graph_1.as_default():
    x_in = Input(shape=(1, ), name='in_graph1')
    pred = Dense(5, name='dense1_graph1')(x_in)
    pred = Dense(1, name='dense2_graph1')(pred)
    model = Model(input=x_in, output=pred)
with graph_2.as_default():
    x_in = Input(shape=(1, ), name='in_graph2')
    pred = Dense(10, name='dense1_graph2')(x_in)
    pred = Dense(1, name='dense2_graph2')(pred)
    model = Model(input=x_in, output=pred)


with tf.Session() as sess:
    default_ops = sess.graph.get_operations()

with graph_1.as_default():
    with tf.Session() as sess:
        one_ops = sess.graph.get_operations()

with graph_2.as_default():
    with tf.Session() as sess:      
        two_ops = sess.graph.get_operations()

As you can see by running the code, default_ops is an empty list which means there is no operation in the default graph. one_ops is a list of operations of the first keras model and two_ops is a list of operations of the second keras model.

So, by using with graph.as_default(), a keras model can be exclusively embedded in a tensorflow graph.

With this in mind, it becomes easy to load several keras models in a single script. I think the example script below will address your confusions:

import numpy as np
import tensorflow as tf 
from keras.layers import Input, Dense
from keras.models import Model
from Keras.models import model_from_json

tf.reset_default_graph()
x = np.linspace(1, 4, 4)
y = np.random.rand(4)

models = {}
graph_1, graph_2 = tf.Graph(), tf.Graph()

# graph_1 
with graph_1.as_default():
    x_in = Input(shape=(1, ), name='in_graph1')
    pred = Dense(5, name='dense1_graph1')(x_in)
    pred = Dense(1, name='dense2_graph1')(pred)
    model = Model(input=x_in, output=pred)
    models['graph_1'] = model
# graph_2
with graph_2.as_default():
    x_in = Input(shape=(1, ), name='in_graph2')
    pred = Dense(10, name='dense1_graph2')(x_in)
    pred = Dense(1, name='dense2_graph2')(pred)
    model = Model(input=x_in, output=pred)
    models['graph_2'] = model

# save the two models 
with tf.Session(graph=graph_1) as sess:
    with open("model_1.json", "w") as source:
        source.write(models['graph_1'].to_json())
    models['graph_1'].save_weights("weights_1.h5")
with tf.Session(graph=graph_2) as sess:
    with open("model_2.json", "w") as source:
        source.write(models['graph_2'].to_json())
    models['graph_2'].save_weights("weights_2.h5")

####################################################
# play with the model 
pred_one, pred_one_reloaded = [], []
pred_two, pred_two_reloaded = [], []
for _ in range(10):
    print(_)
    if _ % 2 == 0:

        with graph_1.as_default():
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
                pred_one.append(models['graph_1'].predict(x).ravel())
        with tf.Session() as sess:
            with open("model_1.json", "r") as f:
                model = model_from_json(f.read())
            model.load_weights("weights_1.h5")
            pred_one_reloaded.append(model.predict(x).ravel())

    else:
        with graph_2.as_default():
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
                pred_two.append(models['graph_2'].predict(x).ravel())
        with tf.Session() as sess:
            with open("model_2.json", "r") as f:
                model = model_from_json(f.read())
            model.load_weights("weights_2.h5")
            pred_two_reloaded.append(model.predict(x).ravel())

pred_one = np.array(pred_one)
pred_one_reloaded = np.array(pred_one_reloaded)
pred_two = np.array(pred_two)
pred_two_reloaded = np.array(pred_two_reloaded)

print(pred_one)
print(pred_one_reloaded)
print(pred_two)
print(pred_two_reloaded)
πŸ‘€meTchaikovsky

1πŸ‘

You have 2 options at this point, either use multiprocessing library and spin-off a new process the moment you get a request. Be careful here as to using up the memory.

The other one (Recommended) is export your TensorFlow model to be served in tensorflow serving, in that you have the option of loading multiple instances of the same model, that way you can serve simultaneously without having to worry about things like memory management or loading and unloading memory.

πŸ‘€Chandan Gm

Leave a comment