0

人口普查和花卉样本展示了如何使用 Google 的机器学习引擎预测类别标签。

我们可以部署自己的模型来生成图像标题吗?如果是,预测是如何工作的?预测响应的格式是什么?

更具体地说,在下面显示的附件中,概率子数组给出了每个类的索引和机会。如果我们使用图像说明模型,预测响应会是什么样子?

附件:http ://boaloysius.me/sites/default/files/inline-images/predict1_0.png

4

1 回答 1

0

Cloud ML Engine 允许您部署几乎任何您能够导出的 TensorFlow 模型。对于任何此类模型,您都可以定义输入和输出,这决定了请求和响应的形式。

我认为通过一个例子来理解这一点可能很有用。您可以想象像这样导出模型:

def my_model(image_in):
  # Construct an inference graph for predicting captions
  #
  # image_in is a tensor/array with shape=(None,) and dtype=string
  # Meaning, a batch of raw image bytes.

  ... Do your interesting stuff here ...      

  # caption_out is a tensor/matrix with shape=(None, MAX_WORDS) and 
  # dtype=tf.string), that is, you will be returning a batch
  # of captions, one per input image, one word per column with
  # padding when the number of words to output is < MAX_WORDS
  return caption_out

image_in = tf.placeholder(shape=(None,), dtype=tf.string)
caption_out = my_model(image_in)

inputs = {"image_bytes": tf.saved_model.utils.build_tensor_info(image_in}
outputs = {"caption": tf.saved_model.utils.build_tensor_info(caption_out)}

signature = tf.saved_model.signature_def_utils.build_signature_def(
      inputs=inputs,
      outputs=outputs,
      method_name='tensorflow/serving/predict'
)

导出此模型后(参见这篇文章),您将构建一个 JSON 请求,如下所示:

{
  "instances": [
    {
      "image_bytes": {
        "b64": <base64_encoded_image1>
      }
    },
    {
      "image_bytes": {
        "b64": <base64_encoded_image2>
      }
    }
  ]
}

让我们分析一下请求。首先,我们将向服务发送一批图像。所有请求都是一个 JSON 对象,具有一个名为“instances”的数组值属性;数组中的每个条目都是一个实例,用于为图形提供预测。请注意,这就是我们需要在None导出的模型上设置最外层维度的原因——它们需要能够处理可变大小的批次。

数组中的每个条目本身就是一个 JSON 对象,其中的属性是input我们在导出模型时定义的 dict 的键。在这种情况下,我们只定义了image_bytes. 因为image_bytes是一个字节字符串,我们需要对数据进行base64编码,我们通过传递表单的JSON对象来做到这一点{"b64": <data>}。如果我们想向服务发送多个图像,我们可以为每个图像添加一个类似的条目到instance数组中。

现在,此示例的示例 JSON 响应可能如下所示:

{
  "predictions": [
    {
      "caption": [
        "the",
        "quick",
        "brown",
        "",
        "",
        ""
      ]
    },
    {
      "caption": [
        "A",
        "person",
        "on",
        "the",
        "beach",
        ""
      ]
    }
  ]
}

所有响应都是 JSON 对象,具有称为“预测”的数组值属性。instances数组的每个元素都是与请求中数组中相应输入相关联的预测。

数组中的每个条目都是一个 JSON 对象,其属性由outputs我们之前导出的 dict 的键确定。在这种情况下,我们每个输入都有一个输出,称为caption. 请注意,标题的源张量caption_out实际上是一个矩阵,其中行数等于发送到服务的实例数以及我们定义为某个常数的列数。但是,服务不会返回矩阵,而是独立地返回矩阵的每一行作为prediction数组中的条目。矩阵的第二维是一些常数,并且可能模型本身会将额外的单词填充为空字符串(如上图所示)。

一个非常重要的注意事项:在上面的示例中,我展示了原始 JSON 请求/响应主体。从您的帖子中,很明显您正在使用 Google 的通用客户端,该客户端正在解析响应并在其周围添加结构,具体而言,您正在打印的对象将预测包装在嵌套字段中[data],然后[modelData:protected].

我个人的建议是不要将该客户端用于该服务,而是使用通用请求/响应库(以及 Google 的身份验证库),但既然您有工作,欢迎使用适合您的任何东西。

于 2017-07-10T14:59:28.603 回答