TensorFlow

TensorFlow

Tutorial TensorFlow: Capas en Keras

Aprende cómo utilizar capas densas, convolucionales y recurrentes en Keras, además de crear capas personalizadas para modelos avanzados de aprendizaje profundo.

Aprende TensorFlow GRATIS y certifícate

Definición de capa de neuronas en Keras

En Keras, una capa de neuronas es el componente elemental que conforma los modelos de aprendizaje profundo. Cada capa aplica una transformación sobre los datos de entrada mediante operaciones matemáticas parametrizadas, lo que permite a la red neuronal aprender representaciones complejas de los datos.

Las capas en Keras son módulos que procesan tensores y producen otros tensores como salida. Por ejemplo, una capa densa (Dense) es una capa completamente conectada donde cada neurona está conectada a todas las neuronas de la capa anterior:

from tensorflow.keras.layers import Dense

# Crear una capa densa con 64 unidades y función de activación ReLU
capa_densa = Dense(64, activation='relu')

Cada capa puede tener parámetros ajustables, como el número de unidades (neuronas), la función de activación, inicializadores de pesos y regularizadores. Estos parámetros permiten personalizar el comportamiento de la capa para adaptarse a diferentes tipos de datos y problemas.

Las capas son los bloques constructivos de los modelos en Keras y se pueden conectar de manera secuencial o mediante grafos complejos utilizando la API funcional. Al combinar múltiples capas, es posible crear modelos profundos que capturan patrones y relaciones en los datos.

Por ejemplo, al construir un modelo secuencial, se integran capas de forma lineal:

from tensorflow.keras.models import Sequential

modelo = Sequential([
    Dense(128, activation='relu', input_shape=(100,)),
    Dense(10, activation='softmax')
])

En este modelo, la primera capa recibe entradas de dimensión 100 y produce una salida de 128 neuronas, mientras que la segunda capa genera una salida de 10 neuronas con activación softmax, adecuada para clasificación multiclase.

Además de las capas predefinidas, Keras permite crear capas personalizadas heredando de la clase base Layer. Esto es útil cuando se necesitan operaciones específicas no cubiertas por las capas existentes. Al definir una capa personalizada, se implementa el método call() donde se especifica el comportamiento de la capa.

La flexibilidad de las capas en Keras facilita la experimentación y el prototipado rápido de modelos de aprendizaje profundo, permitiendo ajustar y extender las arquitecturas de acuerdo con las necesidades del proyecto.

Capas densas

Las capas densas, también conocidas como capas completamente conectadas, son fundamentales en la construcción de modelos de redes neuronales con Keras. En una capa densa, cada neurona está conectada a todas las neuronas de la capa anterior, lo que permite una transformación lineal completa de las entradas seguida de una función de activación no lineal.

La clase Dense de Keras se utiliza para implementar capas densas. Se define especificando el número de unidades (neuronas) y la función de activación que se aplicará a la salida de cada neurona. Por ejemplo:

from tensorflow.keras.layers import Dense

# Crear una capa densa con 64 unidades y activación ReLU
capa_densa = Dense(units=64, activation='relu')

En este ejemplo, la capa tiene 64 neuronas y utiliza la función de activación ReLU (Rectified Linear Unit), que introduce no linealidad al modelo y ayuda a aprender relaciones más complejas.

Matemáticamente, una capa densa realiza la siguiente operación:

$$
\text{salida} = \text{activación}(\mathbf{W} \cdot \text{entrada} + \mathbf{b})
$$

Donde:

  • $\mathbf{W}$ es la matriz de pesos que conecta las entradas con las salidas.
  • $\mathbf{b}$ es el vector de sesgos.
  • $\text{activación}$ es la función de activación aplicada elemento a elemento.

Al diseñar un modelo secuencial en Keras, las capas densas se añaden de forma secuencial:

from tensorflow.keras.models import Sequential

modelo = Sequential()
modelo.add(Dense(128, activation='relu', input_shape=(100,)))
modelo.add(Dense(64, activation='relu'))
modelo.add(Dense(10, activation='softmax'))

En este modelo:

  • La primera capa densa tiene 128 unidades y especifica input_shape=(100,), indicando que las entradas son vectores de dimensión 100.
  • La segunda capa densa reduce la dimensionalidad a 64 unidades.
  • La última capa densa tiene 10 unidades con activación softmax, apropiada para problemas de clasificación multiclase.

Los parámetros clave de una capa densa incluyen:

  • units: número de neuronas en la capa.
  • activation: función de activación aplicada a la salida.
  • kernel_initializer: inicializador de los pesos.
  • bias_initializer: inicializador de los sesgos.
  • kernel_regularizer: regularización aplicada a los pesos.
  • bias_regularizer: regularización aplicada a los sesgos.

