第一步是确保您导出的图形具有可以接受JPEG数据的占位符和运算。请注意,CloudML假定您正在发送一批图像。我们必须使用tf.map_fn
来解码并调整一批图像的大小。根据模型,可能需要对数据进行额外的预处理以规范化数据等。如下所示:
CHANNELS = 3
HEIGHT = 200
WIDTH = 200
images_placeholder = tf.placeholder(dtype=tf.string, shape=(None,))
def decode_and_resize(image_str_tensor):
"""Decodes jpeg string, resizes it and returns a uint8 tensor."""
image = tf.image.decode_jpeg(image_str_tensor, channels=CHANNELS)
image = tf.expand_dims(image, 0)
image = tf.image.resize_bilinear(
image, [HEIGHT, WIDTH], align_corners=False)
image = tf.squeeze(image, squeeze_dims=[0])
image = tf.cast(image, dtype=tf.uint8)
return image
decoded_images = tf.map_fn(
decode_and_resize, images_placeholder, back_prop=False, dtype=tf.uint8)
images = tf.image.convert_image_dtype(decoded_images, dtype=tf.float32)
images = tf.sub(images, 0.5)
images = tf.mul(images, 2.0)
此外,我们需要确保正确标记输入内容。在这种情况下,关键字(映射中的键)的名称必须以“
_bytes
”结尾。发送基于base64编码的数据时,这将告诉CloudML预测服务需要解码数据。
inputs = {"image_bytes": images_placeholder.name}
tf.add_to_collection("inputs", json.dumps(inputs))
命令期望的数据格式应该是这样的:
{"image_bytes": {"b64": "dGVzdAo="}}
(请注意,如果您的模型的唯一输入是
image_bytes
,则可以简化为
{"b64": "dGVzdAo="}
。)
例如,要从磁盘上的文件创建此内容,您可以尝试以下操作:
echo "{\"image_bytes\": {\"b64\": \"`base64 image.jpg`\"}}" > instances
然后像这样将其发送到服务端:
gcloud beta ml predict --instances=instances --model=my_model
请注意,在直接向服务发送数据时,您发送的请求正文需要包装在“instances”列表中。因此,上述gcloud命令实际上将以下内容作为HTTP请求的正文发送到服务端:
{"instances" : [{"image_bytes": {"b64": "dGVzdAo="}}]}