Повторное использование сеанса Tensorflow в нескольких потоках вызывает сбой - PullRequest
0 голосов
/ 02 октября 2018

Справочная информация:

У меня есть несколько сложных алгоритмов обучения подкрепления, которые я хочу запустить в нескольких потоках.

Проблема

При попытке вызвать sess.run в потоке я получаю следующее сообщение об ошибке:

RuntimeError: The Session graph is empty. Add operations to the graph before calling run().

Код, воспроизводящий ошибку:

import tensorflow as tf

import threading

def thread_function(sess, i):
    inn = [1.3, 4.5]
    A = tf.placeholder(dtype=float, shape=(None), name="input")
    P = tf.Print(A, [A])
    Q = tf.add(A, P)
    sess.run(Q, feed_dict={A: inn})

def main(sess):

    thread_list = []
    for i in range(0, 4):
        t = threading.Thread(target=thread_function, args=(sess, i))
        thread_list.append(t)
        t.start()

    for t in thread_list:
        t.join()

if __name__ == '__main__':

    sess = tf.Session()
    main(sess)

Если я запускаю тот же код вне потока, он работает правильно.

Может кто-нибудь дать некоторое представление о том, как использовать Tensorflowсеансы правильно с потоками Python?

Ответы [ 2 ]

0 голосов
/ 07 августа 2019

Расширение ответа de1 другим ресурсом на github: tenenflow / tenorflow # 28287 (комментарий)

Следующее исправлено для меня: многопоточность совместимости tf:

# on thread 1
session = tf.Session(graph=tf.Graph())
with session.graph.as_default():
    k.backend.set_session(session)
    model = k.models.load_model(filepath)

# on thread 2
with session.graph.as_default():
    k.backend.set_session(session)
    model.predict(x)

При этом сохраняются значения Session и Graph для других потоков.
Модель загружается в их «контексте» (вместо значений по умолчанию) и сохраняется для использования другими потоками.
(По умолчаниюмодель загружается по умолчанию Session и по умолчанию Graph)
Еще один плюс заключается в том, что они хранятся в одном и том же объекте - проще в обращении.

0 голосов
/ 03 октября 2018

Не только Session может быть текущим по умолчанию потоком, но также и график.Пока вы проходите сеанс и вызываете run для него, график по умолчанию будет другим.

Вы можете изменить thread_function следующим образом, чтобы он работал:

def thread_function(sess, i):
    with sess.graph.as_default():
        inn = [1.3, 4.5]
        A = tf.placeholder(dtype=float, shape=(None), name="input")
        P = tf.Print(A, [A])
        Q = tf.add(A, P)
        sess.run(Q, feed_dict={A: inn})

Однако я бы не надеялся на какое-либо значительное ускорение.Python threading не то, что он означает в некоторых других языках, только некоторые операции, такие как io, будут выполняться параллельно.Для тяжелых операций с процессором это не очень полезно.Многопроцессорная обработка может выполнять код действительно параллельно, но вы не будете использовать один и тот же сеанс.

...