我已经成功设置了Google Cloud,并部署了预训练的ML模型,该模型采用了shape=(?, 224, 224, 3)
和dtype=float32
的输入张量(图像)。它可以很好地工作,但是在发出REST请求时效率很低,实际上应该使用base64编码的字符串。面临的挑战是我正在使用转移学习,并且无法控制原始预训练模型的输入。为了通过添加其他基础结构来解决此问题,我创建了一个小图(包装器)来处理从base64到数组的转换,并将其连接到预先训练的模型图上,从而生成一个新的单个图。小图采用带有shape=(), dtype=string
的输入张量,并返回带有shape=(224, 224, 3), dtype=float32
的张量,然后可以将其传递给原始模型。该模型无错误地编译为.pb
文件并成功部署,但是在发出Post请求时出现以下错误:
{'error': 'Prediction failed: Error during model execution: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Index out of range using input dim 0; input has only 0 dims\n\t [[{{node lambda/map/while/strided_slice}}]]")'}
发布请求正文:
{'instances': [{'b64': 'iVBORw0KGgoAAAANSUhEUgAAAOAA...'}]}`
此错误使我相信发布请求的格式不正确,无法处理base64字符串,或者我的基本转换图输入设置不正确。我可以通过在组合模型上调用预测并在本地运行代码,并将其传递为在本地构造的shape=(), dtype=string
形式的张量,并成功获得结果。
这是我用于组合两个图形的代码:
import tensorflow as tf
# Local dependencies
from myProject.classifier_models import mobilenet
from myProject.dataset_loader import dataset_loader
from myProject.utils import f1_m, recall_m, precision_m
with tf.keras.backend.get_session() as sess:
def preprocess_and_decode(img_str, new_shape=[224,224]):
#img = tf.io.decode_base64(img_str)
img = tf.image.decode_png(img_str, channels=3)
img = (tf.cast(img, tf.float32)/127.5) - 1
img = tf.image.resize_images(img, new_shape, method=tf.image.ResizeMethod.AREA, align_corners=False)
# If you need to squeeze your input range to [0,1] or [-1,1] do it here
return img
InputLayer = tf.keras.layers.Input(shape = (1,),dtype="string")
OutputLayer = tf.keras.layers.Lambda(lambda img : tf.map_fn(lambda im : preprocess_and_decode(im[0]), img, dtype="float32"))(InputLayer)
base64_model = tf.keras.Model(InputLayer,OutputLayer)
tf.keras.backend.set_learning_phase(0) # Ignore dropout at inference
transfer_model = tf.keras.models.load_model('./trained_model/mobilenet_93.h5', custom_objects={'f1_m': f1_m, 'recall_m': recall_m, 'precision_m': precision_m})
sess.run(tf.global_variables_initializer())
base64_input = base64_model.input
final_output = transfer_model(base64_model.output)
new_model = tf.keras.Model(base64_input,final_output)
export_path = '../myModels/001'
tf.saved_model.simple_save(
sess,
export_path,
inputs={'input_class': new_model.input},
outputs={'output_class': new_model.output})
技术:TensorFlow 1.13.1和Python 3.5
我看了很多相关的帖子,例如:
https://stackoverflow.com/a/50606625
https://stackoverflow.com/a/42859733
http://www.voidcn.com/article/p-okpgbnul-bvs.html(右键单击翻译为英语)
https://cloud.google.com/ml-engine/docs/tensorflow/online-predict
任何建议或反馈将不胜感激!
更新06/12/2019:
检查3个图形摘要,所有内容似乎均已正确合并
更新06/14/2019:
最终改为使用this替代策略,实施了tf.estimator