Как я могу ускорить загрузку моделей в Keras и Tensorflow? - PullRequest
1 голос
/ 23 июня 2019

Давайте предположим, что у меня есть большое количество обученных моделей керас, и мне приходится иногда загружать их и делать прогнозы. Мне нужно загрузить каждую модель и предсказать данные как можно быстрее. Я думаю, что самое быстрое решение - это сохранить их в памяти, но я полагаю, что это не очень хороший способ, потому что вскоре переполнится 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

1 Ответ

0 голосов
/ 23 июня 2019

Поскольку вы сказали, что используете все модели все время, было бы хорошо сохранить их в памяти, чтобы вы не загружали и не предсказывали каждый раз, когда вы делаете запрос.Например, вы должны определить класс, который загружает модель и сохраняет разные экземпляры этого класса для разных моделей.Это не проверенный код, поэтому вам, возможно, придется внести некоторые изменения.

# if you are using GPU
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

class LoadModel:
    def __init__(self, path_to_model):
        self.path  = path
        self.sess  = tf.Session(config=config)
        self.graph = tf.get_default_graph()
        K.set_session(self.sess) 
        self.model = self.load()

    def load(self):
        with graph.as_default():
            model = load_model(self.path)
        return model

    def do_predictions(self, x):
        return self.model.predict(x)    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...