如何将图形导出到 Tensorflow Serving 以便输入为 b64?
How do I export a graph to Tensorflow Serving so that the input is b64?
我有一个 Keras 图,它具有形状为 (?, 224, 224, 3) 的 float32 张量,我想将其导出到 Tensorflow Serving,以便使用 RESTful 进行预测。问题是我无法输入张量,而是编码了 b64 字符串,因为这是 REST API 的限制。这意味着在导出图形时,输入需要是需要解码的字符串。
如何在不重新训练图本身的情况下"inject"将新输入转换为旧张量?我试过几个例子 [1].
我目前有以下导出代码:
image = tf.placeholder(dtype=tf.string, shape=[None], name='source')
signature = predict_signature_def(inputs={'image_bytes': image},
outputs={'output': model.output})
我不知何故需要找到一种将图像转换为 model.input 的方法,或者一种使模型输出连接到图像的方法。
如有任何帮助,我们将不胜感激!
您可以使用 tf.decode_base64
:
image = tf.placeholder(dtype=tf.string, shape=[None], name='source')
image_b64decoded = tf.decode_base64(image)
signature = predict_signature_def(inputs={'image_bytes': image_b64decoded},
outputs={'output': model.output})
编辑:
如果需要使用tf.image.decode_image
, you can get it to work with multiple inputs using tf.map_fn
:
image = tf.placeholder(dtype=tf.string, shape=[None], name='source')
image_b64decoded = tf.decode_base64(image)
image_decoded = tf.map_fn(tf.image.decode_image, image_b64decoded, dtype=tf.uint8)
当然,只要图像具有相同的尺寸,这就可以工作。然而,结果是一个形状完全未知的张量,因为 tf.image.decode_image
可以根据图像类型输出不同数量的维度。您可以重塑它或使用另一个 tf.image.decode_*
调用,这样至少您在张量中有一个已知的维数。
创建 export_model 可能是一种更简单的方法。
One example in tensorflow.org
- 具有 float32、形状 (?, 224, 224, 3) 张量的 Keras 图
model = ...
- 定义一个函数来预处理 b64 图像
def preprocess_input(base64_input_bytes):
def decode_bytes(img_bytes):
img = tf.image.decode_jpeg(img_bytes, channels=3)
img = tf.image.resize(img, (224, 224))
img = tf.image.convert_image_dtype(img, tf.float32)
return img
base64_input_bytes = tf.reshape(base64_input_bytes, (-1,))
return tf.map_fn(lambda img_bytes:
decode_bytes(img_bytes),
elems=base64_input_bytes,
fn_output_signature=tf.float32)
- 导出服务模型
serving_inputs = tf.keras.layers.Input(shape=(), dtype=tf.string, name='b64_input_bytes')
serving_x = tf.keras.layers.Lambda(preprocess_input, name='decode_image_bytes')(serving_inputs)
serving_x = model(serving_x)
serving_model = tf.keras.Model(serving_inputs, serving_x)
tf.saved_model.save(serving_model, serving_model_path)
- 服务
import requests
data = json.dumps({"signature_name": "serving_default", "instances": [{"b64_input_bytes": {"b64": b64str_1}}, {"b64_input_bytes": {"b64": b64str_2}}]})
headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/{model_name}:predict', data=data, headers=headers)
predictions = json.loads(json_response.text)['predictions']
我有一个 Keras 图,它具有形状为 (?, 224, 224, 3) 的 float32 张量,我想将其导出到 Tensorflow Serving,以便使用 RESTful 进行预测。问题是我无法输入张量,而是编码了 b64 字符串,因为这是 REST API 的限制。这意味着在导出图形时,输入需要是需要解码的字符串。
如何在不重新训练图本身的情况下"inject"将新输入转换为旧张量?我试过几个例子 [1]
我目前有以下导出代码:
image = tf.placeholder(dtype=tf.string, shape=[None], name='source')
signature = predict_signature_def(inputs={'image_bytes': image},
outputs={'output': model.output})
我不知何故需要找到一种将图像转换为 model.input 的方法,或者一种使模型输出连接到图像的方法。
如有任何帮助,我们将不胜感激!
您可以使用 tf.decode_base64
:
image = tf.placeholder(dtype=tf.string, shape=[None], name='source')
image_b64decoded = tf.decode_base64(image)
signature = predict_signature_def(inputs={'image_bytes': image_b64decoded},
outputs={'output': model.output})
编辑:
如果需要使用tf.image.decode_image
, you can get it to work with multiple inputs using tf.map_fn
:
image = tf.placeholder(dtype=tf.string, shape=[None], name='source')
image_b64decoded = tf.decode_base64(image)
image_decoded = tf.map_fn(tf.image.decode_image, image_b64decoded, dtype=tf.uint8)
当然,只要图像具有相同的尺寸,这就可以工作。然而,结果是一个形状完全未知的张量,因为 tf.image.decode_image
可以根据图像类型输出不同数量的维度。您可以重塑它或使用另一个 tf.image.decode_*
调用,这样至少您在张量中有一个已知的维数。
创建 export_model 可能是一种更简单的方法。 One example in tensorflow.org
- 具有 float32、形状 (?, 224, 224, 3) 张量的 Keras 图
model = ...
- 定义一个函数来预处理 b64 图像
def preprocess_input(base64_input_bytes):
def decode_bytes(img_bytes):
img = tf.image.decode_jpeg(img_bytes, channels=3)
img = tf.image.resize(img, (224, 224))
img = tf.image.convert_image_dtype(img, tf.float32)
return img
base64_input_bytes = tf.reshape(base64_input_bytes, (-1,))
return tf.map_fn(lambda img_bytes:
decode_bytes(img_bytes),
elems=base64_input_bytes,
fn_output_signature=tf.float32)
- 导出服务模型
serving_inputs = tf.keras.layers.Input(shape=(), dtype=tf.string, name='b64_input_bytes')
serving_x = tf.keras.layers.Lambda(preprocess_input, name='decode_image_bytes')(serving_inputs)
serving_x = model(serving_x)
serving_model = tf.keras.Model(serving_inputs, serving_x)
tf.saved_model.save(serving_model, serving_model_path)
- 服务
import requests
data = json.dumps({"signature_name": "serving_default", "instances": [{"b64_input_bytes": {"b64": b64str_1}}, {"b64_input_bytes": {"b64": b64str_2}}]})
headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/{model_name}:predict', data=data, headers=headers)
predictions = json.loads(json_response.text)['predictions']