Python gcloud ml引擎返回大文件错误
我有一个经过训练的模型,它接受了一些较大的输入。我通常将其作为形状的numpy数组(1473473,3)来执行。当我把它转换成JSON时,我得到了一个大约9.2MB的文件。即使我将其转换为JSON文件的base64编码,输入仍然相当大 ml engine predict在发送JSON文件时拒绝我的请求,错误如下:Python gcloud ml引擎返回大文件错误,python,json,numpy,predict,google-cloud-ml,Python,Json,Numpy,Predict,Google Cloud Ml,我有一个经过训练的模型,它接受了一些较大的输入。我通常将其作为形状的numpy数组(1473473,3)来执行。当我把它转换成JSON时,我得到了一个大约9.2MB的文件。即使我将其转换为JSON文件的base64编码,输入仍然相当大 ml engine predict在发送JSON文件时拒绝我的请求,错误如下: (gcloud.ml-engine.predict) HTTP request failed. Response: { "error": { "code": 400,
(gcloud.ml-engine.predict) HTTP request failed. Response: {
"error": {
"code": 400,
"message": "Request payload size exceeds the limit: 1572864 bytes.",
"status": "INVALID_ARGUMENT"
}
}
看起来我无法将任何超过1.5MB大小的数据发送到ML引擎。这肯定是一件事吗?其他人是如何对大数据进行在线预测的?我必须启动一个计算引擎,还是会遇到同样的问题
编辑:
我从Keras模型开始,尝试导出到tensorflow服务。我将Keras模型加载到一个名为“model”的变量中,并定义了一个目录“export\u path”。我构建tensorflow服务模型如下:
signature = predict_signature_def(inputs={'input': model.input},
outputs={'output': model.output})
builder = saved_model_builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
sess=sess,
tags=[tag_constants.SERVING],
signature_def_map={
signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature
}
)
builder.save()
def serving_input_fn():
# Note: only handles one image at a time ...
inputs = {'imageurl': tf.placeholder(tf.string, shape=())}
filename = tf.squeeze(inputs['imageurl']) # make it a scalar
image = read_and_preprocess(filename)
# make the outer dimension unknown (and not 1)
image = tf.placeholder_with_default(image, shape=[None, HEIGHT, WIDTH, NUM_CHANNELS])
features = {'image' : image}
return tf.estimator.export.ServingInputReceiver(features, inputs)
输入如何查找此签名?JSON会像{'input':''}一样,其中文件是(1473473,3)numpy数组吗
第二次编辑:
查看Lak Lakshmanan发布的代码,我尝试了一些不同的变体,但没有成功地读取图像url并尝试以这种方式解析文件。我尝试了以下方法,但没有成功:
inputs = {'imageurl': tf.placeholder(tf.string, shape=[None])}
filename = tf.squeeze(inputs['imageurl'])
image = read_and_preprocess(filename)#custom preprocessing function
image = tf.placeholder_with_default(image, shape=[None, HEIGHT, WIDTH, NUM_CHANNELS])
features = {'image' : image}
inputs.update(features)
signature = predict_signature_def(inputs= inputs,
outputs={'output': model.output})
with K.get_session() as session:
"""Convert the Keras HDF5 model into TensorFlow SavedModel."""
builder = saved_model_builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
sess=session,
tags=[tag_constants.SERVING],
signature_def_map={
signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature
}
)
builder.save()
我认为问题在于从imageurl占位符到构建功能的映射。思考我做错了什么?我通常做的是让json引用Google云存储中的文件。用户首先必须将文件上传到地面军事系统,然后调用预测。但这种方法还有其他优点,因为存储实用程序允许并行和多线程上传 Keras/TensorFlow 2.0 在TensorFlow 2.0中,这是服务函数的外观:
@tf.function(input_signature=[tf.TensorSpec([None,], dtype=tf.string)])
def predict_bytes(img_bytes):
input_images = tf.map_fn(
preprocess,
img_bytes,
fn_output_signature=tf.float32
)
batch_pred = model(input_images) # same as model.predict()
top_prob = tf.math.reduce_max(batch_pred, axis=[1])
pred_label_index = tf.math.argmax(batch_pred, axis=1)
pred_label = tf.gather(tf.convert_to_tensor(CLASS_NAMES), pred_label_index)
return {
'probability': top_prob,
'flower_type_int': pred_label_index,
'flower_type_str': pred_label
}
@tf.function(input_signature=[tf.TensorSpec([None,], dtype=tf.string)])
def predict_filename(imageurl):
img_bytes = tf.map_fn(
tf.io.read_file,
filenames
)
result = predict_bytes(img_bytes)
result['filename'] = filenames
return result
shutil.rmtree('export', ignore_errors=True)
os.mkdir('export')
model.save('export/flowers_model3',
signatures={
'serving_default': predict_filename,
'from_bytes': predict_bytes
})
完整代码如下:
TensorFlow 1.0
在TensorFlow 1.0中,代码如下所示:
signature = predict_signature_def(inputs={'input': model.input},
outputs={'output': model.output})
builder = saved_model_builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
sess=sess,
tags=[tag_constants.SERVING],
signature_def_map={
signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature
}
)
builder.save()
def serving_input_fn():
# Note: only handles one image at a time ...
inputs = {'imageurl': tf.placeholder(tf.string, shape=())}
filename = tf.squeeze(inputs['imageurl']) # make it a scalar
image = read_and_preprocess(filename)
# make the outer dimension unknown (and not 1)
image = tf.placeholder_with_default(image, shape=[None, HEIGHT, WIDTH, NUM_CHANNELS])
features = {'image' : image}
return tf.estimator.export.ServingInputReceiver(features, inputs)
完整代码如下:
我在AI平台上运行带有大图像的预测时遇到了相同的错误。我解决了有效载荷限制问题,首先将图像编码为PNG格式,然后再将其发送到AI平台 我的Keras模型没有将PNG编码的图像作为输入,因此我需要将Keras模型转换为Tensorflow估计器,并定义其包含的代码,以将PNG编码的图像解码回模型期望的格式 模型需要两个不同灰度图像作为输入时的示例代码:
将tensorflow导入为tf
从tensorflow.keras.estimator导入模型到估计量
来自tensorflow.estimator.export-import Serving InputReceiver
IMG\u PNG\u 1=“编码的\u PNG\u图像\u 1”
IMG\u PNG\u 2=“编码的\u PNG\u图像\u 2”
def create_SERVICE_fn(图像高度、图像宽度):
def服务_输入_fn():
def预处理\u png(png编码\u img):
img=tf.重塑(png\u编码的\u img,shape=())
img=tf.io.decode\u png(img,通道=1)
img=img/255
img=tf.展开尺寸(img,轴=0)
返回img
#接收器_张量仅在未定义形状参数时起作用
接收器张量={
IMG_PNG_1:tf.compat.v1.placeholder(tf.string),
IMG_PNG_2:tf.compat.v1.placeholder(tf.string)
}
img\u 1=预处理\u png(png\u编码的\u img=接收张量[img\u png\u 1])
img\u 2=预处理\u png(png\u编码的\u img=接收张量[img\u png\u 2])
输入带有默认值的\u img\u 1=tf.compat.v1.placeholder\u(img\u 1,形状=[无,图像高度,图像宽度,1])
输入带有默认值的\u img\u 2=tf.compat.v1.placeholder\u(img\u 2,形状=[无,图像高度,图像宽度,1])
特征={
“模型输入1”:输入1,
“模型输入2”:输入2,
}
返回服务输入接收器(特征=特征,接收器张量=接收器张量)
返回服务\u输入\u fn
#将训练的Keras模型转化为估计量
估计器=模型对模型估计器(keras\u模型=模型)
保存\u path=“保存的模型的位置”
导出路径=估计器。导出保存的模型(
export\u dir\u base=保存路径,
服务\输入\接收器\ fn=创建\服务\ fn(1000,1000)
)
谢谢你的回复,拉克。因此,我的用例实际上是将h5文件中带有权重的Keras模型转换为tensorflow服务。我已经做过这样的工作,比如使用model.input作为输入,使用model.output作为输出,将其输入到一个predict_signature_def,并将其提供给一个SavedModelBuilder。我(很明显)不习惯转换过程,我想知道如何将服务输入转换成我可以构建的模型。我将在编辑我的问题时添加我当前的导出功能。谢谢@lak,是否也可以使用谷歌云存储进行在线预测,或者您的解决方案仅适用于批量预测?也适用于在线预测。只需让服务函数将文件名作为参数,然后调用tf.io.read_file()获取图像字节