【问题标题】:GCP ML Engine Prediction failed: Error processing input: Expected float32 got base64GCP ML 引擎预测失败:处理输入时出错:预期 float32 得到 base64
【发布时间】:2019-06-12 00:19:16
【问题描述】:

我正在尝试对部署到 GCP ML 引擎的自定义训练 TensorFlow 模型调用预测。当我尝试调用模型上的预测时,它返回以下错误消息“预期 float32 得到 base64”

  1. 我使用 迁移学习 和 TensorFlow 的 retrain.py 脚本在我的图像上训练我的模型,遵循 official documentation
python retrain.py --image_dir ~/training_images saved_model_dir /saved_model_directory
  1. 我已经使用 TensorFlow 的 label_img.py 脚本在本地测试了预测,预测在本地适用于我的图像
python label_image.py --graph=/tmp/output_graph.pb --labels=/tmp/output_labels.txt --input_layer=Placeholder --output_layer=final_result \
  1. 我已按照 retrain.py 脚本文档中的说明导出了我的模型以与 Tensorflow Serving 一起使用。
python retrain.py --image_dir ~/training_images --saved_model_dir /saved_model_directory
  1. 我已将模型上传到 Firebase,GCP 验证并接受了我的模型,我能够触发我的模型。

  2. 尝试调用在线预测时,我收到“Expected float32”错误。

 test.json ={"image_bytes": {"b64": "/9j/4AAQSkZJ.......=="}}

 gcloud ml-engine predict \
        --model my_model \
        --version v1 \
        --json-instances ./test.json

我是否需要修改 retrain.py 以使我保存的模型接受 base64 或者是否有其他解决方案?

我已经检查了以下答案,但不幸的是它并没有解决我的问题: How to pass base64 encoded image to Tensorflow prediction?

【问题讨论】:

  • 您使用的是哪个 Python 版本? 2个还是3个?
  • Python 2.7 和 TensorFlow 1.10.0

标签: python tensorflow machine-learning google-cloud-platform google-cloud-ml


【解决方案1】:

问题在于retrain.py 导出了一个模型,其输入需要一个已解码并以浮点形式调整大小的图像(请参阅此line),但您传递的是原始的、未解码的图像数据。

有两种解决方案。

  1. 以预期格式(浮点数)创建 JSON 请求。这是一个简单的解决方法,但可能会影响性能(以 JSON 格式发送 float32 数据可能效率低下)。
  2. 更改模型以接受原始图像数据作为输入。这需要对模型进行一些修改。

对于 (1),您将发送类似于以下内容的 JSON 文件:

{"images": [[[0.0, 0.0, 0.0], [0,0,0], [...]], [...], ...]}

当然,你可能会使用一些客户端库来构建它

(2) 涉及更多一点。 This sample 可以指导您如何做到这一点。

【讨论】:

  • 感谢您的回答,我使用第一个解决方案只是为了检查我的在线预测是否有效。它有效,但效率不高(如您所说)。最终的解决方案是先将图片上传到服务器,在后端进行转换,然后将转换后的图片提供给模型。
  • 我遇到了同样的问题,我尝试了第一个解决方案(将 float32 数据作为 JSON 发送),但在创建 JSON 请求时出现错误:` raise TypeError(repr(o) + " is not JSON serializable") TypeError: array([[[0.85098046, 0.85098046, 0.85098046], .... [0.48627454, 0.48627454, 0.48627454]]], dtype=float32) is not JSON serializable` 我试图自己编码并将其转换为遵循 link 的 JSON 格式,但没有运气......关于如何做到这一点的任何提示?
  • 在你的 ndarray 上调用 tolist()。此外,请确保获取正确的请求格式。请参阅this 回答以获取一些提示
【解决方案2】:

虽然在 json 中发送 float32 数组是可行的,但由于网络延迟,您会发现它非常慢。如果可能的话,你会想要使用 base64 编码的字符串。

为此,您可以对导出脚本进行的一项非常简单的更改是将图像输入名称更改为以_bytes 结尾。发生这种情况时,tensorflow 服务将自动为您解码您的 base64 编码图像字符串。基本上更新这一行https://github.com/tensorflow/hub/blob/a96bbd73abbecfad8c5517684cf3655b48bab39b/examples/image_retraining/retrain.py#L963

inputs={'image_bytes': in_image},

这可能是处理图像输入时 tensorflow 服务最有用但鲜为人知的行为之一。

你也可以在导出模型的时候使用tf.io.decode,编写自己的解码函数。

最后,您的 json 有效负载看起来像这样

{"inputs": {"image_bytes": {"b64": "/9j/4AAQSkZJ.......=="}}}

或者,如果您更喜欢实例格式

{"instances": [{"image_bytes": {"b64": "/9j/4AAQSkZJ.......=="}}]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 2021-06-08
    相关资源
    最近更新 更多