Por ejemplo, para implementar una capa densa con inicialización He normal y regularización L2:

from tensorflow.keras.layers import Dense
from tensorflow.keras.initializers import HeNormal
from tensorflow.keras.regularizers import l2

capa_personalizada = Dense(
    units=64,
    activation='relu',
    kernel_initializer=HeNormal(),
    kernel_regularizer=l2(0.001)
)

La inicialización adecuada de los pesos y la aplicación de regularización pueden mejorar significativamente el rendimiento del modelo y prevenir el sobreajuste.

Las capas densas son especialmente útiles en las últimas etapas de modelos que involucran otras capas, como las capas convolucionales o las capas recurrentes. Después de extraer características con estas capas, las capas densas pueden combinar y clasificar dichas características:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Flatten, Dense, Input

modelo_cnn = Sequential([
    Input(shape=(64, 64, 3)),  # Define la entrada explícitamente
    Conv2D(32, (3, 3), activation='relu'),
    Flatten(),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

En este ejemplo:

  • Se utiliza una capa Conv2D para procesar imágenes.
  • La capa Flatten convierte el tensor de salida de la capa convolucional en un vector.
  • Las capas densas finales realizan la clasificación basándose en las características extraídas.

Es crucial seleccionar la función de activación adecuada en las capas densas:

  • relu: común en capas ocultas por su eficiencia computacional y capacidad para mitigar el problema del gradiente desaparecido.
  • sigmoid: usada en la capa de salida para clasificación binaria, produce una probabilidad entre 0 y 1.
  • softmax: utilizada en problemas de clasificación multiclase, proporciona una distribución de probabilidad sobre las clases.

Un modelo para un problema de regresión podría configurarse sin función de activación en la capa de salida o utilizando activaciones lineales:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

modelo = Sequential()
modelo.add(Dense(64, activation='relu', input_shape=(10,)))
modelo.add(Dense(32, activation='relu'))
modelo.add(Dense(1))  # Sin activación en la capa de salida

Las capas densas también admiten máscaras y pueden manejar valores faltantes si se configuran correctamente. Además, es posible utilizar capas densas con entradas y salidas multidimensionales, lo que permite diseñar arquitecturas complejas para tareas avanzadas.

Las mejores prácticas al trabajar con capas densas incluyen:

  • Normalizar o escalar las entradas para mejorar la convergencia.
  • Ajustar el número de unidades y capas para equilibrar el sesgo y la varianza.
  • Utilizar técnicas de regularización como Dropout o regularización L1/L2.
  • Realizar búsqueda de hiperparámetros para encontrar la configuración óptima.

En resumen, las capas densas son un componente esencial en el desarrollo de modelos con Keras, ofreciendo flexibilidad y potencia para una amplia gama de aplicaciones en aprendizaje automático.

Capas convolucionales

Las capas convolucionales son un componente fundamental en la construcción de modelos para el procesamiento de datos con estructuras espaciales, como imágenes y señales de audio. En Keras, estas capas permiten extraer características locales mediante la aplicación de filtros que recorren la entrada, capturando patrones de bajo nivel que pueden combinarse en estructuras más complejas.

La clase principal para implementar capas convolucionales bidimensionales es Conv2D. Esta se utiliza comúnmente en el procesamiento de imágenes:

from tensorflow.keras.layers import Conv2D

# Crear una capa convolucional con 32 filtros, tamaño de kernel 3x3 y activación ReLU
capa_convolucional = Conv2D(filters=32, kernel_size=(3, 3), activation='relu')

En esta capa:

  • filters: número de filtros o mapas de características que la capa aprenderá.
  • kernel_size: tamaño del kernel o ventana que se desplaza sobre la entrada.
  • activation: función de activación aplicada a la salida de la convolución.

Matemáticamente, la operación de una capa convolucional se define como:

$$
\text{Salida}(i, j, k) = \sigma \left( \sum_{m=0}^{F-1} \sum_{n=0}^{F-1} \sum_{l=0}^{C_{\text{in}}-1} \mathbf{X}(i+m, j+n, l) \cdot \mathbf{K}(m, n, l, k) + b_k \right) $$

Donde:

  • $\mathbf{X}$ es el tensor de entrada.
  • $\mathbf{K}$ es el conjunto de filtros aprendibles.
  • $b_k$ es el sesgo asociado al filtro $k$.
  • La suma se realiza sobre las dimensiones del kernel y los canales de entrada.

Esta operación aplica un filtro (o kernel) de tamaño definido sobre regiones locales de la entrada para extraer características relevantes. Posteriormente, estas características pueden combinarse en capas adicionales para capturar patrones más complejos. El resultado final depende de la combinación de estos filtros y de la arquitectura del modelo.

Al diseñar un modelo CNN (Convolutional Neural Network) en Keras, es común combinar capas convolucionales con capas de pooling y densas:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

modelo = Sequential()
modelo.add(Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))
modelo.add(MaxPooling2D(pool_size=(2, 2)))
modelo.add(Conv2D(64, (3, 3), activation='relu'))
modelo.add(MaxPooling2D(pool_size=(2, 2)))
modelo.add(Flatten())
modelo.add(Dense(128, activation='relu'))
modelo.add(Dense(10, activation='softmax'))

En este modelo:

  • La primera capa Conv2D procesa imágenes de tamaño 64x64 con 3 canales (RGB).
  • MaxPooling2D reduce la dimensionalidad espacial, enfocándose en las características más relevantes.
  • Las capas convolucionales adicionales profundizan el aprendizaje de patrones más complejos.
  • Flatten transforma el tensor en un vector para las capas densas.
  • Las capas densas finales realizan la clasificación basándose en las características extraídas.

Los parámetros clave de una capa convolucional incluyen:

  • filters: determina la profundidad de la salida y el número de características aprendidas.
  • kernel_size: tamaño del filtro; puede ser un entero o una tupla.
  • strides: controla el paso con el que el kernel se mueve sobre la entrada; por defecto es (1, 1).
  • padding: decide cómo manejar los bordes de la entrada; puede ser 'valid' (sin padding) o 'same' (con padding para mantener el tamaño).
  • activation: función de activación como 'relu', 'tanh', etc.

Por ejemplo, una capa convolucional con padding 'same' y strides (2, 2):

capa_convolucional = Conv2D(
    filters=64,
    kernel_size=(3, 3),
    strides=(2, 2),
    padding='same',
    activation='relu'
)

El uso de padding 'same' asegura que las dimensiones espaciales de la salida se ajusten adecuadamente, mientras que los strides controlan la resolución de la salida.

Además de Conv2D, Keras ofrece capas convolucionales para diferentes dimensiones:

  • Conv1D: para datos unidimensionales como series temporales o texto.
  • Conv3D: para datos tridimensionales como secuencias de vídeo o volúmenes médicos.

Un ejemplo de capa Conv1D:

from tensorflow.keras.layers import Conv1D

# Capa convolucional unidimensional
capa_convolucional_1d = Conv1D(filters=128, kernel_size=5, activation='relu')

Al trabajar con capas convolucionales, es común utilizar capas de normalización y regularización para mejorar el rendimiento:

  • BatchNormalization: normaliza las activaciones de la capa anterior, acelerando el entrenamiento y mejorando la estabilidad.
  • Dropout: apaga aleatoriamente un porcentaje de neuronas durante el entrenamiento para prevenir el sobreajuste.

Ejemplo de uso combinado:

from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, Reshape

# Crear el modelo
modelo = Sequential()

# Define la entrada inicial
modelo.add(Input(shape=(10,)))
modelo.add(Reshape((1, 10, 1)))

modelo.add(Conv2D(64, (3, 3), padding='same'))
modelo.add(BatchNormalization())
modelo.add(Activation('relu'))

Las capas convolucionales también admiten la especificación de inicializadores y regularizadores:

  • kernel_initializer: define cómo se inicializan los pesos del kernel; por ejemplo, HeNormal() es adecuado para activaciones ReLU.
  • kernel_regularizer: aplica penalizaciones sobre los pesos para evitar que crezcan excesivamente; por ejemplo, l2(0.001).

Implementación con inicializador y regularizador:

from tensorflow.keras.regularizers import l2
from tensorflow.keras.initializers import HeNormal

capa_convolucional = Conv2D(
    filters=32,
    kernel_size=(3, 3),
    activation='relu',
    kernel_initializer=HeNormal(),
    kernel_regularizer=l2(0.001)
)

Al diseñar redes convolucionales, es esencial considerar aspectos como:

  • Profundidad y número de filtros para capturar características de alto nivel.
  • Tamaño del kernel: filtros pequeños como 3x3 suelen ser efectivos y eficientes.
  • Stride y padding para controlar la dimensionalidad y preservar información espacial.
  • Evitar el sobreajuste mediante técnicas como regularización, aumento de datos y uso de capas Dropout.

En tareas de visión por ordenador, las capas convolucionales son especialmente efectivas para clasificación de imágenes, detección de objetos y segmentación semántica. También se aplican en dominios como el procesamiento de audio y texto.

Ejemplo completo de un modelo CNN para clasificación de imágenes:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout

modelo = Sequential()

modelo.add(Conv2D(32, (3, 3), activation='relu', input_shape=(128, 128, 3)))
modelo.add(Conv2D(32, (3, 3), activation='relu'))
modelo.add(MaxPooling2D(pool_size=(2, 2)))
modelo.add(Dropout(0.25))

modelo.add(Conv2D(64, (3, 3), activation='relu'))
modelo.add(Conv2D(64, (3, 3), activation='relu'))
modelo.add(MaxPooling2D(pool_size=(2, 2)))
modelo.add(Dropout(0.25))

modelo.add(Flatten())
modelo.add(Dense(512, activation='relu'))
modelo.add(Dropout(0.5))
modelo.add(Dense(10, activation='softmax'))

modelo.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

En este ejemplo:

  • Se combinan capas convolucionales y de pooling para extraer características y reducir dimensionalidad.
  • Dropout ayuda a prevenir el sobreajuste apagando neuronas aleatoriamente.
  • Las capas densas finales procesan las características extraídas para la clasificación.

Para mejorar el rendimiento en conjuntos de datos limitados, el aprendizaje por transferencia es una estrategia efectiva. Consiste en utilizar modelos preentrenados y adaptar sus capas finales:

from tensorflow.keras.applications import VGG16
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Flatten

# Cargar el modelo VGG16 preentrenado sin las capas superiores
base_modelo = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# Añadir nuevas capas para nuestra tarea específica
x = base_modelo.output
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
salida = Dense(10, activation='softmax')(x)

# Definir el modelo completo
modelo_transferencia = Model(inputs=base_modelo.input, outputs=salida)

# Congelar las capas convolucionales del modelo base
for capa in base_modelo.layers:
    capa.trainable = False

# Compilar el modelo
modelo_transferencia.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

En este caso:

  • Se utiliza VGG16 preentrenado en ImageNet como base.
  • Se añaden capas densas para adaptar el modelo a una nueva tarea con 10 clases.
  • Al congelar las capas del modelo base, se evita modificar los pesos preentrenados durante el entrenamiento.

Es crucial ajustar correctamente las dimensiones de entrada y salida al trabajar con capas convolucionales. Utilizar modelo.summary() ayuda a inspeccionar la arquitectura y verificar las formas de los tensores:

# Mostrar resumen del modelo
modelo.summary()

Las capas convolucionales en Keras brindan una gran flexibilidad para construir modelos potentes y eficientes, adaptables a diversas tareas en aprendizaje profundo. Su correcto uso, combinado con prácticas como la regularización y el aprendizaje por transferencia, puede conducir a resultados sobresalientes en problemas complejos.

Capas recurrentes

Las capas recurrentes en Keras son fundamentales para procesar datos secuenciales o temporales, como series de tiempo, texto y audio. Estas capas permiten que la red neuronal mantenga información sobre estados anteriores, lo que es esencial para capturar dependencias en secuencias de datos.

Keras proporciona varias capas recurrentes, siendo las más comunes SimpleRNN, LSTM y GRU. Cada una tiene características específicas que las hacen adecuadas para diferentes tipos de problemas secuenciales.

La capa SimpleRNN es la forma más básica de capa recurrente. Implementa una red neuronal recurrente simple cuya salida se retroalimenta a sí misma para el siguiente paso temporal:

from tensorflow.keras.layers import SimpleRNN

# Crear una capa SimpleRNN con 50 unidades
capa_simple_rnn = SimpleRNN(units=50, activation='tanh')

Sin embargo, las SimpleRNN suelen tener dificultades para aprender dependencias a largo plazo debido al problema del desvanecimiento del gradiente. Para superar esta limitación, se utilizan capas más avanzadas como LSTM.

La capa LSTM (Long Short-Term Memory) está diseñada para aprender dependencias de largo plazo en secuencias. Utiliza puertas de entrada, olvido y salida para controlar el flujo de información:

from tensorflow.keras.layers import LSTM

# Crear una capa LSTM con 100 unidades
capa_lstm = LSTM(units=100, activation='tanh')

Las LSTM son especialmente efectivas en tareas como modelado del lenguaje, traducción automática y predicción de series temporales, donde las dependencias a largo plazo son cruciales.

Otra capa recurrente popular es GRU (Gated Recurrent Unit), que es una variante simplificada de LSTM. Las GRU suelen ser más rápidas de entrenar y pueden ofrecer un rendimiento similar:

from tensorflow.keras.layers import GRU

# Crear una capa GRU con 80 unidades
capa_gru = GRU(units=80, activation='tanh')

Al utilizar capas recurrentes, es importante considerar el parámetro return_sequences. Por defecto, una capa recurrente devuelve solo la salida del último paso temporal, pero si se establece return_sequences=True, la capa devolverá la salida en cada paso temporal:

# Capa LSTM que devuelve secuencias completas
capa_lstm_seq = LSTM(units=100, return_sequences=True)

Esto es esencial al construir modelos profundos que apilan varias capas recurrentes, permitiendo que cada capa tenga acceso a las salidas completas de la capa anterior.

Para mejorar el rendimiento y prevenir el sobreajuste, se pueden aplicar técnicas de regularización como dropout y recurrent_dropout:

# Capa GRU con dropout interno y recurrente
capa_gru_dropout = GRU(units=80, dropout=0.2, recurrent_dropout=0.2)

Aquí, dropout se aplica a las entradas de la capa y recurrent_dropout a las conexiones recurrentes entre unidades internas.

Un ejemplo de modelo utilizando capas recurrentes para clasificación de secuencias es el siguiente:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense

modelo = Sequential()
modelo.add(LSTM(128, input_shape=(timesteps, features)))
modelo.add(Dense(10, activation='softmax'))

modelo.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

En este modelo, input_shape debe especificar el número de pasos temporales (timesteps) y el número de características por paso. La capa LSTM procesará la secuencia y la capa densa final realizará la clasificación.

Para tareas donde se necesita una salida por cada elemento de la secuencia, como en etiquetado de secuencias o traducción, es necesario configurar las capas recurrentes con return_sequences=True y utilizar capas como TimeDistributed:

from tensorflow.keras.layers import TimeDistributed

modelo = Sequential()
modelo.add(LSTM(128, return_sequences=True, input_shape=(timesteps, features)))
modelo.add(LSTM(64, return_sequences=True))
modelo.add(TimeDistributed(Dense(10, activation='softmax')))

modelo.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

La capa TimeDistributed aplica la misma capa densa a cada paso temporal de la secuencia, permitiendo obtener una clasificación o predicción para cada elemento.

Las capas bidireccionales pueden mejorar el rendimiento al procesar secuencias en ambas direcciones, capturando información del pasado y del futuro:

from tensorflow.keras.layers import Bidirectional

# Capa LSTM bidireccional
capa_bi_lstm = Bidirectional(LSTM(64))

modelo = Sequential()
modelo.add(capa_bi_lstm)
modelo.add(Dense(10, activation='softmax'))

Las capas bidireccionales son especialmente útiles en procesamiento del lenguaje natural, donde el contexto completo de una frase puede influir en la interpretación de cada palabra.

Para problemas con secuencias muy largas, es importante manejar eficientemente los datos. El truncamiento y el padding permiten que todas las secuencias en un lote tengan la misma longitud:

from tensorflow.keras.preprocessing.sequence import pad_sequences

# Suponiendo que 'sequences' es una lista de secuencias de diferentes longitudes
sequences_padded = pad_sequences(sequences, maxlen=max_length, padding='post')

Además, se pueden utilizar máscaras para indicar a las capas que ignoren ciertos pasos temporales:

from tensorflow.keras.layers import Masking

modelo = Sequential()
modelo.add(Masking(mask_value=0., input_shape=(timesteps, features)))
modelo.add(LSTM(128))

La capa Masking ayudará a que la capa LSTM ignore los valores de padding (por ejemplo, ceros) en las secuencias.

Al entrenar modelos con capas recurrentes, es posible aprovechar la aceleración por hardware. Si se dispone de una GPU, Keras utilizará automáticamente las implementaciones optimizadas de CuDNN para capas LSTM y GRU, lo que puede acelerar significativamente el entrenamiento.

Es importante también ajustar adecuadamente los hiperparámetros, como el número de unidades, la tasa de aprendizaje y el tipo de optimizador, para obtener un rendimiento óptimo. Las capas recurrentes son poderosas, pero pueden ser propensas al sobreajuste, por lo que técnicas como la regularización y el uso de conjuntos de validación son esenciales.

En resumen, las capas recurrentes en Keras ofrecen una herramienta robusta para abordar problemas que involucran datos secuenciales, permitiendo construir modelos capaces de interpretar y predecir comportamientos a lo largo del tiempo.

Capas de regularización

Las capas de regularización en Keras son componentes esenciales para prevenir el sobreajuste en modelos de aprendizaje profundo. Estas capas aplican técnicas que ayudan a mejorar la generalización del modelo al introducir cierta penalización o perturbación durante el entrenamiento. Entre las capas de regularización más utilizadas se encuentran Dropout, GaussianNoise y GaussianDropout.

La capa Dropout es una de las técnicas de regularización más populares. Consiste en apagar aleatoriamente un porcentaje de neuronas durante cada paso de entrenamiento, lo que evita que las neuronas se vuelvan demasiado dependientes entre sí. Esto obliga al modelo a aprender representaciones más robustas y reduce el riesgo de sobreajuste:

from tensorflow.keras.layers import Dropout

# Añadir una capa Dropout con una tasa del 50%
capa_dropout = Dropout(rate=0.5)

En este ejemplo, el parámetro rate=0.5 indica que el 50% de las neuronas se desactivarán aleatoriamente en cada paso. Es importante destacar que durante la fase de prueba o inferencia, la capa Dropout no afecta al modelo y todas las neuronas están activas.

Otra capa de regularización común es GaussianNoise, que introduce ruido gaussiano a la salida de la capa anterior. Esto puede ser útil para hacer el modelo más robusto a variaciones en los datos de entrada:

from tensorflow.keras.layers import GaussianNoise

# Añadir una capa GaussianNoise con desviación estándar de 0.1
capa_ruido_gaussiano = GaussianNoise(stddev=0.1)

La adición de ruido ayuda al modelo a aprender patrones significativos y a no depender excesivamente de características específicas del conjunto de entrenamiento. El parámetro stddev define la desviación estándar del ruido gaussiano aplicado.

La capa GaussianDropout es similar a Dropout, pero en lugar de apagar neuronas, multiplica la activación de las neuronas por una variable aleatoria de distribución gaussiana. Esto también sirve para regularizar el modelo:

from tensorflow.keras.layers import GaussianDropout

# Añadir una capa GaussianDropout con tasa de 0.5
capa_gaussian_dropout = GaussianDropout(rate=0.5)

En este caso, rate controla la intensidad de la regularización aplicada mediante la multiplicación de las activaciones por factores aleatorios.

Las capas de regularización se suelen colocar después de capas densas o convolucionales. Por ejemplo, en un modelo secuencial:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout

modelo = Sequential()
modelo.add(Dense(128, activation='relu', input_shape=(100,)))
modelo.add(Dropout(0.5))
modelo.add(Dense(64, activation='relu'))
modelo.add(Dropout(0.5))
modelo.add(Dense(10, activation='softmax'))

En este modelo, las capas Dropout se sitúan entre las capas densas, lo que ayuda a regularizar el aprendizaje y prevenir el sobreajuste.

La regularización también puede aplicarse directamente sobre los pesos de las capas mediante la utilización de regularizadores L1 y L2. Aunque no son capas en sí mismas, los regularizadores de pesos se especifican al definir las capas densas o convolucionales:

from tensorflow.keras.regularizers import l1, l2
from tensorflow.keras.layers import Dense

# Capa densa con regularización L1 en los pesos y L2 en los sesgos
capa_regularizada = Dense(
    units=64,
    activation='relu',
    kernel_regularizer=l1(0.01),
    bias_regularizer=l2(0.01)
)

En este caso, el parámetro kernel_regularizer aplica una penalización L1 a los pesos de la capa, fomentando la esparsidad de los mismos, mientras que bias_regularizer aplica una penalización L2 a los sesgos, lo que limita su magnitud.

La capa ActivityRegularization permite aplicar una penalización directamente sobre las activaciones de la capa anterior. Esto puede influir en la forma en que las activaciones contribuyen a la función de pérdida:

from tensorflow.keras.layers import ActivityRegularization, Dense

modelo = Sequential()
modelo.add(Dense(64, activation='relu', input_shape=(100,)))
modelo.add(ActivityRegularization(l1=0.01, l2=0.01))
modelo.add(Dense(10, activation='softmax'))

Aquí, ActivityRegularization añade términos de penalización L1 y L2 a las activaciones, lo que puede contribuir a un mejor equilibrio en la distribución de los valores de salida.

Además de estas capas, la normalización por lotes o BatchNormalization también puede considerarse una técnica de regularización, aunque su objetivo principal es acelerar el entrenamiento y estabilizar la distribución de las activaciones:

from tensorflow.keras.layers import BatchNormalization, Dense

modelo = Sequential()
modelo.add(Dense(128, activation='relu', input_shape=(100,)))
modelo.add(BatchNormalization())
modelo.add(Dense(10, activation='softmax'))

BatchNormalization normaliza las activaciones de la capa anterior por lote, lo que puede reducir el problema del desvanecimiento del gradiente y mejorar la convergencia del modelo.

Al combinar diferentes capas de regularización y técnicas, es posible diseñar modelos más robustos y capaces de generalizar mejor a nuevos datos. No obstante, es importante ajustar adecuadamente los hiperparámetros de regularización, ya que una regularización excesiva puede llevar a un subajuste del modelo.

Por ejemplo, al entrenar un modelo, se puede utilizar un callback de EarlyStopping para detener el entrenamiento cuando la pérdida en el conjunto de validación deja de mejorar, evitando así el sobreajuste:

from tensorflow.keras.callbacks import EarlyStopping

early_stopping = EarlyStopping(patience=5, restore_best_weights=True)

modelo.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
modelo.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=100, callbacks=[early_stopping])

