Keras + Tensorflow и многопроцессорность в Python
Я использую Keras с Tensorflow в качестве backend.
Я пытаюсь сохранить модель в своем основном процессе, а затем загрузить/запустить (т.е. вызвать model.predict
) в рамках другого процесса.
В настоящее время я просто пытаюсь использовать наивный подход из документов для сохранения/загрузки модели: https://keras.io/getting-started/faq/#how-can-i-save-a-keras-model.
Итак, в основном:
-
model.save()
в основном процессе
-
model = load_model()
в дочернем процессе
-
model.predict()
в дочернем процессе
Однако он просто зависает при вызове load_model
.
Поиск вокруг Я обнаружил этот потенциально связанный ответ, предполагающий, что Keras можно использовать только в одном процессе: используя многопроцессорную обработку с помощью anano, но я не уверен, что это правда ( как представляется, не находят много на этом).
Есть ли способ достичь моей цели? Приветствуется описание высокого уровня или короткий пример.
Примечание. Я попытался подходить к методам передачи графа процессу, но сработал, так как кажется, что графики тензорного потока не подбираются (связанная с этим ссылка SO здесь: Tensorflow: Передача сеанса в многопроцесс python). Если действительно есть способ передать график/модель тензорного потока в дочерний процесс, тогда я также открыт для этого.
Спасибо!
Ответы
Ответ 1
Из моего опыта - проблема заключается в загрузке Keras
в один процесс, а затем при создании Keras
нового процесса, когда он загружен в вашу основную среду. Но для некоторых приложений (например, для подготовки смеси моделей Keras
) просто лучше иметь все это в одном процессе. Итак, я советую следующее (немного громоздкое, но работающее для меня) подход:
-
НЕ НАГРУЖАЙТЕ КЕРАС К ВАШЕЙ ОСНОВНОЙ СРЕДЕ. Если вы хотите загрузить Keras/Theano/TensorFlow, сделайте это только в среде функций. Например. не делать это:
import keras
def training_function(...):
...
но выполните следующие действия:
def training_function(...):
import keras
...
-
Запуск работы, связанной с каждой моделью, в отдельном процессе: Я обычно создаю рабочих, которые выполняют работу (например, обучение, настройка, подсчет очков), и я запускаю их в отдельных процессах. Что хорошо, что вся память, используемая этим процессом, полностью освобождена, когда ваш процесс завершен. Это помогает вам с множеством проблем с памятью, которые обычно возникают при использовании многопроцессорности или даже при запуске нескольких моделей в одном процессе. Так что это выглядит, например. например:
def _training_worker(train_params):
import keras
model = obtain_model(train_params)
model.fit(train_params)
send_message_to_main_process(...)
def train_new_model(train_params):
training_process = multiprocessing.Process(target=_training_worker, args = train_params)
training_process.start()
get_message_from_training_process(...)
training_process.join()
Разный подход - это просто подготовка разных сценариев для разных действий модели. Но это может привести к ошибкам памяти, особенно когда ваши модели потребляют память. ПРИМЕЧАНИЕ, что по этой причине лучше сделать ваше выполнение строго последовательным.
Ответ 2
Я создал один простой пример, чтобы показать, как запустить модель Keras в нескольких процессах с несколькими gpus. Надеюсь, этот образец поможет вам.
https://github.com/yuanyuanli85/Keras-Multiple-Process-Prediction
Ответ 3
Я создал декоратор, который исправил мой код.
from multiprocessing import Pipe, Process
def child_process(func):
"""Makes the function run as a separate process."""
def wrapper(*args, **kwargs):
def worker(conn, func, args, kwargs):
conn.send(func(*args, **kwargs))
conn.close()
parent_conn, child_conn = Pipe()
p = Process(target=worker, args=(child_conn, func, args, kwargs))
p.start()
ret = parent_conn.recv()
p.join()
return ret
return wrapper
@child_process
def keras_stuff():
""" Keras stuff here"""