Керас прогнозируют в процессе зависания - PullRequest
0 голосов
/ 29 января 2020

Я пытаюсь создать сервер, который предсказывает (регрессию) данные определенного ввода, однако, когда я делаю файл с общими керасами (с бэкэндом тензорного потока) для предварительной загрузки и пропускаю загрузку модели каждый раз (что сэкономит около 1,8 секунды) и когда я пытаюсь что-либо предсказать из потока, программа просто зависает (хотя во время моего теста к нему обращается только один поток). Я знаю, что тензор не предназначен для этого, однако, поскольку он только предсказывает, для этого должен быть обходной путь. Я попытался использовать _make_prediction_function, но это не сработало.

Это основная функция:

keras_model = keras_model_for_threads()
def thread_function(conn, addr, alive):
    print('Connected by', addr)
    start = time.time()
    sent = conn.recv(1024)
    x_pred = preproc(sent)
    conn.sendall(keras_model.predict_single(x_pred))
    conn.close()
import socket

HOST = ''
PORT = xxxxx
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1000)
print('Ready for listening')
while alive.get():
    conn, addr = s.accept()
    Process(target=thread_function, args=(conn, addr, alive)).start()

с помощью keras_model:

class keras_model_for_threads():
    def __init__(self):
        self.model = load_model(model_path)
        self.model._make_predict_function()

    def predict_single(self, x_pred):        
        return self.model.predict(x_pred)

Теперь, если я запустите это обычно он выполняет и возвращает прогноз, но через процесс с функцией потока он останавливается в self.model.predict.

1 Ответ

0 голосов
/ 30 января 2020

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

from multiprocessing.managers import BaseManager
from multiprocessing import Lock

class KerasModelForThreads():
    def __init__(self):
        self.lock = Lock()
        self.model = None

    def load_model(self):
        from keras.models import load_model
        self.model = load_model(model_path)

    def predict_single(self, x_pred):
        with self.lock:
            return (self.model.predict(x_pred) + self.const.offset)[0][0]

class KerasManager(BaseManager):
    pass

KerasManager.register('KerasModelForThreads', KerasModelForThreads)

и основной код на

from keras_for_threads import KerasManager
keras_manager = KerasManager()
keras_manager.start()
keras_model = keras_manager.KerasModelForThreads()
keras_model.load_model()
def thread_function(conn, addr, alive):
    print('Connected by', addr)
    start = time.time()
    sent = conn.recv(1024)
    x_pred = preproc(sent)
    conn.sendall(keras_model.predict_single(x_pred))
    conn.close()
import socket

HOST = ''
PORT = xxxxx
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1000)
print('Ready for listening')
while alive.get():
    conn, addr = s.accept()
    Process(target=thread_function, args=(conn, addr, alive)).start()

Это урезанная версия (без материала Flask, только часть keras) из проекта GitHub я нашел здесь: https://github.com/Dref360/tuto_keras_web

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...