En este ejemplo, patience=5 indica que el entrenamiento se detendrá si no hay mejora en la pérdida de validación durante 5 épocas consecutivas, y restore_best_weights=True restaurará los pesos del modelo a la mejor época observada.

Al seleccionar las capas de regularización adecuadas y configurarlas correctamente, se puede mejorar significativamente el rendimiento del modelo y su capacidad para generalizar a datos no vistos.

Capas personalizadas

En Keras, es posible crear capas personalizadas para implementar transformaciones o cálculos que no están cubiertos por las capas predefinidas. Esto es especialmente útil cuando se requiere funcionalidad específica para un modelo avanzado o se desea experimentar con nuevas ideas en el diseño de redes neuronales.

Para crear una capa personalizada, se hereda de la clase base Layer de Keras y se sobreescriben los métodos necesarios. El método clave es call, donde se define la lógica computacional de la capa. Si la capa tiene variables o pesos que deben ser aprendidos durante el entrenamiento, se pueden crear en el método __init__ o en build.

Por ejemplo, para crear una capa personalizada que realiza una transformación específica:

from tensorflow.keras.layers import Layer
import tensorflow as tf

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

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

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b

En este ejemplo:

  • Se define una clase MiCapaPersonalizada que hereda de Layer.
  • En el método build, se crean los pesos w y b utilizando add_weight, y se especifica que son entrenables.
  • El método call implementa la lógica de la capa, en este caso una transformación lineal simple.

