如何在ml引擎中构建用于对象检测预测的uint8 numpy数组输入张量

时间:2018-10-17 11:47:20

标签: python numpy tensorflow google-cloud-ml object-detection-api

我想根据Google ML引擎中已经存在的模型进行在线对象检测预测(或推断)。但是我无法建立json请求。

该模型是TF模型动物园中的fast_rcnn_inception_resnet_v2_atrous_coco_2017_11_08。输入是输出类别,bb,得分等的图像...

所需的输入是(来自saved_model_cli show)

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

如果我使用tolist()方法将numpy数组转换为列表,则json文件占用3兆字节,而ML引擎拒绝它“发送消息”:“请求有效负载大小超出限制:1572864字节。”,

我会将这个json作为json文件发送到ml-engine Forecast。

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

2 个答案:

答案 0 :(得分:0)

发送一个大的整数数组通常效率不高(您将花费大量的时间对这些数组进行编码和解码,网络延迟等)。 This post提供了一些选项(包括您尝试过的tolist)。

我建议使用“打包为字节字符串的张量”或“压缩图像数据”。

更新10/19/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)

答案 1 :(得分:0)

我正在处理的图像被标准化为[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()

结果低于有效载荷大小限制。