En este módulo, aprenderemos cómo crear capas y modelos personalizados en TensorFlow. Esta habilidad es crucial para diseñar arquitecturas de redes neuronales que se ajusten específicamente a tus necesidades y para experimentar con nuevas ideas en el campo del aprendizaje profundo.

Objetivos del Módulo

  • Comprender la necesidad de capas y modelos personalizados.
  • Aprender a crear capas personalizadas utilizando tf.keras.layers.Layer.
  • Aprender a crear modelos personalizados utilizando tf.keras.Model.
  • Implementar ejemplos prácticos de capas y modelos personalizados.
  • Realizar ejercicios prácticos para reforzar los conceptos aprendidos.

  1. Introducción a Capas Personalizadas

¿Por qué Capas Personalizadas?

Las capas personalizadas te permiten:

  • Implementar operaciones específicas que no están disponibles en las capas predefinidas.
  • Experimentar con nuevas arquitecturas de redes neuronales.
  • Optimizar el rendimiento de tu modelo para tareas específicas.

Creación de una Capa Personalizada

Para crear una capa personalizada, hereda de tf.keras.layers.Layer y sobrescribe los métodos __init__, build y call.

import tensorflow as tf

class MiCapaPersonalizada(tf.keras.layers.Layer):
    def __init__(self, unidades=32, **kwargs):
        super(MiCapaPersonalizada, self).__init__(**kwargs)
        self.unidades = unidades

    def build(self, input_shape):
        self.peso = self.add_weight(shape=(input_shape[-1], self.unidades),
                                    initializer='random_normal',
                                    trainable=True)
        self.bias = self.add_weight(shape=(self.unidades,),
                                    initializer='zeros',
                                    trainable=True)

    def call(self, inputs):
        return tf.matmul(inputs, self.peso) + self.bias

Explicación del Código

  • __init__: Inicializa la capa y define los parámetros.
  • build: Crea los pesos de la capa. Este método se llama una vez que se conoce la forma de la entrada.
  • call: Define la lógica de la capa. Este método se llama durante el paso de forward.

  1. Introducción a Modelos Personalizados

¿Por qué Modelos Personalizados?

Los modelos personalizados te permiten:

  • Combinar múltiples capas personalizadas y predefinidas.
  • Implementar arquitecturas complejas que no se pueden construir fácilmente con la API secuencial o funcional de Keras.

Creación de un Modelo Personalizado

Para crear un modelo personalizado, hereda de tf.keras.Model y sobrescribe el método call.

class MiModeloPersonalizado(tf.keras.Model):
    def __init__(self):
        super(MiModeloPersonalizado, self).__init__()
        self.capa1 = tf.keras.layers.Dense(32, activation='relu')
        self.capa2 = MiCapaPersonalizada(10)

    def call(self, inputs):
        x = self.capa1(inputs)
        return self.capa2(x)

Explicación del Código

  • __init__: Inicializa las capas del modelo.
  • call: Define la lógica del modelo, combinando las capas.

  1. Ejemplo Práctico: Clasificación de Dígitos MNIST

Paso 1: Importar Librerías y Cargar Datos

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

# Cargar datos
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
y_train, y_test = to_categorical(y_train), to_categorical(y_test)

Paso 2: Definir Capas y Modelo Personalizado

class MiCapaPersonalizada(tf.keras.layers.Layer):
    def __init__(self, unidades=32, **kwargs):
        super(MiCapaPersonalizada, self).__init__(**kwargs)
        self.unidades = unidades

    def build(self, input_shape):
        self.peso = self.add_weight(shape=(input_shape[-1], self.unidades),
                                    initializer='random_normal',
                                    trainable=True)
        self.bias = self.add_weight(shape=(self.unidades,),
                                    initializer='zeros',
                                    trainable=True)

    def call(self, inputs):
        return tf.matmul(inputs, self.peso) + self.bias

class MiModeloPersonalizado(tf.keras.Model):
    def __init__(self):
        super(MiModeloPersonalizado, self).__init__()
        self.flatten = tf.keras.layers.Flatten()
        self.capa1 = tf.keras.layers.Dense(128, activation='relu')
        self.capa2 = MiCapaPersonalizada(10)

    def call(self, inputs):
        x = self.flatten(inputs)
        x = self.capa1(x)
        return self.capa2(x)

Paso 3: Compilar y Entrenar el Modelo

# Crear una instancia del modelo
modelo = MiModeloPersonalizado()

# Compilar el modelo
modelo.compile(optimizer='adam',
               loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
               metrics=['accuracy'])

# Entrenar el modelo
modelo.fit(x_train, y_train, epochs=5, batch_size=32, validation_split=0.2)

Paso 4: Evaluar el Modelo

# Evaluar el modelo
loss, accuracy = modelo.evaluate(x_test, y_test)
print(f'Pérdida: {loss}, Precisión: {accuracy}')

  1. Ejercicios Prácticos

Ejercicio 1: Crear una Capa Personalizada

Crea una capa personalizada que implemente una operación de normalización batch.

Ejercicio 2: Crear un Modelo Personalizado

Crea un modelo personalizado que utilice la capa de normalización batch que creaste en el ejercicio anterior.

Soluciones

Solución Ejercicio 1

class BatchNormalizationLayer(tf.keras.layers.Layer):
    def __init__(self, **kwargs):
        super(BatchNormalizationLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        self.gamma = self.add_weight(shape=(input_shape[-1],),
                                     initializer='ones',
                                     trainable=True)
        self.beta = self.add_weight(shape=(input_shape[-1],),
                                    initializer='zeros',
                                    trainable=True)

    def call(self, inputs):
        mean, variance = tf.nn.moments(inputs, axes=[0])
        return self.gamma * (inputs - mean) / tf.sqrt(variance + 1e-6) + self.beta

Solución Ejercicio 2

class ModeloConBatchNorm(tf.keras.Model):
    def __init__(self):
        super(ModeloConBatchNorm, self).__init__()
        self.flatten = tf.keras.layers.Flatten()
        self.capa1 = tf.keras.layers.Dense(128, activation='relu')
        self.batch_norm = BatchNormalizationLayer()
        self.capa2 = tf.keras.layers.Dense(10)

    def call(self, inputs):
        x = self.flatten(inputs)
        x = self.capa1(x)
        x = self.batch_norm(x)
        return self.capa2(x)

Conclusión

En este módulo, hemos aprendido a crear capas y modelos personalizados en TensorFlow. Estas habilidades son esenciales para diseñar y experimentar con arquitecturas de redes neuronales avanzadas. Asegúrate de practicar los ejercicios para consolidar tu comprensión y estar preparado para los siguientes módulos.

© Copyright 2024. Todos los derechos reservados