Как построить входной тензор массива uint8 numpy для предсказания обнаружения объектов в движке ml

Я хочу делать прогнозы обнаружения объектов в Интернете (или делать выводы) на основе уже существующей модели в движке Google ML. Но я не могу создать запрос json.

Модель быстрее_rcnn_inception_resnet_v2_atrous_coco_2017_11_08 из зоопарка моделей TF. Входы - это изображения, выходы: класс, bb, оценка и т. Д.

Необходимые входные данные (из шоу saved_model_cli)

inputs['inputs'] tensor_info:
dtype: DT_UINT8
shape: (-1, -1, -1, 3)
name: image_tensor:0

Поскольку он ожидает массив uint8, я загружаю изображение в массив numpy

encoded_contents = np.array(image.getdata()).reshape(
        (im_height, im_width, 3)).astype(np.uint8)

Измените размер изображения image_np_expanded = np.expand_dims (encoded_contents, axis = 0)

Пытался построить json-запрос

instance = {"input":encoded_contents}
row = json.dumps(instance,sort_keys=True)

Но я не могу это построить, потому что

TypeError(repr(o) + " is not JSON serializable")
TypeError: array([[[164, 191, 220],
[190, 157, 114],
[190, 157, 114]]], dtype=uint8) is not JSON serializable

Если я конвертирую массив numpy в список с помощью метода tolist (), json-файл занимает 3 мегабайта, и ML-движок отклоняет его «message»: «Размер полезной нагрузки запроса превышает предел: 1572864 байта.»,

Я отправлю этот json-файл в ml-engine прогноз в виде файла json.

gcloud ml-engine predict --model=pellaires --version=pellaires14 --json- 
instances=request.json > response.yaml

person Juan Luis    schedule 17.10.2018    source источник


Ответы (2)


Отправка такого большого массива int обычно неэффективна (вы потратите нетривиальное время на кодирование и декодирование этих массивов, задержку в сети и т. Д.). В этом сообщении представлены несколько вариантов (включая tolist, который вы пробовали).

Я бы порекомендовал либо «Тензоры, упакованные как байтовые строки», либо «Сжатые данные изображения».

ОБНОВЛЕНИЕ 19.10.2018

Чтобы использовать эти подходы, вам нужно будет изменить свой график. Если вы можете повторно экспортировать модель, это проще всего. Вместо:

images = tf.placeholder(dtype=tf.uint8, shape=[None, None, None, 3])

Вы бы использовали:

raw_byte_strings = tf.placeholder(dtype=tf.string, shape=[None])
decode = lambda raw_byte_str: tf.decode_raw(raw_byte_str, tf.uint8)
images = tf.map_fn(decode, raw_byte_strings, dtype=tf.uint8)
person rhaertel80    schedule 17.10.2018
comment
Спасибо. Я уже читал этот пост, но думаю, что ни один из этих входов не принимается моей моделью, которая ожидает массивы dtype: DT_UINT8. Размеры двоичного изображения не такие большие, не более 100 КБ, он получает 3 МБ, когда я использую метод tolist () для создания json (поскольку массив не сериализуемый) - person Juan Luis; 17.10.2018
comment
Спасибо. Наконец я перешел на tenorflow_serving API, обслуживающий его в кубернетах. Намного более гибкий и отлаживаемый. В ML API эта ошибка была неразрешима, так как не имела смысла (я следил за опубликованными Google инструкциями). Более того, мой клиентский код Python развернут в движке приложений (и я рассматривал возможность использования мобильных телефонов Android), поэтому я хотел, чтобы они были как можно легче. Итак, я не хотел загружать тензорный поток в моем клиенте (те, которые отправляют изображения на вывод), а просто numpy и python (не th.placeholder) - person Juan Luis; 07.11.2018

Изображения, с которыми я работаю, нормализованы до [0,1]. При преобразовании в список каждый пиксель изображения имеет излишне большую точность:

[[[0.4, 0.41568627450980394, 0.4117647058823529],
  [0.39215686274509803, 0.403921568627451, 0.403921568627451],
  [0.38823529411764707, 0.4, 0.4],
  [0.3803921568627451, 0.39215686274509803, 0.3843137254901961],
  [0.3803921568627451, 0.38823529411764707, 0.38823529411764707],
  ...
  [0.11764705882352941, 0.12941176470588237, 0.12549019607843137],
  [0.11764705882352941, 0.12941176470588237, 0.12549019607843137],
  [0.11764705882352941, 0.12941176470588237, 0.12549019607843137]]]

Быстрое и грязное решение - использовать np.around ():

img_list = np.around(img_np, 4).tolist()

Результат ниже предельного размера полезной нагрузки.

person mherzog    schedule 31.08.2020