Al utilizar la capa personalizada en un modelo, se integra como cualquier otra capa de Keras:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input

# Definir el modelo utilizando Input para evitar advertencias
modelo = Sequential([
    Input(shape=(100,)),  # Define la entrada explícitamente
    MiCapaPersonalizada(unidades=64),
    tf.keras.layers.ReLU(),
    tf.keras.layers.Dense(10, activation='softmax')
])

Las capas personalizadas permiten incorporar comportamientos complejos que no son posibles con las capas estándar. Por ejemplo, se puede crear una capa que aplique una función de activación específica o que implemente un mecanismo de atención personalizado.

Es importante considerar el manejo de formas y dimensiones al crear capas personalizadas. Utilizar las utilidades de Keras y TensorFlow, como tf.shape y las funciones de manipulación de tensores, ayuda a garantizar la compatibilidad y evitar errores durante el entrenamiento.

Para añadir regularización o restricciones a los pesos de la capa personalizada, se pueden incluir argumentos adicionales en add_weight:

from tensorflow.keras import regularizers, constraints

self.w = self.add_weight(
    shape=(input_shape[-1], self.unidades),
    initializer='random_normal',
    regularizer=regularizers.l2(0.01),
    constraint=constraints.max_norm(2.),
    trainable=True,
    name='peso')

