Construir, entrenar y guardar modelos usando Keras y tf.Module

Demasiado Largo; Para Leer

Esta guía te lleva a través de la creación de capas Keras flexibles, la construcción de modelos con tf.keras.Model, y guardarlos con las robustas herramientas de TensorFlow.
featured image - Construir, entrenar y guardar modelos usando Keras y tf.Module
Tensor Flow - [Technical Documentation] HackerNoon profile picture
0-item

Contenido Overview

  • Lámparas de Keras
  • El paso de la construcción
  • Los modelos de Keras
  • Salvar los modelos de Keras
  • Verificación de los modelos de Keras

Tenga en cuenta que hasta este punto, no hay mención de Keras. Puede construir su propia API de alto nivel entf.ModuleY la gente tiene.

En esta sección, examinarás cómo utiliza Kerastf.ModuleUna guía de usuario completa de los modelos de Keras se puede encontrar en elGuía de Keras.

Las capas y modelos de Keras tienen muchas más características adicionales, incluyendo:

  • Pérdidas opcionales
  • Apoyo a la metrología
  • Soporte integrado para un argumento de entrenamiento opcional para diferenciar entre el uso de entrenamiento y de inferencia
  • Guardar y restaurar objetos de Python en lugar de sólo funciones de caja negra
  • los métodos get_config y from_config que le permiten almacenar con precisión las configuraciones para permitir la clonación de modelos en Python

Estas características permiten modelos mucho más complejos a través de la subclasificación, como un modelo GAN personalizado o un modelo Variational AutoEncoder (VAE).Guía completade las capas y los modelos.

Los modelos Keras también vienen con funcionalidad adicional que los hace fáciles de entrenar, evaluar, cargar, guardar e incluso entrenar en múltiples máquinas.

Lámparas de Keras

tf.keras.layers.Layeres la clase base de todas las capas de Keras, y es heredada detf.Module.

Puede convertir un módulo en una capa Keras simplemente intercambiando la capa madre y luego cambiando__call__Doscall:


class MyDense(tf.keras.layers.Layer):
  # Adding **kwargs to support base Keras layer arguments
  def __init__(self, in_features, out_features, **kwargs):
    super().__init__(**kwargs)

    # This will soon move to the build step; see below
    self.w = tf.Variable(
      tf.random.normal([in_features, out_features]), name='w')
    self.b = tf.Variable(tf.zeros([out_features]), name='b')
  def call(self, x):
    y = tf.matmul(x, self.w) + self.b
    return tf.nn.relu(y)

simple_layer = MyDense(name="simple", in_features=3, out_features=3)

Las cucarachas tienen su propia__call__que hace alguna contabilidad descrita en la siguiente sección y luego llamacall()No debe notar ningún cambio en la funcionalidad.


simple_layer([[2.0, 2.0, 2.0]])


<tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[1.1688161, 0.       , 0.       ]], dtype=float32)>

Elbuildpaso

Como se ha señalado, en muchos casos es conveniente esperar a crear variables hasta que esté seguro de la forma de entrada.

Las capas de Keras vienen con un paso de ciclo de vida adicional que le permite más flexibilidad en la forma en que define sus capas.buildFuncionamiento .

buildse llama exactamente una vez, y se llama con la forma de la entrada. Se utiliza generalmente para crear variables (pesos).

Puedes reescribirMyDensela capa superior para ser flexible al tamaño de sus entradas:


class FlexibleDense(tf.keras.layers.Layer):
  # Note the added `**kwargs`, as Keras supports many arguments
  def __init__(self, out_features, **kwargs):
    super().__init__(**kwargs)
    self.out_features = out_features

  def build(self, input_shape):  # Create the state of the layer (weights)
    self.w = tf.Variable(
      tf.random.normal([input_shape[-1], self.out_features]), name='w')
    self.b = tf.Variable(tf.zeros([self.out_features]), name='b')

  def call(self, inputs):  # Defines the computation from inputs to outputs
    return tf.matmul(inputs, self.w) + self.b

