我正在尝试使用Amazon Sagemaker训练模型,并且希望与Tensorflow服务一起使用。为此,我将模型下载到Tensorflow服务docker,并尝试从那里服务。
Sagemaker的训练和评估阶段已完成,没有错误,但是当我将模型加载到Tensorflow服务服务器并尝试调用它时,我得到Tensorflow服务错误,这表明我的模型没有定义的输入。可以看出,正在提供模型的Tensorflow服务服务器。
出于调试目的,我尝试将其与Sagemaker一起使用,但是我得到的只是一条模糊的错误消息,提示我在调用端点时出错。
我认为问题在于我没有很好地定义serving_input_fn或调用错误或两者兼而有之。有人可以帮忙吗?
curl -d '{"instances": [{"col3": 1.0}]}' -X POST http://localhost:8501/v1/models/test_model:predict
{ "error": "Failed to process element: 0 key: col3 of \'instances\' list. Error: Invalid argument: JSON object: does not have named input: col3" }%
import os
import tensorflow as tf
from tensorflow.python.ops import nn
TRAIN_FILENAME = 'test.csv'
TEST_FILENAME = 'train.csv'
NODES_IN_LAYER = 6
LAYERS_NUM = 10
NUM_LINES_TO_SKIP = 1
CSV_COLUMNS = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7', 'col8', 'label']
RECORDS_DEFAULTS = [[0], [0], [0.0], [0.0], [0], [0.0], [0.0], [0], [0.0]]
BATCH_SIZE = 32
FEATURE_SPEC = {
'col3': tf.FixedLenFeature(dtype=tf.float32, shape=[]),
}
def estimator_fn(run_config, params):
feature_columns = [
tf.feature_column.numeric_column('col3')]
return tf.estimator.DNNRegressor(feature_columns=feature_columns,
hidden_units=[NODES_IN_LAYER] * LAYERS_NUM,
activation_fn=nn.tanh,
config=run_config)
def serving_input_fn(params):
return tf.estimator.export.build_raw_serving_input_receiver_fn(FEATURE_SPEC)
def train_input_fn(training_dir, params):
"""Returns input function that would feed the model during training"""
return _generate_input_fn(training_dir, TRAIN_FILENAME)
def eval_input_fn(training_dir, params):
"""Returns input function that would feed the model during evaluation"""
return _generate_input_fn(training_dir, TEST_FILENAME)
def parse_csv(line):
columns = tf.decode_csv(line, record_defaults=RECORDS_DEFAULTS)
line_features = dict(zip(CSV_COLUMNS, columns))
line_label = line_features.pop('label')
return {'col3': line_features.pop('col3')}, line_label
def _generate_input_fn(training_dir, training_filename):
filename = os.path.join(training_dir, training_filename)
dataset = tf.data.TextLineDataset(filename)
dataset = dataset.skip(NUM_LINES_TO_SKIP).map(parse_csv).batch(BATCH_SIZE)
return dataset
答案 0 :(得分:0)
serving_input_fn定义输入中预期的张量的名称以及形状。因此,在您的情况下,请求应为{'col3':[]}的字典。
当前使用json时字典的反序列化行为当前也存在问题,在此问题中进行了描述:https://github.com/aws/sagemaker-tensorflow-container/issues/71
此拉出请求一旦出现,应该可以解决该问题:https://github.com/aws/sagemaker-tensorflow-container/pull/76
答案 1 :(得分:0)
拨打regress
而不是predict
curl -d '{"examples": [{"col3": 1.0}]}' -X POST http://localhost:8501/v1/models/test_model:regress
答案 2 :(得分:0)
尝试首先使用saved_model_cli
检查导出的模型,以确保输入和输出均符合预期:
saved_model_cli show --dir . --tag_set serve --signature_def serving_default
您正在使用罐头估算器,因此您应该看到类似以下内容的
:The given SavedModel SignatureDef contains the following input(s):
inputs['examples'] tensor_info:
dtype: DT_STRING
shape: (-1)
name: input_example_tensor:0
The given SavedModel SignatureDef contains the following output(s):
outputs['output'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 1)
name: groupwise_dnn_v2/accumulate_scores/truediv:0
其中输入是ProtoBuf示例,输出是一批回归标量。
现在,您可以尝试使用CLI查询模型:
saved_model_cli run \
--dir . \
--tag_set serve \
--signature_def predict \
--input_examples 'examples=[{"col3":[1.0]},{"col3":[2.0]},{"col3":[3.0]}]'
如果可以从CLI查询模型,则可以帮助消除问题中的一些变量。
答案 3 :(得分:0)
当模型的输入与您输入的输入之间不匹配时,会发生此错误。
最好的方法是通过发出以下请求来检查服务模型的输入:
http://<ip>:8501/v1/models/bilstm/metadata
它将返回类似的输出
{
"model_spec": {
"name": "bilstm",
"signature_name": "",
"version": "1"
},
"metadata": {
"signature_def": {
"signature_def": {
"serving_default": {
"inputs": {
"sequence_length": {
"dtype": "DT_INT32",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
}
],
"unknown_rank": false
},
"name": "sequence_lengths:0"
},
"word_ids": {
"dtype": "DT_INT32",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
},
{
"size": "-1",
"name": ""
}
],
"unknown_rank": false
},
"name": "word_ids:0"
},
"lr": {
"dtype": "DT_FLOAT",
"tensor_shape": {
"dim": [],
"unknown_rank": false
},
"name": "lr:0"
},
"word_lengths": {
"dtype": "DT_INT32",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
},
{
"size": "-1",
"name": ""
}
],
"unknown_rank": false
},
"name": "word_lengths:0"
},
"char_ids": {
"dtype": "DT_INT32",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
},
{
"size": "-1",
"name": ""
},
{
"size": "-1",
"name": ""
}
],
"unknown_rank": false
},
"name": "char_ids:0"
},
"dropout": {
"dtype": "DT_FLOAT",
"tensor_shape": {
"dim": [],
"unknown_rank": false
},
"name": "dropout:0"
}
},
"outputs": {
"scores": {
"dtype": "DT_FLOAT",
"tensor_shape": {
"dim": [
{
"size": "-1",
"name": ""
},
{
"size": "-1",
"name": ""
},
{
"size": "30",
"name": ""
}
],
"unknown_rank": false
},
"name": "bi-lstm-crf/output_ff/BiasAdd:0"
}
},
"method_name": "tensorflow/serving/predict"
}
}
}
}
}