¡Reserva! Google I / O regresa del 18 al 20 de mayo Regístrese ahora
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Modelos guardados reutilizables

Introducción

TensorFlow Hub aloja SavedModels para TensorFlow 2, entre otros activos. Se pueden volver a cargar en un programa de Python con obj = hub.load(url) [ más información ]. El obj devuelto es el resultado de tf.saved_model.load() (consulta la guía de modelo guardado de TensorFlow). Este objeto puede tener atributos arbitrarios que son tf.functions, tf.Variables (inicializados a partir de sus valores entrenados previamente), otros recursos y, de forma recursiva, más objetos de este tipo.

En esta página, se describe una interfaz que debe implementar el obj cargado para reutilizarla en un programa TensorFlow Python. Los modelos guardados que se ajustan a esta interfaz se denominan modelos guardados reutilizables .

Reutilizar significa construir un modelo más grande alrededor de obj , incluida la capacidad de ajustarlo. Medios de ajuste adicional de formación de los pesos de la carga obj como parte del modelo circundante. La función de pérdida y el optimizador están determinados por el modelo circundante; obj solo define el mapeo de las activaciones de entrada a salida (el "paso hacia adelante"), posiblemente incluyendo técnicas como el abandono o la normalización por lotes.

El equipo de TensorFlow Hub recomienda implementar la interfaz de modelo guardado reutilizable en todos los modelos guardados que están destinados a ser reutilizados en el sentido anterior. Muchas utilidades de la biblioteca tensorflow_hub , en particular hub.KerasLayer , requieren SavedModels para implementarlo.

Relación con SignatureDefs

Esta interfaz en términos de tf.functions y otras características de TF2 es independiente de las firmas de SavedModel, que han estado disponibles desde TF1 y continúan usándose en TF2 para inferencia (como implementar SavedModels en TF Serving o TF Lite). Las firmas para inferencia no son lo suficientemente expresivas para admitir el ajuste fino, y tf.function proporciona una API de Python más natural y expresiva para el modelo reutilizado.

Relación con las bibliotecas de construcción de modelos

Un modelo guardado reutilizable usa solo primitivas de TensorFlow 2, independientemente de cualquier biblioteca de creación de modelos en particular, como Keras o Sonnet. Esto facilita la reutilización en las bibliotecas de creación de modelos, sin depender del código de creación de modelos original.

Se necesitará cierta cantidad de adaptación para cargar modelos guardados reutilizables o guardarlos desde cualquier biblioteca de creación de modelos. Para Keras, hub.KerasLayer proporciona la carga, y el guardado integrado de Keras en el formato SavedModel se ha rediseñado para TF2 con el objetivo de proporcionar un superconjunto de esta interfaz (consulte el RFC de mayo de 2019).

Relación con las "API de modelo guardado común" específicas de la tarea

La definición de interfaz en esta página permite cualquier número y tipo de entradas y salidas. Las API Common SavedModel para TF Hub refinan esta interfaz general con convenciones de uso para tareas específicas para que los modelos sean fácilmente intercambiables.

Definición de interfaz

Atributos

Un modelo guardado reutilizable es un modelo guardado de TensorFlow 2 tal que obj = tf.saved_model.load(...) devuelve un objeto que tiene los siguientes atributos

  • __call__ . Requerido. Una función que implementa el cálculo del modelo (el "pase hacia adelante") sujeto a la especificación a continuación.

  • variables : una lista de objetos tf.Variable, que enumera todas las variables utilizadas por cualquier posible invocación de __call__ , incluidas las entrenables y no entrenables.

    Esta lista se puede omitir si está vacía.

  • trainable_variables : una lista de objetos tf.Variable tal que v.trainable es verdadero para todos los elementos. Estas variables deben ser un subconjunto de variables . Estas son las variables que se deben entrenar al ajustar el objeto. El creador del modelo guardado puede optar por omitir aquí algunas variables que originalmente se podían entrenar para indicar que no deben modificarse durante el ajuste fino.

    Esta lista se puede omitir si está vacía, en particular, si el modelo guardado no admite el ajuste fino.

  • regularization_losses : Una lista de tf.functions, cada una de las cuales toma cero entradas y devuelve un solo tensor de flotación escalar. Para un ajuste fino, se recomienda al usuario de SavedModel que los incluya como términos de regularización adicionales en la pérdida (en el caso más simple sin más escalado). Normalmente, se utilizan para representar regularizadores de peso. (Por falta de entradas, estas funciones de tf. No pueden expresar regularizadores de actividad).

    Esta lista se puede omitir si está vacía, en particular, si el modelo guardado no admite el ajuste fino o no desea prescribir la regularización de peso.

