Экспорт модели keras в формат сохраненной модели: как исправить serve_input_fn
Я хочу использовать AI-платформу Google для развертывания моей модели keras, для которой требуется, чтобы модель была в тензорном формате SavedModel. Я сохраняю модель keras в модели оценки тензорного потока, а затем экспортирую эту модель оценки. Я сталкиваюсь с проблемами в определении моего 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
(первый слой моей нейронной сети), однако, из примеров кода, которые я видел, например, serving_receiver_input_fn
кормит все особенности в моей модели.
Как я могу решить это?
Я использую tensflow==2.0.0-бета1.
2 ответа
Мне удалось сохранить модель 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)
Я постараюсь найти ссылки, которые привели меня сюда, но я не смог их записать в то время. Я обновлю ссылки, когда найду их.
Я закончил тем, что изменил следующее:
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')
}
и я смог получить папку с моим сохраненным_моделем.pb.