Вопрос или проблема
Я выполняю задачу обнаружения экземпляров и извлечения изображений с помощью Keras и Tensorflow в качестве бэкенда.
Я планирую использовать многопоточность для загрузки двух моделей, загружая maskrcnn в одном потоке и mobile net в другом.
Я успешно загрузил maskrcnn в одном потоке, но не смог загрузить mobile net в другом потоке, и:
показано: ValueError: тензор a должен быть из той же графа, что и тензор b.
Код приведен ниже:
Merge.py
from keras import backend as K
g1=tf.Graph()
g2=tf.Graph()
sess1=tf.Session(graph=g1)
sess2=tf.Session(graph=g2)
def intiMaskrcnn():
with g1.as_default():
with sess1.as_default():
Model1=........
def instanceDetect():
K.set_session(sess1)
with g1.as_default():
Model1.predit()
............
def intiMobilenet():
with g2.as_default():
with sess2.as_default():
Model2=........
def Retrieval():
K.set_session(sess2)
with g2.as_default():
Model2.predit()
............
Thread1.py
intiMaskrcnn()
instanceDetect()
Thread2.py
intiMobilenet()
Retrieval()
Где я ошибаюсь?
TensorFlow хранит все операции в операционном графе. Этот граф определяет, какие функции выводят результаты и куда, и он связывает это все вместе, чтобы следовать тем шагам, которые вы задали в графе для получения конечного результата. Если вы попытаетесь ввести тензор или операцию из одного графа в тензор или операцию из другого графа, это приведет к ошибке. Все должно быть в одном графе выполнения.
Попробуйте использовать
tf.reset_default_graph()
чтобы сбросить граф tf после его выполнения.
Для keras используйте K.clear_session()
.
Для получения более подробной информации о взаимодействии keras и tensorflow просмотрите блог документации Keras.https://blog.keras.io/keras-as-a-simplified-interface-to-tensorflow-tutorial.html это очень поможет вам.
Ответ или решение
Использование графов TensorFlow в многопоточном режиме: Решение проблемы ValueError
Введение
При работе с TensorFlow и Keras, особенно в контексте многопоточной обработки, разработчики могут столкнуться с ошибками, связанными с графами и сессиями. Ваша ошибка ValueError: tensor a must be from the same graph as tensor b
указывает на проблему с использованием тензоров, которые принадлежат разным графам. Эта статья предоставит вам руководство по правильному использованию графов TensorFlow в многопоточном окружении.
Основные Проблемы
TensorFlow использует концепцию графов для управления моделью и ее вычислениями. Каждый граф определяет собственный набор операций и тензоров. Когда вы пытаетесь использовать тензоры из одного графа в контексте другого, TensorFlow вызывает ошибку, поскольку не может сопоставить операции.
В вашем случае, вы создали два отдельных графа (g1
и g2
), каждый из которых имеет свою сессию (sess1
и sess2
). Это обоснованный шаг, но использование их в разных потоках требует внимательности.
Решение Проблемы
-
Инициализация Графа и Сессий: Убедитесь, что каждый поток использует свой собственный граф и сессию. Важно также убедиться, что весь код выполнения (включая вызовы методов предсказания) находится внутри соответствующих контекстов графа.
-
Используйте
tf.reset_default_graph()
иK.clear_session()
:
Эти команды помогут сбросить текущий граф и очистить сессии Keras, что полезно в сценариях. Однако, если вы работаете в многопоточном режиме, это не должно быть выполнено в потоках, которые выполняют действия, зависящие от текущих графов. -
Настройка Моделей и Сессий в Один Поток: Убедитесь, что инициализация моделей и их предсказания выполняются в одном и том же потоке, используя соответствующий граф и сессию.
Переписанный Пример Кода
Вот как можно переписать ваш код, чтобы избежать указанной ошибки:
import tensorflow as tf
from keras import backend as K
import threading
g1 = tf.Graph()
g2 = tf.Graph()
sess1 = tf.Session(graph=g1)
sess2 = tf.Session(graph=g2)
def intiMaskrcnn():
with g1.as_default():
with sess1.as_default():
global Model1
Model1 = ... # Задайте вашу модель здесь
def instanceDetect():
with g1.as_default():
K.set_session(sess1)
preds = Model1.predict(...) # Замените '...' на параметры
return preds
def intiMobilenet():
with g2.as_default():
with sess2.as_default():
global Model2
Model2 = ... # Задайте вашу модель здесь
def Retrieval():
with g2.as_default():
K.set_session(sess2)
preds = Model2.predict(...) # Замените '...' на параметры
return preds
# Создаем потоки
thread1 = threading.Thread(target=lambda: (intiMaskrcnn(), instanceDetect()))
thread2 = threading.Thread(target=lambda: (intiMobilenet(), Retrieval()))
# Запускаем потоки
thread1.start()
thread2.start()
# Ждем завершения потоков
thread1.join()
thread2.join()
Важные Замечания
-
Глобальные Переменные: В приведенном выше примере используйте глобальные переменные для моделей, чтобы обеспечить их доступ в разных функциях.
-
Контекст Менеджеры: Используйте
with
для явного задания контекста графа и сессии, предотвращая случайные сессии при вызовах функций. -
Параметры Предсказания: Убедитесь, что в методах предсказания переданы правильные параметры.
Заключение
Работа с TensorFlow и Keras в многопоточном окружении может быть сложной задачей из-за особенностей работы с графами. Однако, следуя описанным выше рекомендациям, вы сможете успешно настроить вашу систему для выполнения задач совместной работы с несколькими моделями. Убедитесь, что понимать и соблюдать контексты графов и сессий — это ключевой аспект для избегания ошибок.