En este caso, se aplica una regularización L2 y se establece una restricción de norma máxima a los pesos.

Además, se pueden definir variables no entrenables para almacenar parámetros calculados o estados internos de la capa:

self.total = self.add_weight(
    shape=(),
    initializer='zeros',
    trainable=False,
    name='total_acumulado')

Al implementar capas personalizadas, es posible aprovechar las ventajas de AutoGraph de TensorFlow y utilizar el decorador @tf.function para mejorar el rendimiento:

@tf.function
def call(self, inputs):
    ...

Sin embargo, en el contexto de subclases de capas, Keras gestiona automáticamente la compilación de gráficos y no es necesario aplicar manualmente el decorador.

Para mejorar la reutilización y la legibilidad del código, es recomendable definir funciones auxiliares dentro de la capa o en módulos separados si la lógica es compleja.

Las capas personalizadas también pueden manejar múltiples entradas y salidas. Al definir el método call, se puede aceptar un diccionario o una lista de tensores:

def call(self, inputs):
    x1, x2 = inputs
    return x1 + x2

En este ejemplo, la capa suma dos tensores de entrada.

Cuando se utilizan capas personalizadas en combinación con la API Funcional de Keras, se facilita la construcción de modelos con arquitecturas más sofisticadas:

from tensorflow.keras import Input, Model

