Path: blob/master/site/es-419/guide/saved_model.ipynb
25115 views
Copyright 2018 The TensorFlow Authors.
Uso del formato SavedModel
Un SavedModel contiene un programa completo de TensorFlow, que incluye los parámetros entrenados (es decir, las tf.Variable
) y los cálculos. No requiere del código con el que se creó el modelo original para ejecutarse. Esta virtud hace que resulte útil compartirlo o implementarlo con TFLite, TensorFlow.js, TensorFlow Serving o TensorFlow Hub.
Un modelo se puede guardar y cargar en el formato SavedModel con las siguientes API:
La API
tf.saved_model
de bajo nivel. En este documento se describe en detalle cómo usar esta API.Guardar:
tf.saved_model.save(model, path_to_dir)
Cargar:
model = tf.saved_model.load(path_to_dir)
API
tf.keras.Model
de alto nivel. Consulte la guía sobre el guardado y serializado con keras.Si simplemente desea guardar o cargar pesos durante el entrenamiento, consulte la guía sobre puntos de verificación.
Advertencia: Los modelos TensorFlow son código y hay que tener cuidado con que dicho código no sea confiable. Aprenda más en la sección sobre cómo usar TensorFlow de forma segura.
Creación de un SavedModel con Keras
Obsoleto: Para los objetos Keras, se recomienda usar el nuevo formato de alto nivel .keras
y tf.keras.Model.export
, como se demuestra en la guía aquí. El formato SavedModel de bajo nivel sigue siendo compatible con el código existente.
A modo de introducción breve, en esta sección se exporta un modelo keras previamente entrenado y se realizan solicitudes de clasificación con él. En el resto de la guía se completan los detalles y se analizan otras formas de crear SavedModels.
Usaremos una imagen de Grace Hopper como ejemplo y un modelo de clasificación previamente entrenado de Keras, ya que es fácil de usar. Los modelos personalizados también funcionan; hablaremos en detalle sobre ellos más adelante.
La principal predicción para esta imagen es el "uniforme militar".
La ruta de guardado sigue una convención usada por TensorFlow Serving donde el último componente de la ruta (aquí 1/
) es un número de versión para su modelo. Permite usar herramientas como TensorFlow Serving para razonar sobre la frescura relativa.
El SavedModel se puede volver a cargar en Python con tf.saved_model.load
y, entonces, ver cómo se clasifica la imagen de la almirante Hopper.
Las firmas importadas siempre devuelven diccionarios. Para personalizar los nombres y las claves del diccionario de salida, consulte Especificación de las firmas durante la exportación.
Al ejecutar la inferencia del SavedModel se obtiene el mismo resultado del modelo original.
Ejecución de SavedModel en TensorFlow Serving
Los SavedModel se pueden usar desde Python (más adelante se brindan más detalles), pero los entornos de producción normalmente usan un servicio exclusivo para la inferencia sin ejecutar código Python. Se configura con facilidad a partir de un SavedModel con TensorFlow Serving.
Para conocer un ejemplo completo de servicio de TensorFlow, consulte Entrene y sirva un modelo de TensorFlow con TensorFlow Serving.
El formato SavedModel en disco
Un SavedModel es un directorio que contiene firmas serializadas y el estado necesita ejecutarlas, incluidos los valores de variables y vocabularios.
El archivo saved_model.pb
almacena el programa de TensorFlow real, o el modelo, y configura un conjunto de firmas con nombre. Con cada una de ellas se identifica una función que acepta las entradas del tensor y produce las salidas de tensor.
Los SavedModels pueden contener múltiples variantes del modelo (múltiples v1.MetaGraphDefs
, identificados con la etiqueta --tag_set
para saved_model_cli
), pero no es lo más común. Las API que crean múltiples variantes de un modelo incluyen tf.Estimator.experimental_export_all_saved_models
y en TensorFlow, 1.x tf.saved_model.Builder
.
El directorio de variables
contiene un punto de verificación de entrenamiento estándar (consulte la guía para entrenamiento de puntos de verificación).
El directorio assets
contiene archivos que usa el grafo de TensorFlow; por ejemplo, los archivos de texto que se usan para inicializar las tablas de vocabulario. No se usa en este ejemplo.
SavedModels puede tener un directorio assets.extra
para cualquier archivo que no use el grafo de TensorFlow. Por ejemplo, la información para consumidores sobre qué hacer con el SavedModel. TensorFlow mismo no usa este directorio.
El archivo fingerprint.pb
contiene la huella digital de un SavedModel, que está compuesta de varias funciones hash de 64 bits que identifican de forma única el contenido del SavedModel. La API de huella, por el momento, es experimental, pero tf.saved_model.experimental.read_fingerprint
se puede usar para leer la huella digital de SavedModel en un objeto tf.saved_model.experimental.Fingerprint
.
Guardado de un modelo personalizado
tf.saved_model.save
permite guardar objetos tf.Module
y sus subclases, como tf.keras.Layer
y tf.keras.Model
.
Observemos un ejemplo en el que se muestra cómo guardar y restaurar un tf.Module
.
Cuando guarda un tf.Module, también se guarda cualquier atributo tf.Variable o método decorado por tf.function y tf.Modules que se hallen a través de recorridos recursivos. (Para más información sobre los recorridos recursivos, consulte el tutorial sobre puntos de verificación). Sin embargo, se pierden cualquiera de las funciones, los datos y los atributos Python. Significa que cuando se guarda una tf.function
, no se guarda ningún código de Python.
Si no se guarda ningún código Python, ¿cómo sabe el SavedModel qué tiene que hacer para restaurar la función?
En resumen, tf.function
funciona rastreando el código Python para generar una función concreta (ConcreteFunction) (un encrustamiento invocable en torno a tf.Graph
). Al guardar la tf.function
, en realidad, se guarda el caché de la tf.function
de las funciones concretas.
Para más información sobre la relación entre tf.function
y las funciones concretas, consulte la guía sobre tf.function.
Carga y uso de un modelo personalizado
Cuando carga un SavedModel en Python, todos los atributos de tf.Variable
, los métodos decorados por tf.function
y los tf.Module
se restauran con la misma estructura de objeto del tf.Module
.
Como no se guarda ningún código Python, si se invoca una tf.function
con una firma de entrada nueva, fallará:
ValueError: Could not find matching function to call for canonicalized inputs ((<tf.Tensor 'args_0:0' shape=(1,) dtype=float32>,), {}). Only existing signatures are [((TensorSpec(shape=(), dtype=tf.float32, name=u'x'),), {})].
Ajuste fino básico
Hay objetos variables disponibles y es posible propagar hacia atrás (backprop) mediante funciones importadas. Esto es suficiente como para aplicar el ajuste fino (es decir, como para retener) un SavedModel en casos simples.
Ajuste fino general
Un SavedModel de Keras aporta más detalles que una __call__
simple para abordar casos más avanzados de ajuste fino. TensorFlow Hub recomienda proporcionar, en caso de ser posible, lo siguiente en los SavedModels compartidos para ajuste fino:
Si el modelo usa la técnica de abandono (dropout) u alguna otra en que el pase hacia adelante difiere entre entrenamiento e inferencia (como la normalización por lotes), el método
__call__
toma un argumento opcional detraining=
valuado por Python, que por defecto esFalse
pero que se puede establecer comoTrue
.Junto al atributo
__call__
, hay atributos.variable
y.trainable_variable
con las correspondientes listas de variables. De.trainable_variables
se omite una variable que originalmente era entrenable, pero que esta prevista para quedar congelada durante el ajuste fino.Para satisfacer los esquemas como Keras que representan regularizadores de peso, como atributos de capas o submodelos; también puede haber un atributo
.regularization_losses
. Este contiene una lista de las funciones de argumento cero cuyos valores fueron previstos para sumarlos a la pérdida total.
Si volvemos al ejemplo original de MobileNet, veremos a algunos en acción:
Especificación de firmas durante la exportación
Las herramientas como TensorFlow Serving y saved_model_cli
pueden interactuar con SavedModels. Para ayudar a esas herramientas a determinar qué funciones concretas usar, se deberán especificar las firmas de servicio (serving). Los tf.keras.Model
especifican automáticamente las firmas de servicio, pero habrá que declarar explícitamente una firma de servicio para los módulos personalizados.
IMPORTANTE: A menos que necesite exportar su modelo a un entorno diferente de TensorFlow 2.x con Python, es probable que no haga falta exportar explícitamente las firmas. Si lo que busca es una forma de forzar una firma de entrada para una función específica, analice el argumento input_signature
para tf.function
.
Por defecto, en un tf.Module
personalizado no se declaran las firmas.
Para declarar una firma de servicio, especifique una función concreta con los kwarg de las signatures
. Cuando especifique una firma sola, la clave de esa firma será ''serving_default'
', que se guarda como la constante de tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY
.
Para exportar múltiples firmas, pase un diccionario de claves de firmas a funciones concretas. Cada clave de firma corresponde a una función concreta.
Por defecto, los nombres del tensor de salida son bastante genéricos, como output_0
. Para controlar los nombres de las salidas, modifique la tf.function
para devolver un diccionario que mapee los nombres de las salidas con las salidas mismas. Los nombres de las entradas derivan de los nombres de los argumentos de las funciones de Python.
División de protoclase
Nota: esta función será parte del lanzamiento de TensorFlow 2.15. En este momento, está disponible en la versión "nocturna", que se puede instalar con pip install tf-nightly
.
Debido a los límites de la implementación del protobuf (búfer de protocolo), los tamaños de las protoclases no deben exceder los 2GB. De lo contrario puede causar los siguientes errores cuando intente guardar modelos muy grandes:
Si desea guardar modelos que excedan el límite de 2GB, deberá guardarlos con una nueva opción de división de protoclase:
Acceda a más información en la guía sobre divisor de protoclase / biblioteca de fusión.
Carga de un SavedModel en C++
La versión C++ del cargador de SavedModel proporciona una API para cargar un SavedModel con una ruta y, a la vez, admite SessionOptions y RunOptions. Hay que especificar las etiquetas asociadas con el grafo que se cargará. A la versión cargada de SavedModel se la conoce como SavedModelBundle y contiene el MetaGraphDef y la sesión dentro de la que se carga.
Detalles de la interfaz de línea de comandos de SavedModel
La interfaz de línea de comandos (CLI) de SavedModel se puede usar para inspeccionar y ejecutar un SavedModel. Por ejemplo, puede usar una interfaz de línea de comandos para inspeccionar las SignatureDef
del modelo. La interfaz de línea de comandos le permitirá confirmar rápidamente el tensor de tipo d de entrada y la coincidencia de la forma del modelo. Además, si desea probar el modelo, puede usar la interfaz de línea de comandos para hacer una prueba de cordura (sanity check) mediante el pase de entradas en varios formatos (por ejemplo, en expresiones Python) y después una extracción de la salida.
Instalación de la interfaz de línea de comandos de SavedModel
En términos generales, TensorFlow se puede instalar de alguna de las siguientes dos maneras:
Mediante la instalación de un TensorFlow binario preconfigurado.
Mediante la creación de TensorFlow a partir de código fuente.
Si instaló TensorFlow con TensorFlow binario preconfigurado, entonces, la interfaz de línea de comandos del SavedModel ya está instalada en su sistema, en bin/saved_model_cli
.
Si creó TensorFlow con código fuente, debe ejecutar el siguiente comando adicional para crear saved_model_cli
:
Descripción general de los comandos
La interfaz de línea de comandos de SavedModel admite los siguientes dos comandos en un SavedModel:
show
, que muestra los cálculos disponibles para SavedModel.run
, que ejecuta un cálculo de un SavedModel.
Comando show
Un SavedModel contiene una o más variantes del modelo (técnicamente, son v1.MetaGraphDef
), identificadas por sus conjuntos de etiquetas. Se preguntará cuál es el tipo de SignatureDef
de cada variante del modelo y cuáles son sus entradas y salidas, para servir al modelo. El comando show
permite examinar el contenido de SavedModel en orden jerárquico. A continuación, la sintaxis:
Por ejemplo, el siguiente comando muestra todos los conjuntos de etiquetas disponibles en el SavedModel:
El siguiente comando muestra todas las claves de SignatureDef
disponibles para un conjunto de etiquetas:
Si hay múltiples etiquetas en el conjunto de etiquetas, deberá especificarlas a todas, cada una por separado con una coma. Por ejemplo:
$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve,gpu
Para mostrar todas las entradas y salidas de TensorInfo para una SignatureDef
específica, pase la clave de SignatureDef
a la opción signature_def
. Esta acción resulta muy útil cuando lo que se desea es conocer el valor de la clave del tensor, el tipo d y la forma de los tensores de entrada para ejecutar más adelante los grafos de cálculo. Por ejemplo:
Para mostrar toda la información disponible en el SavedModel, use la opción --all
. Por ejemplo:
$ saved_model_cli show --dir /tmp/saved_model_dir --all MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs: signature_def['classify_x2_to_y3']: The given SavedModel SignatureDef contains the following input(s): inputs['inputs'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: x2:0 The given SavedModel SignatureDef contains the following output(s): outputs['scores'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: y3:0 Method name is: tensorflow/serving/classify ... signature_def['serving_default']: The given SavedModel SignatureDef contains the following input(s): inputs['x'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: x:0 The given SavedModel SignatureDef contains the following output(s): outputs['y'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: y:0 Method name is: tensorflow/serving/predict
Comando run
Invoque el comando run
para ejecutar el cálculo de un grafo, el paso de entradas y para después, mostrar (y, opcionalmente, guardar) las salidas. A continuación, la sintaxis:
El comando run
ofrece las siguientes tres formas de pasar entradas al modelo:
La opción de
--inputs
le permitirá pasar ndarray de numpy en archivos.La opción
--input_exprs
le permitirá pasar las expresiones de Python.La opción
--input_examples
le permitirá pasartf.train.Example
.
--inputs
Para pasar archivos de datos de entrada, especifique la opción --inputs
, que toma el siguiente formato general:
donde INPUTS (entradas) tiene alguno de los siguientes formatos:
<input_key>=<filename>
<input_key>=<filename>[<variable_name>]
Se pueden pasar múltiples INPUTS. Si lo hace, use un punto y coma para separarlos.
saved_model_cli
usa numpy.load
para cargar el nombre de archivo. El nombre de archivo se puede encontrar en cualquiera de los siguientes formatos:
.npy
.npz
formato pickle
Un archivo .npy
siempre contiene un ndarray (arrglo nd) de numpy. Por lo tanto, cuando se carga un archivo .npy
, el contenido se asignará directamente al tensor de entrada especificado. Si especifica un variable_name con ese archivo .npy
, el variable_name se ignorará y se emitirá una advertencia.
Cuando haga una carga de un archivo .npz
(zip), tendrá la opción de especificar un variable_name (nombre de variable) para identificar la variable dentro del archivo zip para cargar la clave del tensor de entrada. Si no especifica el variable_name, la interfaz de línea de comandos de SavedModel solamente controlará que el zip contenga un solo archivo y lo cargará para la clave del tensor de entrada especificado.
Cuando cargue de un archivo pickle, si no se especifica ningún variable_name
entre los corchetes rectos, lo que esté dentro del archivo pickle pasará a la clave del tensor de entrada especificado. De lo contrario la interfaz de línea de comandos de SavedModel supondrá que se almacena un diccionario en el archivo pickle y que se usará el valor correspondiente al variable_name.
--input_exprs
Para pasar entradas a través de expresiones Python, especifique la opción --input_exprs
. Esto puede resultar útil para cuando no se tienen archivos de datos cerca, pero aún se desea hacer el sanity check del modelo con algunas entradas simples que coincidan con el tipo d y la forma de las SignatureDef
del modelo. Por ejemplo:
Además de expresiones de Python, también podría pasar funciones numpy. Por ejemplo:
(Tenga en cuenta que el módulo numpy
ya está disponible como np
.)
--input_examples
Para pasar tf.train.Example
como entradas, especifique la opción --input_examples
. Para cada clave de entrada, toma una lista de diccionario, donde cada diccionario es una instancia de tf.train.Example
. Las claves de diccionario son las características, y los valores son las listas de valores de cada característica. Por ejemplo:
Guardado de salidas
Por defecto, la interfaz de línea de comandos de SavedModel escribe salidas a stdout. Si un directorio se pasa a la opción --outdir
, las salidas se guardarán como archivos .npy
con los nombres de las claves del tensor de salida del mismo directorio.
Use --overwrite
para sobrescribir los archivos de salida existentes.