# Create the instance of the layer
flexible_dense = FlexibleDense(out_features=3)

En este momento, el modelo no ha sido construido, por lo que no hay variables:


flexible_dense.variables


[]

Llamando la función asigna variables de tamaño apropiado:


# Call it, with predictably random results
print("Model results:", flexible_dense(tf.constant([[2.0, 2.0, 2.0], [3.0, 3.0, 3.0]])))


Model results: tf.Tensor(
[[-2.531786  -5.5550847 -0.4248762]
 [-3.7976792 -8.332626  -0.6373143]], shape=(2, 3), dtype=float32)


flexible_dense.variables


[<tf.Variable 'flexible_dense/w:0' shape=(3, 3) dtype=float32, numpy=
 array([[-0.77719826, -1.9281565 ,  0.82326293],
        [ 0.85628736, -0.31845194,  0.10916236],
        [-1.3449821 , -0.5309338 , -1.1448634 ]], dtype=float32)>,
 <tf.Variable 'flexible_dense/b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]

Desdebuildsólo se llama una vez, las entradas serán rechazadas si la forma de entrada no es compatible con las variables de la capa:


try:
  print("Model results:", flexible_dense(tf.constant([[2.0, 2.0, 2.0, 2.0]])))
except tf.errors.InvalidArgumentError as e:
  print("Failed:", e)


Failed: Exception encountered when calling layer 'flexible_dense' (type FlexibleDense).

{ {function_node __wrapped__MatMul_device_/job:localhost/replica:0/task:0/device:CPU:0} } Matrix size-incompatible: In[0]: [1,4], In[1]: [3,3] [Op:MatMul] name: 

Call arguments received by layer 'flexible_dense' (type FlexibleDense):
  • inputs=tf.Tensor(shape=(1, 4), dtype=float32)

Los modelos de Keras

Puede definir su modelo como capas de Keras niñadas.

Sin embargo, Keras también proporciona una clase de modelos completa llamadatf.keras.ModelSe hereda detf.keras.layers.Layer, por lo que un modelo Keras se puede usar y anidar de la misma manera que las capas Keras. los modelos Keras vienen con funcionalidad adicional que los hace fáciles de entrenar, evaluar, cargar, guardar e incluso entrenar en múltiples máquinas.

Puedes definir elSequentialModulede arriba con el código casi idéntico, de nuevo convertiendo__call__Doscall()Cambiar de padre:


@keras.saving.register_keras_serializable()
class MySequentialModel(tf.keras.Model):
  def __init__(self, name=None, **kwargs):
    super().__init__(**kwargs)

    self.dense_1 = FlexibleDense(out_features=3)
    self.dense_2 = FlexibleDense(out_features=2)
  def call(self, x):
    x = self.dense_1(x)
    return self.dense_2(x)

# You have made a Keras model!
my_sequential_model = MySequentialModel(name="the_model")

# Call it on a tensor, with random results
print("Model results:", my_sequential_model(tf.constant([[2.0, 2.0, 2.0]])))


Model results: tf.Tensor([[ 0.26034355 16.431221  ]], shape=(1, 2), dtype=float32)

Todas las mismas características están disponibles, incluyendo el seguimiento de variables y submodulos.

Nota: Un tf.Module crudo niñado dentro de una capa o modelo Keras no obtendrá sus variables recogidas para entrenamiento o ahorro.

Nota: Un tf.Module crudo niñado dentro de una capa o modelo Keras no obtendrá sus variables recogidas para entrenamiento o ahorro.


my_sequential_model.variables


[<tf.Variable 'my_sequential_model/flexible_dense_1/w:0' shape=(3, 3) dtype=float32, numpy=
 array([[ 1.4749854 ,  0.16090827,  2.2669017 ],
        [ 1.6850946 ,  1.1545411 ,  0.1707306 ],
        [ 0.8753734 , -0.13549292,  0.08751986]], dtype=float32)>,
 <tf.Variable 'my_sequential_model/flexible_dense_1/b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>,
 <tf.Variable 'my_sequential_model/flexible_dense_2/w:0' shape=(3, 2) dtype=float32, numpy=
 array([[-0.8022977 ,  1.9773549 ],
        [-0.76657015, -0.8485579 ],
        [ 1.6919082 ,  0.49000967]], dtype=float32)>,
 <tf.Variable 'my_sequential_model/flexible_dense_2/b:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>]


my_sequential_model.submodules


(<__main__.FlexibleDense at 0x7f790c7e0e80>,
 <__main__.FlexibleDense at 0x7f790c7e6940>)

Supervivenciatf.keras.Modeles un enfoque muy Pythonic para construir modelos de TensorFlow. Si está migrando modelos de otros marcos, esto puede ser muy sencillo.

Si está construyendo modelos que son ensamblajes simples de capas y entradas existentes, puede ahorrar tiempo y espacio utilizando elFuncionamiento del fuego, que viene con características adicionales en torno a la reconstrucción del modelo y la arquitectura.

Aquí está el mismo modelo con la API funcional:


inputs = tf.keras.Input(shape=[3,])

x = FlexibleDense(3)(inputs)
x = FlexibleDense(2)(x)

my_functional_model = tf.keras.Model(inputs=inputs, outputs=x)

my_functional_model.summary()


Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 3)]               0         
                                                                 
 flexible_dense_3 (Flexible  (None, 3)                 12        
 Dense)                                                          
                                                                 
 flexible_dense_4 (Flexible  (None, 2)                 8         
 Dense)                                                          
                                                                 
