Давайте предположим, что у меня есть большое количество обученных моделей керас, и мне приходится иногда загружать их и делать прогнозы. Мне нужно загрузить каждую модель и предсказать данные как можно быстрее. Я думаю, что самое быстрое решение - это сохранить их в памяти, но я полагаю, что это не очень хороший способ, потому что вскоре переполнится RAM? Так что в этот момент я достигаю высочайшей производительности с чем-то вроде этого.
K.clear_session()
random_model = load_model('path/to/' + str(random_model))
results = random_model(final_input_row)
Кроме того, у меня есть пять моделей, которыми я пользуюсь почти все время, и в этом случае производительность еще важнее. Я загружаю их во время запуска сервера и имею постоянный доступ к ним.
graph = tf.get_default_graph()
with graph.as_default():
constant_model = load_model(
'path/to/constant_model')
предсказание:
with graph.as_default():
results = constant_model(final_input_row)
Проблема в том, что во время K.clear_session()
, которое я выполняю во время загрузки random_models
, я потерял их из памяти. Без K.clear_session()
загрузка random_models
длится слишком долго. У вас есть идеи, как я могу решить это? Я даже могу использовать совершенно разные методы.
UPDATE
Я пытаюсь сделать что-то вроде этого:
class LoadModel:
def __init__(self, path):
self.path = path
self.sess = tf.Session(config=config)
self.graph = tf.get_default_graph()
K.set_session(self.sess)
with self.graph.as_default():
self.model = load_model(self.path)
def do_predictions(self, x):
with self.graph.as_default():
return self.model.predict(x)
А потом, когда я выполню:
random_model = LoadModel('./path/to/random_model.h5')
results = random_model.do_predictions(final_input_row)
Для прогнозирования данных требуется около 3 секунд. В случае random_models
, когда у меня много моделей, это приемлемо. Однако в случае constant_models
, когда у меня их пять, и мне нужен постоянный доступ к ним, это длится слишком долго. До сих пор я делал это так, что загружал модель во время запуска сервера Django и сохранял это в памяти, а затем мог просто запустить results = constant_model.do_predictions(final_input_row)
, и это было очень быстро. Работает нормально, пока я не запускаю random_models
, после этого в каждом запросе я получаю
tensorflow.python.framework.errors_impl.InvalidArgumentError: Tensor lstm_14_input:0, specified in either feed_devices or fetch_devices was not found in the Graph
[24/Jun/2019 10:11:00] "POST /request/ HTTP/1.1" 500 17326
[24/Jun/2019 10:11:02] "GET /model/ HTTP/1.1" 201 471
Exception ignored in: <bound method BaseSession._Callable.__del__ of <tensorflow.python.client.session.BaseSession._Callable object at 0x130069908>>
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1455, in __del__
self._session._session, self._handle, status)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__
c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: No such callable handle: 140576717540032
[24/Jun/2019 10:11:02] "GET /model/ HTTP/1.1" 201 471
[24/Jun/2019 10:11:07] "GET /model/ HTTP/1.1" 201 471
Очевидно, это работает правильно, если я запускаю constant_model = LoadModel('./path/to/constant_model.h5')
перед каждым results = constant_model.do_predictions(final_input_row)
, однако, как я уже говорил, это слишком медленно. Есть идеи как это решить?
UPDATE2
Я пытаюсь таким образом
session = tf.Session(config=config)
K.set_session(session)
class LoadModel:
def __init__(self, path):
self.path = path
self.graph = tf.get_default_graph()
with self.graph.as_default():
self.model = load_model(self.path)
def do_predictions(self, x):
with self.graph.as_default():
return self.model.predict(x)
но все равно я получаю TypeError: Cannot interpret feed_dict key as Tensor: Tensor Tensor("Placeholder:0", shape=(1, 128), dtype=float32) is not an element of this graph.
РЕШЕНИЕ
Ниже мое рабочее решение. Если кто-нибудь знает еще более эффективный способ загрузки модели, отвечающий описанным выше требованиям, я буду благодарен за сообщение.
class LoadModel:
def __init__(self, model_path):
with K.get_session().graph.as_default():
self.model = load_model(model_path)
self.model._make_predict_function()
self.graph = tf.get_default_graph()
def predict_data(self, data):
with self.graph.as_default():
output = self.model.predict(data)
return output