В первой части этой серии мы обсудили, как создать готовую к эксплуатации модель в TensorFlow, совместимую с обслуживанием TensorFlow, а во второй части мы обсудили, как создать среду обслуживания TF с помощью Docker. В этой части мы поговорим о создании клиента, который будет запрашивать сервер модели, работающий в контейнере Docker, для вывода на тестовый образ.



Краткое введение в gRPC (удаленный вызов процедур Google) и буферы протокола

gRPC (удаленный вызов процедур Google) - это RPC-протокол Google с оболочкой HTTP2. Это позволяет клиенту, работающему на компьютере, получить доступ к удаленному компьютеру через компьютерную сеть и вызвать функцию на этом удаленном компьютере, как если бы функция была локальной для клиента. Служба TensorFlow использует этот протокол для обслуживания моделей для вывода. Согласно официальной документации,

В gRPC клиентское приложение может напрямую вызывать методы серверного приложения на другом компьютере, как если бы это был локальный объект, что упрощает создание распределенных приложений и сервисов.

Здесь сервер gRPC - это наш контейнер докеров, на котором запущена служба обслуживания TensorFlow, а наш клиент находится на Python, который запрашивает эту службу для вывода. В этой статье очень структурировано описывается, как RPC работает.

gRPC использует протоколы буферов для сериализации структурированных данных, а также для определения параметров и возврата ответов для вызываемых методов. Он не зависит от языка и платформы. Он имеет структурированный язык, который затем компилирует код сериализации транспорта на выбранный вами язык для включения в ваш проект. Он передает данные в двоичном формате, который меньше и быстрее, чем старые добрые JSON и XML.

Создание клиента

Запрос на обслуживание TensorFlow может быть трех типов:

  1. Классификация: использует API RPC классификации, который принимает входной тензор (например, изображение) и выводит класс и оценку.
  2. Прогнозирование и регрессия: использует RPC API прогнозирования, который принимает входной тензор (например, изображение) и выводит несколько тензоров, таких как (для обнаружения объектов) bounding_boxes, классы, оценки и т. Д.

Поскольку проблема здесь связана с прогнозированием, мы будем использовать RPC API прогнозирования. Для этого нам нужны прогнозируемые protobuf, доступные на TensorFlow, обслуживающем github, и преобразовать их в код, специфичный для нашего языка (например, python). Вы можете сделать это самостоятельно или пойти простым путем и загрузить файлы python из этого репозитория github. Мы будем использовать этот объект для создания запроса на прогноз в нашем клиенте.

Шаблон клиента RPC для прогнозирования

Заглушка - это фрагмент кода, который используется для преобразования параметров во время удаленного вызова процедуры (RPC). Поскольку клиент и сервер находятся в разных адресных пространствах, необходимо, чтобы параметр, отправленный от клиента к серверу (и наоборот), был преобразован так, чтобы удаленный серверный компьютер воспринимал RPC как локальный вызов функции. Заглушка, используемая здесь, представляет собой код, сгенерированный из предсказанного protobuf, как описано выше.

Запуск службы обслуживания TensorFlow

Как описано в предыдущей части, наша служба обслуживания TensorFlow будет работать в докер-контейнере с портами, открытыми для внешнего мира. Предполагая, что образ докера доступен, контейнер можно запустить,

$ docker run -it -d -P --name tf_serving_cpu -p 3000:3000 gauravkaila/tf_serving_cpu

Здесь порт 3000 открыт для всего мира, и клиент может получить доступ к сервису обслуживания TensorFlow через этот порт. Экспортируйте каталог модели, созданный в первой части, в папку внутри контейнера с помощью,

$ docker cp /path/to/model tf_serving_cpu:/path/to/destination

Чтобы запустить службу, перейдите в контейнер и начните с

# Move to the serving/ directory
$ cd serving/
# Start the service
$ bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server 
--port=3000 
--model_name=obj_det
--model_base_path=/path/to/dest &> obj_det &

Убедитесь, что имя флага model_name совпадает с именем, указанным в клиенте. Выходные данные регистрируются в obj_det. Если все прошло хорошо, вы сможете увидеть следующий результат, когда наберете:

$ tail -f obj_det

tenorflow_serving / model_servers / main.cc: 288] Запуск ModelServer на 0.0.0.0:3000…

Модель обслуживается и готова к использованию нашим клиентом.

Визуализируйте ограничивающие рамки на тестовых изображениях

Целью модели обнаружения объектов является визуализация ограничивающих рамок расположенных объектов на изображении. Чтобы визуализировать окончательное изображение с ограничивающими рамками, мы будем использовать файл visualization_utils.py из API обнаружения объектов TensorFlow.

Мы можем получить доступ к отдельным выходам из результата с помощью,

boxes = result.outputs['detection_boxes'].float_val
classes = result.outputs['detection_classes'].float_val
scores = result.outputs['detection_scores'].float_val

Это возвращает объекты protobuf, которые можно передать в файл visualization_utils.py с помощью,

image_vis = vis_util.visualize_boxes_and_labels_on_image_array(
    {input_image},
    np.reshape(boxes,[100,4]),
    np.squeeze(classes).astype(np.int32),
    np.squeeze(scores),
    category_index,
    use_normalized_coordinates=True,
    line_thickness=8)

Окончательный клиентский сценарий будет выглядеть так:

Окончательный результат

Отправляя тестовое изображение часов, наш окончательный результат должен выглядеть примерно так. Примечание: используемая здесь модель является более быстрой RCNN, предварительно обученной на наборе данных COCO, для которого номер класса 85 соответствует часам.

outputs {
key: “detection_boxes”
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 300
}
dim {
size: 4
}
}
float_val: 0.24750074744224548
float_val: 0.17159424722194672
float_val: 0.9083144068717957
float_val: 0.797699511051178
outputs {
key: "detection_classes"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 300
}
}
float_val: 85.0
outputs {
key: "detection_scores"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 300
}
}
float_val: 0.9963208436965942

Чего мы достигли

Мы начали с сценария использования обнаружения объектов, чтобы продемонстрировать возможности обслуживания TensorFlow. Мы экспортировали нашу обученную модель в формат, ожидаемый службой TensorFlow, скомпилировали службу TF с помощью Docker и создали клиентский скрипт, который мог запрашивать сервер модели для вывода.

Что в будущем

  1. Используя этот вариант использования в качестве шаблона, мы можем использовать TensorFlow для обслуживания других моделей прогнозирования и классификации.
  2. Мы можем использовать версию TensorFlow для графического процессора, которая помогает ускорить вывод.
  3. Мы можем масштабировать нашу службу, развернув несколько контейнеров Docker, в которых запущена служба обслуживания TF.
  4. Пакетирование входных изображений может быть выполнено вместо отправки одного изображения на запрос.

Об авторе: Гаурав - менеджер по науке о данных в компании EY’s Innovation Advisory в Дублине, Ирландия. В его интересы входит создание масштабируемых систем машинного обучения для приложений компьютерного зрения. Узнайте больше на gauravkaila.com