entrada = Input(shape=(100,))
x = MiCapaPersonalizada(64)(entrada)
salida = tf.keras.layers.Dense(10, activation='softmax')(x)

modelo = Model(inputs=entrada, outputs=salida)

Es esencial asegurarse de que las capas personalizadas sean compatibles con las funcionalidades de Keras, como el guardado y carga de modelos. Para ello, se debe implementar el método get_config si la capa tiene parámetros que necesitan ser serializados:

def get_config(self):
    config = super().get_config()
    config.update({'unidades': self.unidades})
    return config

Esto permite recrear la capa a partir de su configuración al cargar un modelo guardado.

Las capas personalizadas abren la posibilidad de explorar nuevas ideas y algoritmos en el ámbito del aprendizaje profundo, ofreciendo flexibilidad y control total sobre las operaciones realizadas en el modelo.

Al desarrollar capas personalizadas, es importante probar y verificar su correcto funcionamiento, utilizando unidades de prueba y validando su desempeño en conjuntos de datos de prueba antes de integrarlas en modelos más grandes.

Aprende TensorFlow GRATIS online

Todas las lecciones de TensorFlow

Accede a todas las lecciones de TensorFlow y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción Al Deep Learning Y Redes Neuronales

TensorFlow

Introducción Y Entorno

