Exportando un modelo Keras como un Estimador TF: no se puede encontrar un modelo entrenado

Encontré el siguiente problema al intentar exportar un modelo de Keras como un Estimador de TensorFlow con el propósito de servir el modelo. Dado que el mismo problema también surgió en una respuesta a esta pregunta , ilustraré lo que sucede en un ejemplo de juguete y proporcionaré mi solución alternativa para fines de documentación. Este comportamiento ocurre con Tensorflow 1.12.0 y Keras 2.2.4. Esto ocurre tanto con las Keras reales como con las tf.keras .

El problema se produce cuando se intenta exportar un estimador creado a partir de un modelo de Keras con tf.keras.estimator.model_to_estimator . Al llamar a estimator.export_savedmodel , se NotFoundError un NotFoundError o un ValueError .

El siguiente código reproduce esto para un ejemplo de juguete.

Crea un modelo Keras y guárdalo:

 import keras model = keras.Sequential() model.add(keras.layers.Dense(units=1, activation='sigmoid', input_shape=(10, ))) model.compile(loss='binary_crossentropy', optimizer='sgd') model.save('./model.h5') 

A continuación, convierta el modelo en un estimador con tf.keras.estimator.model_to_estimator , agregue una función de receptor de entrada y Savedmodel en el formato de Savedmodel con estimator.export_savedmodel :

 # Convert keras model to TF estimator tf_files_path = './tf' estimator =\ tf.keras.estimator.model_to_estimator(keras_model=model, model_dir=tf_files_path) def serving_input_receiver_fn(): return tf.estimator.export.build_raw_serving_input_receiver_fn( {model.input_names[0]: tf.placeholder(tf.float32, shape=[None, 10])}) # Export the estimator export_path = './export' estimator.export_savedmodel( export_path, serving_input_receiver_fn=serving_input_receiver_fn()) 

Esto arrojará:

 ValueError: Couldn't find trained model at ./tf. 

Mi solución alternativa es la siguiente. La inspección de la carpeta ./tf deja claro que la llamada a model_to_estimator almacenó los archivos necesarios en una subcarpeta keras , mientras que export_model espera que esos archivos estén directamente en la carpeta ./tf , ya que esta es la ruta que especificamos para el argumento model_dir :

 $ tree ./tf ./tf └── keras ├── checkpoint ├── keras_model.ckpt.data-00000-of-00001 ├── keras_model.ckpt.index └── keras_model.ckpt.meta 1 directory, 4 files 

La solución simple es mover estos archivos hacia arriba en una carpeta. Esto se puede hacer con Python:

 import os import shutil from pathlib import Path def up_one_dir(path): """Move all files in path up one folder, and delete the empty folder """ parent_dir = str(Path(path).parents[0]) for f in os.listdir(path): shutil.move(os.path.join(path, f), parent_dir) shutil.rmtree(path) up_one_dir('./tf/keras') 

Lo que hará que el directorio model_dir vea así:

 $ tree ./tf ./tf ├── checkpoint ├── keras_model.ckpt.data-00000-of-00001 ├── keras_model.ckpt.index └── keras_model.ckpt.meta 0 directories, 4 files 

model_to_estimator esta manipulación entre las model_to_estimator y export_savedmodel permite exportar el modelo como se desee:

 export_path = './export' estimator.export_savedmodel( export_path, serving_input_receiver_fn=serving_input_receiver_fn()) 

INFO: tensorflow: SavedModel escrito en: ./export/temp-b’1549796240’/saved_model.pb