2π
My understanding of tensorflow
graphs and sessions is:
A tensorflow
graph hosts operations, placeholder
s and Variable
s. 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)
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.