Introducción A Tensorflow

TensorFlow

Introducción Y Entorno

Introducción A Keras

TensorFlow

Introducción Y Entorno

Redes Neuronales De Múltiples Capas

TensorFlow

Introducción Y Entorno

Algoritmo De Backpropagation

TensorFlow

Introducción Y Entorno

Implementación De Una Red Neuronal Con Numpy

TensorFlow

Introducción Y Entorno

Modelo Con Api Secuencial

TensorFlow

Construcción De Modelos Con Keras

Modelo Con Api Funcional

TensorFlow

Construcción De Modelos Con Keras

Subclases De Modelos

TensorFlow

Construcción De Modelos Con Keras

Capas En Keras

TensorFlow

Construcción De Modelos Con Keras

Funciones De Activación

TensorFlow

Construcción De Modelos Con Keras

Redes Neuronales Densas De Regresión

TensorFlow

Construcción De Modelos Con Keras

Redes Neuronales Densas De Clasificación Binaria

TensorFlow

Construcción De Modelos Con Keras

Redes Neuronales Densas De Clasificación Multiclase

TensorFlow

Construcción De Modelos Con Keras

Redes Convolucionales Cnn

TensorFlow

Construcción De Modelos Con Keras

Redes Recurrentes Rnn

TensorFlow

