Google cloud ml 如何获得一个TensorFlow/Keras模型,该模型将图像作为输入,用于云ML引擎上的预测?
在云ML引擎中为TensorFlow/Keras模型提供预测服务时,有多个问题(例如:、、等)试图解决如何处理图像数据的问题Google cloud ml 如何获得一个TensorFlow/Keras模型,该模型将图像作为输入,用于云ML引擎上的预测?,google-cloud-ml,Google Cloud Ml,在云ML引擎中为TensorFlow/Keras模型提供预测服务时,有多个问题(例如:、、等)试图解决如何处理图像数据的问题 不幸的是,有些答案已经过时,没有一个能全面解决这个问题。这篇文章的目的是提供一个全面的、最新的答案,供将来参考。这篇文章将重点介绍编写TensorFlow代码的高级API,以及目前推荐的方法。此外,Keras使用估计器导出模型以提供服务 这个答案将分为两部分: 如何编写输入\u fn 用于在部署模型后发送请求的客户端代码 如何编写输入\u fn 您的输入的确切细节取决于您
不幸的是,有些答案已经过时,没有一个能全面解决这个问题。这篇文章的目的是提供一个全面的、最新的答案,供将来参考。这篇文章将重点介绍编写TensorFlow代码的高级API,以及目前推荐的方法。此外,Keras使用估计器导出模型以提供服务 这个答案将分为两部分:
输入\u fn
输入\u fn
您的输入的确切细节取决于您的独特要求。例如,您可以在客户端执行图像解码和调整大小,您可以使用JPG与PNG,您可能需要特定大小的图像,除了图像之外,您可能还有其他输入,等等。我们将重点介绍一种相当通用的方法,它可以接受各种大小的各种图像格式。因此,下面的通用代码应该很容易适应任何更具体的场景
HEIGHT = 199
WIDTH = 199
CHANNELS = 1
def serving_input_receiver_fn():
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
# Optional; currently necessary for batch prediction.
key_input = tf.placeholder(tf.string, shape=[None])
key_output = tf.identity(key_input)
input_ph = tf.placeholder(tf.string, shape=[None], name='image_binary')
images_tensor = tf.map_fn(
decode_and_resize, input_ph, back_prop=False, dtype=tf.uint8)
images_tensor = tf.image.convert_image_dtype(images_tensor, dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver(
{'images': images_tensor},
{'bytes': input_ph})
如果已保存Keras模型并希望将其转换为SavedModel,请使用以下命令:
KERAS_MODEL_PATH='/path/to/model'
MODEL_DIR='/path/to/store/checkpoints'
EXPORT_PATH='/path/to/store/savedmodel'
# If you are invoking this from your training code, use `keras_model=model` instead.
estimator = keras.estimator.model_to_estimator(
keras_model_path=KERAS_MODEL_PATH,
model_dir=MODEL_DIR)
estimator.export_savedmodel(
EXPORT_PATH,
serving_input_receiver_fn=serving_input_receiver_fn)
{
"instances": [
{"bytes": {"b64": "<base64 encoded image>"}}, # image 1
{"bytes": {"b64": "<base64 encoded image>"}} # image 2 ...
]
}
发送请求(客户端代码)
发送到服务的请求主体如下所示:
KERAS_MODEL_PATH='/path/to/model'
MODEL_DIR='/path/to/store/checkpoints'
EXPORT_PATH='/path/to/store/savedmodel'
# If you are invoking this from your training code, use `keras_model=model` instead.
estimator = keras.estimator.model_to_estimator(
keras_model_path=KERAS_MODEL_PATH,
model_dir=MODEL_DIR)
estimator.export_savedmodel(
EXPORT_PATH,
serving_input_receiver_fn=serving_input_receiver_fn)
{
"instances": [
{"bytes": {"b64": "<base64 encoded image>"}}, # image 1
{"bytes": {"b64": "<base64 encoded image>"}} # image 2 ...
]
}
gcloud
将此文件转换为上述请求。下面是一些Python代码示例,可以生成适合与gcloud
一起使用的文件:
import base64
import sys
for filename in sys.argv[1:]:
with open(filename, 'rb') as f:
img_data = f.read()
print('{"bytes": {"b64": "%s"}}' % (base64.b64encode(img_data),))
(我们将此文件调用为_instances.py
)
要使用预测测试模型,请执行以下操作:
python to_instances.py img1.jpg img2.jpg > instances.json
gcloud ml-engine local predict --model-dir /path/to/model --json-instances=instances.json
调试完成后,我们可以使用gcloud ml engine models create
和gcloud ml engine versions create
将模型部署到云中,如中所述
此时,您可以使用所需的客户端向服务上的模型发送请求。请注意,这将需要身份验证令牌。我们将研究一些不同语言的示例。在每种情况下,我们都假设您的模型名为my\u model
gcloud
这与本地预测非常接近:
python to_instances.py img1.jpg img2.jpg > instances.json
gcloud ml-engine predict --model my_model --json-instances=instances.json
卷曲
我们需要像to_instances.py
这样的脚本来转换图像;让我们把它称为to_payload.py
:
import base64
import json
import sys
instances = []
for filename in sys.argv[1:]:
with open(filename, 'rb') as f:
img_data = f.read()
instances.append(base64.b64encode(img_data))
print(json.dumps({"instances": instances}))
python to_request.py img1.jpg img2.jpg > payload.json
curl-m180-xpost-v-k-H“内容类型:application/json”\
-d@payload.json\
-H“授权:承载gcloud auth打印访问令牌”\
${YOUR_PROJECT}/models/my_model:predict
蟒蛇
导入base64
PROJECT=“我的项目”
MODEL=“my\u MODEL”
img_数据=…#您的客户将有自己的方式来获取图像数据。
#创建ML引擎服务对象。
#要进行身份验证,请设置环境变量
#GOOGLE\u应用程序\u凭据=
service=googleapiclient.discovery.build('ml','v1')
名称='projects/{}/models/{}'。格式(项目,模型)
response=service.projects().predict(
name=name,
body={'instances':[{'b64':base64.encode(img_数据)}]}
).execute()
如果响应中出现“错误”:
引发运行时错误(响应['error'])
返回响应[“预测”]
Javascript/Java/C#
用Javascript/Java/C发送请求在其他地方(分别是、、和)都有介绍,这些例子应该很容易适应。上面@rhaertel的回答是我见过的对这个问题的最好的处理方法。对于那些致力于在Google Cloud ML上部署TensorFlow基于图像的模型的人,我建议大家也看看以下repo:
我花了一段时间试图将所有这些用于几个用例,并尽我所能在回购协议中记录整个过程。回购协议涵盖以下主题:
在本地训练一个完全卷积的tf.keras模型(主要是为了有一个用于测试下一部分的模型)
导出使用Cloud ML引擎的模型的示例代码
接受不同JSON输入类型的三个模型版本(1.图像转换为简单列表字符串,2.图像转换为base64编码字符串,3.指向Google存储桶中图像的URL)
通用谷歌云平台设置的说明和参考
用于为3种不同输入类型准备输入JSON文件的代码
控制台中的Google Cloud ML模型和版本创建说明
使用Google Cloud SDK调用模型预测的示例
您当前未处理此问题。另外变量image\u str\u tensor
似乎没有任何作用。@pierrom看起来这个问题已经解决了。您好,谢谢您的回答。在服务输入接收器fn
中,是否有方法使用tensorflow.keras.applications
特定于型号的预处理输入
功能?还有一种方法可以同时支持np数组列表和b64吗?很抱歉,我不熟悉tensorflow.keras.applications。我建议开始一个新的SO问题。您应该能够同时发送np数组和b64,但您可能还想就此提出另一个问题。@Rhartel80我通过本教程成功地在GCloud中运行了模型,但我得到的所有预测都非常相似,并且总是指向预测的同一类,(如果我在将模型转换为估计器之前运行模型,它会给出正确的预测),你知道可能是什么问题吗?我检查了b64图像并将它们转换回来,它们很好,我使用的模型是基于resnet50的,以防它添加信息。谢谢你,谢谢你,你的回购让我省去了很多麻烦。一个问题:当我用<