La función __call__

Un obj modelo guardado restaurado tiene un atributo obj.__call__ que es una función tf.función restaurada y permite llamar a obj de la siguiente manera.

Sinopsis (pseudocódigo):

outputs = obj(inputs, trainable=..., **kwargs)

Argumentos

Los argumentos son los siguientes.

  • Hay un argumento posicional requerido con un lote de activaciones de entrada del modelo guardado. Su tipo es uno de

    • un solo tensor para una sola entrada,
    • una lista de tensores para una secuencia ordenada de entradas sin nombre,
    • un dictado de tensores codificados por un conjunto particular de nombres de entrada.

    (Las revisiones futuras de esta interfaz pueden permitir nidos más generales). El creador del modelo guardado elige uno de esos y las formas y tipos de tensor. Cuando sea útil, algunas dimensiones de la forma deben estar indefinidas (en particular, el tamaño del lote).

  • Puede haber un training argumento de palabra clave opcional que acepte un booleano de Python, True o False . El valor predeterminado es False . Si el modelo admite el ajuste fino, y si su cálculo difiere entre los dos (por ejemplo, como en el abandono y la normalización por lotes), esa distinción se implementa con este argumento. De lo contrario, este argumento puede estar ausente.

    No es necesario que __call__ acepte un argumento de training valores de tensor. tf.cond() la persona que llama usar tf.cond() si es necesario para enviar entre ellos.

  • El creador del modelo guardado puede optar por aceptar más kwargs opcionales de nombres particulares.

    • Para los argumentos con valores de tensor, el creador del modelo guardado define sus dtypes y formas permitidos. tf.function acepta un valor predeterminado de Python en un argumento que se rastrea con una entrada tf.TensorSpec. Dichos argumentos se pueden usar para permitir la personalización de hiperparámetros numéricos involucrados en __call__ (por ejemplo, tasa de abandono).

    • Para los argumentos con valores de Python, el creador del modelo guardado define sus valores permitidos. Tales argumentos se pueden usar como indicadores para hacer elecciones discretas en la función rastreada (pero tenga en cuenta la explosión combinatoria de los rastros).

La función __call__ restaurada debe proporcionar seguimientos para todas las combinaciones permitidas de argumentos. Cambiar el training entre True y False no debe cambiar la permisibilidad de los argumentos.

Resultado

Las outputs de llamar a obj pueden ser

  • un solo tensor para una sola salida,
  • una lista de tensores para una secuencia ordenada de salidas sin nombre,
  • un dictado de tensores codificado por un conjunto particular de nombres de salida.

(Las revisiones futuras de esta interfaz pueden permitir nidos más generales). El tipo de retorno puede variar según los kwargs valorados en Python. Esto permite que las banderas produzcan salidas adicionales. El creador de SavedModel define los tipos y formas de salida y su dependencia de las entradas.

Llamables nombrados

Un modelo guardado reutilizable puede proporcionar varias piezas de modelo de la forma descrita anteriormente colocándolas en subobjetos con nombre, por ejemplo, obj.foo , obj.bar , etc. Cada subobjeto proporciona un método __call__ y atributos de apoyo sobre las variables, etc. específicas de esa pieza del modelo. Para el ejemplo anterior, habría obj.foo.__call__ , obj.foo.variables y así sucesivamente.

Tenga en cuenta que esta interfaz no cubre el enfoque de agregar una función tf.function directamente como tf.foo .

Se espera que los usuarios de modelos guardados reutilizables solo manejen un nivel de anidamiento ( obj.bar pero no obj.bar.baz ). (Las revisiones futuras de esta interfaz pueden permitir un anidamiento más profundo y pueden renunciar al requisito de que el objeto de nivel superior sea invocable por sí mismo).

Palabras de clausura

Relación con las API en proceso

Este documento describe una interfaz de una clase Python que consta de primitivas como tf.function y tf.Variable que sobreviven a un viaje de ida y vuelta a través de la serialización a través de tf.saved_model.save() y tf.saved_model.load() . Sin embargo, la interfaz ya estaba presente en el objeto original que se pasó a tf.saved_model.save() . La adaptación a esa interfaz permite el intercambio de piezas de modelo entre las API de creación de modelos dentro de un solo programa de TensorFlow.