python - after - TensorFlow: cómo y por qué utilizar SavedModel
tensorflow save model after training (1)
Tengo algunas preguntas con respecto a la API SavedModel
, cuya documentation que encuentro deja muchos detalles sin explicar.
Las primeras tres preguntas son sobre qué pasar a los argumentos del método add_meta_graph_and_variables()
método tf.saved_model.builder.SavedModelBuilder
, mientras que la cuarta pregunta es sobre por qué usar la API tf.train.Saver
sobre tf.train.Saver
.
¿Cuál es el formato del argumento
signature_def_map
? ¿Normalmente necesito establecer este argumento al guardar un modelo?Del mismo modo, ¿cuál es el formato del argumento
assets_collection
?¿Por qué guarda una lista de etiquetas con un metágrafo en lugar de simplemente darle un nombre (es decir, adjuntarle solo una etiqueta única)? ¿Por qué agregaría varias etiquetas a un metágrafo dado? ¿Qué pasa si trato de cargar una metagrpah desde un
pb
por una etiqueta determinada, pero varios metagraphs en esepb
coinciden con esa etiqueta?La documentación sostiene que se recomienda utilizar
SavedModel
para guardar modelos completos (en lugar de variables únicamente) en archivos independientes. Perotf.train.Saver
también guarda el gráfico además de las variables en un archivo.meta
. ¿Cuáles son las ventajas de usarSavedModel
? La documentación dice
Cuando desee guardar y cargar variables, el gráfico y los metadatos del gráfico, básicamente, cuando desee guardar o restaurar su modelo, le recomendamos que utilice SavedModel. SavedModel es un formato de serialización hermética, recuperable y neutral en cuanto a idioma. SavedModel permite a los sistemas y herramientas de nivel superior producir, consumir y transformar los modelos TensorFlow.
pero esta explicación es bastante abstracta y realmente no me ayuda a entender cuáles son las ventajas de SavedModel
. ¿Cuáles serían ejemplos concretos en los que SavedModel
(en lugar de tf.train.Saver
) sería mejor usar?
Tenga en cuenta que mi pregunta no es un duplicado de esta pregunta . No estoy preguntando cómo guardar un modelo, estoy haciendo preguntas muy específicas sobre las propiedades de SavedModel
, que es solo uno de los múltiples mecanismos que TensorFlow proporciona para guardar y cargar modelos. Ninguna de las respuestas en la pregunta vinculada toca en la API SavedModel
(que, una vez más, no es lo mismo que tf.train.Saver
).
EDIT : escribí esto de nuevo en TensorFlow 1.4. A partir de hoy (TensorFlow 1.12 es estable, hay un 1.13rc y 2.0 está a la vuelta de la esquina) los documentos vinculados en la pregunta han mejorado mucho.
Estoy tratando de usar tf.saved_model
y también encontré los Docs bastante (demasiado) abstractos. Aquí está mi puñalada en una respuesta completa a sus preguntas:
1. signature_def_map
:
a. Formato Consulte la respuesta de Tom a Tensorflow: cómo guardar / restaurar un modelo . ( Ctrl-F
para "tf.saved_model" - actualmente, los únicos usos de la frase en esa pregunta están en su respuesta).
segundo. necesito Es mi entendimiento de que normalmente lo necesitas. Si pretende usar el modelo, necesita conocer las entradas y salidas del gráfico. Creo que es similar a una firma de función de C ++: si pretende definir una función después de que se la llame o en otro archivo de C ++, necesita la firma en su archivo principal (es decir, en un prototipo o en un archivo de encabezado).
2. assets_collection
:
Formato: no se pudo encontrar documentación clara, por lo que fui al código fuente del generador. Parece que el argumento es un iterable de Tensores de dtype=tf.string
, donde cada Tensor es una ruta para el directorio de activos. Por lo tanto, una colección de TensorFlow Graph debería funcionar. Supongo que ese es el nombre del parámetro, pero del código fuente esperaría que una list
Python también funcionara.
(No preguntó si necesita configurarlo, pero a juzgar por la respuesta de Zoe a ¿Qué son los activos en tensorflow? Y la respuesta de iga al servicio de Tensorflow relacionado tangencialmente : “No hay activos para guardar / escribir” al exportar modelos , no lo hace ” Por lo general, se necesita configurar.
3. Etiquetas:
a. Por qué lista no sé por qué debe pasar una lista, pero puede pasar una lista con un elemento. Por ejemplo, en mi proyecto actual solo uso la etiqueta [tf...tag_constants.SERVING]
.
segundo. Cuándo usar múltiples Diga que está utilizando la ubicación explícita de dispositivos para las operaciones. Tal vez quiera guardar una versión de CPU y una versión de GPU de su gráfico. Obviamente, desea guardar una versión de servicio de cada uno y dice que desea guardar los puntos de control de entrenamiento. Podría usar una etiqueta de CPU / GPU y una etiqueta de capacitación / servicio para gestionar todos los casos. Los docs insinúan:
Cada MetaGraphDef agregado a SavedModel debe anotarse con etiquetas especificadas por el usuario. Las etiquetas proporcionan un medio para identificar el MetaGraphDef específico para cargar y restaurar, junto con el conjunto compartido de variables y activos. Estas etiquetas suelen anotar un MetaGraphDef con su funcionalidad (por ejemplo, servicio o entrenamiento), y opcionalmente con aspectos específicos del hardware (por ejemplo, GPU).
do. Colisión Demasiado perezoso para forzar una colisión yo mismo. Veo dos casos que deberían tratarse, fui al código fuente del cargador. Dentro de la def load
, verás:
saved_model = _parse_saved_model(export_dir)
found_match = False
for meta_graph_def in saved_model.meta_graphs:
if set(meta_graph_def.meta_info_def.tags) == set(tags):
meta_graph_def_to_load = meta_graph_def
found_match = True
break
if not found_match:
raise RuntimeError(
"MetaGraphDef associated with tags " + str(tags).strip("[]") +
" could not be found in SavedModel. To inspect available tag-sets in"
" the SavedModel, please use the SavedModel CLI: `saved_model_cli`"
)
Me parece que está buscando una coincidencia exacta. Por ejemplo, digamos que tiene un metágrafo con las etiquetas "GPU" y "Serving" y un metágrafo con la etiqueta "Serving". Si carga "Serving", obtendrá el último párrafo. Por otro lado, digamos que tiene un metagraph "GPU" y "Serving" y un metagraph "CPU" y "Serving". Si intentas cargar "Serving", obtendrás el error. Si intenta guardar dos metagraphs con las mismas etiquetas en la misma carpeta, espero que sobrescriba la primera. No parece que el código de construcción maneje tal colisión de ninguna manera especial.
4. SavedModel
o tf.train.Saver
:
Esto me confundió también. la respuesta de wicke a ¿Deberían los usuarios de TensorFlow preferir SavedModel sobre Checkpoint o GraphDef? Lo aclaré por mí. Voy a tirar mis dos centavos:
En el ámbito de Python + TensorFlow local, puedes hacer que tf.train.Saver
haga todo. Pero, te costará. Permítanme resumir el caso de uso de guardar y entrenar, modelar e implementar. Necesitarás tu objeto protector. Es más fácil configurarlo para guardar el gráfico completo (cada variable). Probablemente no quiera guardar el .meta
todo el tiempo, ya que está trabajando con un gráfico estático. Tendrá que especificar eso en su gancho de entrenamiento. Puedes leer sobre eso en cv-tricks . Cuando termine su entrenamiento, necesitará convertir su archivo de punto de control en un archivo pb
. Por lo general, esto significa borrar el gráfico actual, restaurar el punto de control, congelar las variables a constantes con tf.python.framework.graph_util
y escribirlo con tf.gfile.GFile
. Puedes leer sobre eso en un medio . Después de eso, quieres implementarlo en Python. Necesitará los nombres de Tensor de entrada y salida: los nombres de cadena en la definición del gráfico. Puedes leer sobre eso en metaflow (en realidad es una muy buena publicación de blog para el método tf.train.Saver
) . Algunos nodos operativos te permitirán ingresar datos en ellos fácilmente. Algunos no tanto. Por lo general, me di por vencido en la búsqueda de un nodo apropiado y agregué una tf.reshape
que en realidad no tf.reshape
la forma del gráfico def. Ese fue mi nodo de entrada ad-hoc. Lo mismo para la salida. Y finalmente, puede implementar su modelo, al menos localmente en Python.
O, podría usar la respuesta que SavedModel
en el punto 1 para lograr todo esto con la API SavedModel
. Menos dolores de cabeza gracias a la respuesta de Tom . Obtendrá más soporte y funciones en el futuro si alguna vez se documenta adecuadamente . Parece que es más fácil usar la línea de comandos (el enlace del medio cubre eso con Saver
- parece difícil, ¡buena suerte!). Está prácticamente cocido a los nuevos estimadores. Y según los documentos,
SavedModel es un formato de serialización hermética, recuperable y neutral en cuanto a idioma .
Énfasis mío: Parece que puede hacer que sus modelos entrenados entren en la creciente API de C ++ mucho más fácil.
A mi modo de ver, es como la API de conjuntos de datos. ¡Es más fácil que la forma antigua!
En cuanto a los ejemplos concretos de SavedModel
of tf.train.Saver
: Si "básicamente, cuando quiere guardar o restaurar su modelo" no es lo suficientemente claro para usted: el momento adecuado para usarlo es en cualquier momento que le haga la vida más fácil . Para mí, eso se parece siempre. Especialmente si está utilizando estimadores, implementando en C ++ o utilizando la línea de comandos.
Así que esa es mi investigación sobre tu pregunta. O cuatro preguntas enumeradas. Err, ocho signos de interrogación. Espero que esto ayude.