【问题标题】:Export keras model to tf savedModel format: how to fix serving_input_fn将 keras 模型导出为 tf savedModel 格式:如何修复 serving_input_fn
【发布时间】:2019-11-19 03:00:24
【问题描述】:

我想利用 google 的 AI 平台来部署我的 keras 模型,这需要模型采用 tensorflow SavedModel 格式。我将 keras 模型保存到 tensorflow 估计器模型,然后导出这个估计器模型。我在定义 serving_input_receiver_fn 时遇到了问题。

这是我的模型的总结:

Model: "model_49"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_49 (InputLayer)        [(None, 400, 254)]        0
_________________________________________________________________
gru_121 (GRU)                (None, 400, 64)           61248
_________________________________________________________________
gru_122 (GRU)                (None, 64)                24768
_________________________________________________________________
dropout_73 (Dropout)         (None, 64)                0
_________________________________________________________________
1M (Dense)                   (None, 1)                 65
=================================================================
Total params: 86,081
Trainable params: 86,081
Non-trainable params: 0
_________________________________________________________________

这是我遇到的错误:

KeyError: "The dictionary passed into features does not have the expected 
inputs keys defined in the keras model.\n\tExpected keys: 
{'input_49'}\n\tfeatures keys: {'col1','col2', ..., 'col254'}

下面是我的代码。

def serving_input_receiver_fn():
    feature_placeholders = {
        column.name: tf.placeholder(tf.float64, [None]) for column in INPUT_COLUMNS
    }

    # feature_placeholders = {
    #     'input_49': tf.placeholder(tf.float64, [None])
    # }
    features = {
        key: tf.expand_dims(tensor, -1)
        for key, tensor in feature_placeholders.items()
    }

    return tf.estimator.export.ServingInputReceiver(features, feature_placeholders)

def run():
    h5_model_file = '../models/model2.h5'
    json_model_file = '../models/model2.json'
    model = get_keras_model(h5_model_file, json_model_file)
    print(model.summary())

    estimator_model = tf.keras.estimator.model_to_estimator(keras_model=model, model_dir='estimator_model')
    export_path = estimator_model.export_saved_model('export', 
    serving_input_receiver_fn=serving_input_receiver_fn)

似乎我的模型需要一个单一的特征键:input_49(我的神经网络的第一层),但是,例如,从the code samples I've seenserving_receiver_input_fn 将所有特征的字典输入到我的模型中。

我该如何解决这个问题?

我正在使用 tensorflow==2.0.0-beta1。

【问题讨论】:

  • AI Platform 目前支持 TF 1.14。它还不支持 TF beta 2.0。 GA 版将支持 TF 2.0。

标签: tensorflow google-cloud-ml tf.keras gcp-ai-platform-notebook


【解决方案1】:

我已经成功地保存了一个 Keras 模型并使用 TF Serving 使用 tf.saved_model.Builder() 对象来托管它。我不确定这是否可以轻松推广到您的应用程序,但以下是对我有用的方法,尽可能通用。

# Set the path where the model will be saved.
export_base_path = os.path.abspath('models/versions/')
model_version = '1'
export_path = os.path.join(tf.compat.as_bytes(export_base_path),
                           tf.compat.as_bytes(model_version))
# Make the model builder.
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
# Define the TensorInfo protocol buffer objects that encapsulate our
# input/output tensors.
# Note you can have a list of model.input layers, or just a single model.input
# without any indexing. I'm showing a list of inputs and a single output layer.
# Input tensor info.
tensor_info_input0 = tf.saved_model.utils.build_tensor_info(model.input[0])
tensor_info_input1 = tf.saved_model.utils.build_tensor_info(model.input[1])
# Output tensor info.
tensor_info_output = tf.saved_model.utils.build_tensor_info(model.output)

# Define the call signatures used by the TF Predict API. Note the name
# strings here should match what the layers are called in your model definition.
# Might have to play with that because I forget if it's the name parameter, or
# the actual object handle in your code.
prediction_signature = (
    tf.saved_model.signature_def_utils.build_signature_def(
        inputs={'input0': tensor_info_input0, 'input1': tensor_info_input1},
        outputs={'prediction': tensor_info_output},
        method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))

# Now we build the SavedModel protocol buffer object and then save it.
builder.add_meta_graph_and_variables(sess,
                                     [tf.saved_model.tag_constants.SERVING],
                                     signature_def_map={'predict': prediction_signature})
builder.save(as_text=True)

我会尝试找到让我来到这里的参考资料,但当时我没有记下它们。找到链接后我会更新。

【讨论】:

  • 谢谢,我想我会试试这个。
【解决方案2】:

我最终更改了以下内容:

feature_placeholders = {
    column.name: tf.placeholder(tf.float64, [None]) for column in INPUT_COLUMNS
}

对此:

   feature_placeholders = {
    'input_49': tf.placeholder(tf.float32, (254, None), name='input_49')
}

我能够使用我的 saved_model.pb 获得一个文件夹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多