Construcción De Modelos Con Keras

Redes Neuronales Mixtas

TensorFlow

Construcción De Modelos Con Keras

Api Dataset

TensorFlow

Procesamiento De Datos

Manejo De Valores Faltantes

TensorFlow

Procesamiento De Datos

Encoding De Valores Categóricos En Continuos

TensorFlow

Procesamiento De Datos

Preprocesados De Escalado, Normalización Y Estandarización

TensorFlow

Procesamiento De Datos

Generación De Nuevas Características

TensorFlow

Procesamiento De Datos

Algoritmos De Optimización

TensorFlow

Entrenamiento Y Evaluación De Modelos

Técnicas De Validación

TensorFlow

Entrenamiento Y Evaluación De Modelos

Monitorización De Entrenamiento

TensorFlow

Entrenamiento Y Evaluación De Modelos

Redes Generativas Adversariales Gans

TensorFlow

Técnicas Avanzadas

Transformers

TensorFlow

Técnicas Avanzadas

Autoencoders

TensorFlow

Técnicas Avanzadas

Carga De Capas Ya Hechas

TensorFlow

Técnicas Avanzadas

Regularización De Modelos

TensorFlow

Herramientas Y Optimización

Hiperparámetros Con Keras Tuner

TensorFlow

Herramientas Y Optimización

Tensorboard

TensorFlow

Herramientas Y Optimización

Uso De Tensorflow Keras En Gpu

TensorFlow

Herramientas Y Optimización

Accede GRATIS a TensorFlow y certifícate

Objetivos de aprendizaje de esta lección

  • Comprender el funcionamiento de las capas en Keras y su impacto en los modelos.
  • Diseñar modelos utilizando capas densas, convolucionales y recurrentes.
  • Implementar regularización con Dropout, BatchNormalization y ActivityRegularization.
  • Crear y usar capas personalizadas con transformaciones específicas.
  • Integrar técnicas como el aprendizaje por transferencia y el uso de modelos preentrenados.