Вопрос или проблема
Я работал над простым API компьютерного зрения с несколькими конечными точками для извлечения полезной информации из изображений ebay. API размещается в контейнере Docker, который ищет h5 файлы, загружает их, если они отсутствуют, запускает все и начинает сервер каждый раз, когда контейнер создается. Одна из конечных точек – это обученный классификатор VGG-16, который разделяет изображения на группы для дальнейшего анализа и проверки человеком. Эта конечная точка демонстрирует странное поведение. Когда я запускаю её напрямую со своего локального компьютера, всё работает нормально. Однако, когда я запускаю её изнутри контейнера Docker, она работает нормально, пока не остается без дела слишком долго, но если это случается, я получаю следующую ошибку, и контейнер Docker нужно будет перезапустить:
Невозможно интерпретировать ключ feed_dict как Tensor: Tensor Tensor("Placeholder:0", shape=(3, 3, 512, 512), dtype=float32) не является элементом этого графа.
В коде не кажется, что есть ошибка, и контейнер Docker выглядит нормально. Я не понимаю, почему это происходит только в контейнеризованном API, а не в локально хранимой версии. Если кто-то сталкивался с этим раньше, пожалуйста, помогите!
Вот мой Dockerfile
FROM python:3.7.3
WORKDIR /code
COPY requirements.txt /code
RUN pip install -r requirements.txt
RUN apt update && apt-get install tesseract-ocr -y
COPY . /code
EXPOSE 8000
CMD ["python", "-u", "manage.py", "runserver", "0.0.0.0:8000"]
manage.py, который управляет соответствующим h5 файлом:
if __name__ == '__main__':
model_getter = os.listdir(".")
model_list = []
for names in model_getter:
if names.endswith(".h5"):
model_list.append(names)
if model_list==[]:
sys.stdout.write("Нейронная сеть не найдена. Загружается модель.\n")
if os.path.exists("../aws-credentials.json"):
with open("../aws-credentials.json") as f:
sys.stdout.write("Загрузка учетных данных разработчика.\n")
data= json.load(f)
conn = boto.connect_s3(data["accessKeyId"], data["secretAccessKey"])
bucket = conn.get_bucket('mybucket')
file_path = bucket.get_key('/developer/model.h5')
sys.stdout.write("модель готовится к загрузке. Пожалуйста, подождите, пока загрузка не завершится. Это может занять некоторое время.\n")
file_path.get_contents_to_filename('model.h5')
sys.stdout.write("Загрузка завершена.\n")
main()
и код CNN:
def runNetwork(request, encoded_url):
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import keras.models
import numpy as np
import requests
from io import BytesIO
model=keras.models.load_model('model.h5')
uri = urllib.parse.unquote(encoded_url)
response = requests.get(uri)
img = image.load_img((BytesIO(response.content)),target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
features = model.predict_classes(x)
if features ==[0]:
code = "foo"
if features ==[1]:
code = "bar"
if features==[2]:
code = "baz"
...
features=np.int(features[0])
obj_json = {"input_uri" : uri, "prediction_index" : features, "prediction_code" : code }
return JsonResponse(obj_json)
и полный трейс стека:
usr/local/lib/python3.7/site-packages/tensorflow/python/client/session.py in _run
subfeed, allow_tensor=True, allow_operation=False) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py in as_graph_element
return self._as_graph_element_locked(obj, allow_tensor, allow_operation) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py in _as_graph_element_locked
raise ValueError("Tensor %s не является элементом этого графа." % obj) …
▶ Local vars
Во время обработки вышеупомянутого исключения (Tensor Tensor("Placeholder:0", shape=(3, 3, 512, 512), dtype=float32) не является элементом этого графа.) возникло другое исключение:
/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py in inner
response = get_response(request) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response
response = self.process_exception_by_middleware(e, request) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
/code/SlabIDs/views.py in runNetwork
model=keras.models.load_model('SlabNet3.h5') …
▶ Local vars
/usr/local/lib/python3.7/site-packages/keras/engine/saving.py in load_model
model = _deserialize_model(f, custom_objects, compile) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/keras/engine/saving.py in _deserialize_model
K.batch_set_value(weight_value_tuples) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py in batch_set_value
get_session().run(assign_ops, feed_dict=feed_dict) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/tensorflow/python/client/session.py in run
run_metadata_ptr) …
▶ Local vars
/usr/local/lib/python3.7/site-packages/tensorflow/python/client/session.py in _run
'Не удалось интерпретировать ключ feed_dict как Tensor: ' + e.args[0]) …
▶ Local vars
Окей, я допустил глупую ошибку. Пожалуйста, проигнорируйте вышеупомянутое паническое бредительство. Однако на случай, если кто-то другой столкнется с чем-то подобным, проблема была решена просто благодаря тому, что я вспомнил о необходимости очищать свою сессию в конце каждого запуска:
from keras import backend as K
...код...
K.clear_session()
Ответ или решение
Интермиттирующая Ошибка При Запуске CNN Внутри Docker-Контейнера: Решение Проблемы
Недавний опыт использования контейнеров Docker для разработки API компьютерного зрения привел к интересной проблеме: ошибка при работе с трансформированным классификатором VGG-16. Эта ситуация подтверждает важность понимания работы с сессиями и графами в Keras и TensorFlow, особенно в условиях контейнеризации.
Проблема
Проблема, с которой вы столкнулись, заключается в следующем сообщении об ошибке:
Cannot interpret feed_dict key as Tensor: Tensor Tensor("Placeholder:0", shape=(3, 3, 512, 512), dtype=float32) is not an element of this graph.
Эта ошибка указывает на то, что попытка обращения к тензору, который не является частью активного графа, завершилась неудачей. Ошибка возникает после продолжительного простоя контейнера, что может свидетельствовать о том, что граф Keras/TensorFlow теряет привязку к сессии или что сессии становятся "мертвыми".
Анализ Кодовой Базы
Ваш API работает по следующему принципу:
- Загружает модель, если
.h5
файл не найден. - Обрабатывает входящие изображения с помощью Keras.
- Возвращает результаты в формате JSON.
Однако, ваша изначальная реализация не очищала сессии Keras после обработки запросов. Это создает множество ненужных графов, которые остаются загруженными, что в итоге приводит к исчерпанию ресурсов и возникновению ошибок при повторном использовании модели.
Решение Проблемы
На основании вашего решения, ключевым моментом был вызов метода K.clear_session()
из Keras после завершения обработки каждого запроса. Этот метод очищает текущую сессию и граф, что позволяет избежать конфликтов и уменьшить использование оперативной памяти. Таким образом, исправлений требует не только логика проверки, но и управление ресурсами:
from keras import backend as K
def runNetwork(request, encoded_url):
# Ваш код обработки изображения...
model = keras.models.load_model('model.h5')
# Ваш код предсказания...
# Очистка сессии для предотвращения ошибок
K.clear_session()
return JsonResponse(obj_json)
Рекомендации по Архитектуре
Для улучшения стабильности вашего API в Docker рассмотрите следующие рекомендации:
-
Изоляция Моделей: Используйте разные инстансы моделей для параллельного обслуживания запросов, если нагрузки высокие.
-
Управление Памятью: Регулярно проводите мониторинг использования памяти контейнера и настраивайте лимиты на ресурсы в Docker.
-
Логирование Ошибок: Добавьте механизм логирования для захвата и анализа ошибок, что поможет в дальнейшем диагностировании проблем.
-
Тестирование: Регулярно тестируйте вашу систему при различных нагрузках, чтобы выявить проблемные места на ранних этапах.
Заключение
Ситуации подобного рода не редкость при работе с глубоким обучением и Docker. Правильное управление сессиями и ресурсами является ключом к развитию надежных и высокопроизводительных приложений. Надеюсь, ваши выводы помогут многим разработчикам в будущем избегать подобных проблем.