=================================================================
Total params: 20 (80.00 Byte)
Trainable params: 20 (80.00 Byte)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________


my_functional_model(tf.constant([[2.0, 2.0, 2.0]]))


<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[3.4276495, 2.937252 ]], dtype=float32)>

La principal diferencia aquí es que la forma de entrada se especifica por delante como parte del proceso de construcción funcional.input_shapeargumento en este caso no tiene que ser completamente especificado; puede dejar algunas dimensiones comoNone.

Nota: No es necesario especificar input_shape o un InputLayer en un modelo subclasificado; estos argumentos y capas se ignorarán.

Nota: No es necesario especificar input_shape o un InputLayer en un modelo subclasificado; estos argumentos y capas se ignorarán.

Salvar los modelos de Keras

Los modelos Keras tienen su propio formato especializado de almacenamiento de archivos zip, marcado por la.kerasExtensión: Cuando se llamatf.keras.Model.saveAñade a.kerasExtensión del archivo, por ejemplo:


my_sequential_model.save("exname_of_file.keras")

Igualmente fácilmente, se pueden cargar de nuevo en:


reconstructed_model = tf.keras.models.load_model("exname_of_file.keras")

Archivo Zip -.kerasarchivos - también guarda los estados de métrica, pérdida y optimizador.

Este modelo reconstruido se puede utilizar y producirá el mismo resultado cuando se llama a los mismos datos:


reconstructed_model(tf.constant([[2.0, 2.0, 2.0]]))


<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[ 0.26034355, 16.431221  ]], dtype=float32)>

Verificación de los modelos de Keras

Los modelos de Keras también se pueden comprobar, y que se verá lo mismo quetf.Module.

Hay más que saber sobre el almacenamiento y la serialización de los modelos Keras, incluyendo el suministro de métodos de configuración para capas personalizadas para el soporte de características.Guía para ahorrar y serializar.

¿Qué es lo siguiente

Si desea saber más detalles sobre Keras, puede seguir las guías Keras existentesAquí.

Otro ejemplo de una API de alto nivel construida entf.modulees Sonnet de DeepMind, que está cubierto ensu sitio.


Originalmente publicado en el sitio web de TensorFlow, este artículo aparece aquí bajo un nuevo título y está licenciado bajo CC BY 4.0.

Originalmente publicado en laTensorFlowEste artículo aparece aquí bajo un nuevo título y está licenciado bajo CC BY 4.0.

TensorFlow


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks