TensorFlow在Cloud ML引擎上将图像作为base64编码字符串提供服务 如何实现TensorFlow作为base64编码字符串的图像输入函数,并在Cloud ML引擎上进行预测
我计划在对模型进行预培训后将其部署到云机器学习(ML)引擎上,但我不知道如何实现服务输入功能 此外,我试图避免使用TensorFlow低级API,只关注TensorFlow高级API(TensorFlow Estimator)。下面的代码块是我正在处理的示例代码TensorFlow在Cloud ML引擎上将图像作为base64编码字符串提供服务 如何实现TensorFlow作为base64编码字符串的图像输入函数,并在Cloud ML引擎上进行预测,tensorflow,tensorflow-serving,google-cloud-ml,tensorflow-estimator,Tensorflow,Tensorflow Serving,Google Cloud Ml,Tensorflow Estimator,我计划在对模型进行预培训后将其部署到云机器学习(ML)引擎上,但我不知道如何实现服务输入功能 此外,我试图避免使用TensorFlow低级API,只关注TensorFlow高级API(TensorFlow Estimator)。下面的代码块是我正在处理的示例代码 本节用于图像输入功能 def imgs_input_fn(filenames, labels=None, perform_shuffle=False, repeat_count=1, batch_size=1): def _p
本节用于图像输入功能
def imgs_input_fn(filenames, labels=None, perform_shuffle=False, repeat_count=1, batch_size=1):
def _parse_function(filename, label):
image_string = tf.read_file(filename)
image = tf.image.decode_image(image_string, channels=3)
image.set_shape([None, None, None])
image = tf.image.resize_images(image, [150, 150])
image = tf.subtract(image, 116.779) # Zero-center by mean pixel
image.set_shape([150, 150, 3])
image = tf.reverse(image, axis=[2]) # 'RGB'->'BGR'
d = dict(zip([input_name], [image])), label
return d
if labels is None:
labels = [0]*len(filenames)
labels=np.array(labels)
# Expand the shape of "labels" if necessary
if len(labels.shape) == 1:
labels = np.expand_dims(labels, axis=1)
filenames = tf.constant(filenames)
labels = tf.constant(labels)
labels = tf.cast(labels, tf.float32)
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(_parse_function)
if perform_shuffle:
# Randomizes input using a window of 256 elements (read into memory)
dataset = dataset.shuffle(buffer_size=256)
dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
dataset = dataset.batch(batch_size) # Batch size to use
iterator = dataset.make_one_shot_iterator()
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels
我想创建一个服务输入函数
def serving_input_receiver_fn():
''' CODE HERE!'''
return tf.estimator.export.ServingInputReceiver(feature_placeholders, feature_placeholders)
培训和评估模型
train_spec = tf.estimator.TrainSpec(input_fn=lambda: imgs_input_fn(train_files,
labels=train_labels,
perform_shuffle=True,
repeat_count=1,
batch_size=20),
max_steps=500)
exporter = tf.estimator.LatestExporter('Servo', serving_input_receiver_fn)
eval_spec = tf.estimator.EvalSpec(input_fn=lambda: imgs_input_fn(val_files,
labels=val_labels,
perform_shuffle=False,
batch_size=1),
exporters=exporter)
tf.estimator.train_and_evaluate(est_imageclassifier, train_spec, eval_spec)
如果我理解正确,那么在Cloud ML引擎上获取预测的输入文件示例应该如下
{\"image_bytes\": {\"b64\": \"YQ==\"}}
{\"image_bytes\": {\"b64\": \"YQ==\"}}
.
.
request.json
{"b64": "9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHJC...”}
{"b64": "9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHJC...”}
及
如果您一直在阅读,并且有一些想法,请您建议我如何为这个特定案例实现服务输入功能
多谢各位
第二篇文章-更新到目前为止我所做的事情。 根据sdcbr的评论,下面是我的服务输入接收器fn() 对于_img_string_to _tensor()函数或(prepare_image function),我想我应该像训练模型一样进行图像准备 imgs_input_fn()=>_parse_function() 在我训练模型并将保存的模型部署到Cloud ML引擎之后。我的输入图像已准备成如下所示的格式
{"image_bytes": {"b64": "YQ=="}}
但我在通过gcloud得到预测后发现了错误
gcloud ml-engine predict --model model_1 \
--version v1 \
--json-instances request.json
{“错误”:“预测失败:模型执行期间出错:
堕胎错误(代码=状态代码。参数无效,详细信息=\”断言
失败:[无法将字节解码为JPEG、PNG、GIF或BMP]\n\t
[{{node
map/while/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert}=
断言[T=[DT_字符串],汇总=3,
_device=\“/job:localhost/replica:0/task:0/device:CPU:0\”](map/while/decode\u image/cond\u jpeg/cond\u png/cond\u gif/is\u bmp,
map/while/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert/data_0)]\”
}
我在字符串到张量函数中做错了什么吗?
你能给我解释一下这个tf.placeholder吗
input_ph = tf.placeholder(tf.string, shape=[None])
对于上面的代码,您使用shape=[1],但我认为它应该是shape=[None]。以下几点应该可以:
def serving_input_receiver_fn():
def prepare_image(image_str_tensor):
image = tf.image.decode_image(image_str_tensor,
channels=3)
image = tf.image.resize_images(image, [150, 150])
return image
# Ensure model is batchable
# https://stackoverflow.com/questions/52303403/
input_ph = tf.placeholder(tf.string, shape=[None])
images_tensor = tf.map_fn(
prepare_image, input_ph, back_prop=False, dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver(
{model.input_names[0]: images_tensor},
{'image_bytes': input_ph})
您可以在prepare_image
功能中添加额外的预处理。注意,images\u tensor
应该映射到tf.keras
模型中应该接收输入的层的名称上
另见和相关问题 回答!
从sdcbr的评论来看,这是我寻找的正确答案,但问题是我刚刚发现了为什么它不起作用
根据误差,
{“错误”:“预测失败:模型执行期间出错:
堕胎错误(代码=状态代码。参数无效,详细信息=\”断言
失败:[无法将字节解码为JPEG、PNG、GIF或BMP]\n\t
[{{node
map/while/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert}=
断言[T=[DT_字符串],汇总=3,
_device=\“/job:localhost/replica:0/task:0/device:CPU:0\”](map/while/decode\u image/cond\u jpeg/cond\u png/cond\u gif/is\u bmp,
map/while/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert/data_0)]\”
}
这是因为request.json类似于
{\"image_bytes\": {\"b64\": \"YQ==\"}}
{\"image_bytes\": {\"b64\": \"YQ==\"}}
.
.
那应该是
{"image_bytes": {"b64": "YQ=="}}
{"image_bytes": {"b64": "YQ=="}}
.
.
在我清理并移除所有反斜杠后,它可以工作了强>
这是你需要仔细检查的。如果在IPython笔记本上打印,则不会显示反斜杠。我必须在编辑器上打开它,然后才能找到真正的问题。非常感谢您的回复和建议。这对我来说意义重大。然而,我仍然被困在这个问题上。我已经在下面发布了“第二篇文章-更新我到目前为止所做的。”我刚刚解决了这个问题!再次感谢你的回答。这是对的!我的输入Json是错误的。是什么导致了\slash,我们如何首先避免它们,而不必纠正输出?
{\"image_bytes\": {\"b64\": \"YQ==\"}}
{\"image_bytes\": {\"b64\": \"YQ==\"}}
.
.
{"image_bytes": {"b64": "YQ=="}}
{"image_bytes": {"b64": "YQ=="}}
.
.