Módulo: Redes neuronales
Este módulo forma parte del curso de TensorFlow. Incluye 11 lecciones .
TensorFlow ofrece varias formas de construir redes neuronales, pero Keras se ha convertido en la API estándar y recomendada para el desarrollo de estos modelos debido a su simplicidad y flexibilidad. Keras está integrado directamente en TensorFlow desde la versión 2.0, proporcionando una interfaz de alto nivel que facilita la creación, entrenamiento y evaluación de modelos de aprendizaje profundo.
Keras sigue una filosofía de diseño centrada en la experiencia del desarrollador, siendo intuitivo, modular y extensible. Esto permite construir redes neuronales complejas con pocas líneas de código, manteniendo al mismo tiempo la potencia y flexibilidad de TensorFlow como motor de cómputo subyacente.
La estructura fundamental de cualquier red neuronal en Keras se compone de capas que procesan tensores de entrada y producen tensores de salida. Estas capas encapsulan tanto los parámetros entrenables (pesos y sesgos) como las operaciones que transforman los datos.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
## Verificamos la versión de Keras que estamos utilizando
print(f"Versión de TensorFlow: {tf.__version__}")
print(f"Versión de Keras: {keras.__version__}")
En Keras existen dos formas principales de construir modelos: la API Secuencial y la API Funcional. La primera es más sencilla y adecuada para redes con una sola entrada y una sola salida, donde las capas se conectan secuencialmente. La segunda ofrece mayor flexibilidad para crear arquitecturas complejas con múltiples entradas, salidas o conexiones no lineales.
Veamos primero cómo construir un modelo secuencial básico:
## Modelo secuencial para clasificación de imágenes
modelo = keras.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
Este ejemplo ilustra una arquitectura convolucional típica para clasificación de imágenes, donde las capas convolutivas extraen características, las capas de pooling reducen la dimensionalidad, y las capas densas realizan la clasificación final.
Para modelos con estructuras más complejas, la API Funcional proporciona mayor flexibilidad:
## Modelo funcional con múltiples entradas
entrada_texto = keras.Input(shape=(100,))
entrada_imagen = keras.Input(shape=(28, 28, 3))
## Procesar texto
x1 = layers.Embedding(20000, 128)(entrada_texto)
x1 = layers.LSTM(32)(x1)
## Procesar imagen
x2 = layers.Conv2D(32, (3, 3))(entrada_imagen)
x2 = layers.MaxPooling2D((2, 2))(x2)
x2 = layers.Flatten()(x2)
## Combinar ambas entradas
combinado = layers.concatenate([x1, x2])
salida = layers.Dense(1, activation='sigmoid')(combinado)
## Crear el modelo especificando entradas y salidas
modelo = keras.Model(inputs=[entrada_texto, entrada_imagen], outputs=salida)
Las capas son los bloques fundamentales de cualquier red neuronal en Keras. TensorFlow ofrece una amplia variedad de capas predefinidas:
- Capas básicas: Dense (completamente conectada), Dropout, Activation
- Capas convolucionales: Conv1D, Conv2D, Conv3D, SeparableConv2D
- Capas de pooling: MaxPooling2D, AveragePooling2D, GlobalMaxPooling2D
- Capas recurrentes: SimpleRNN, LSTM, GRU, Bidirectional
- Capas de normalización: BatchNormalization, LayerNormalization
- Capas de regularización: Dropout, ActivityRegularization, SpatialDropout
- Capas de atención: Attention, MultiHeadAttention
- Capas para procesamiento de secuencias: Embedding, TimeDistributed
- Capas para operaciones de fusión: Add, Concatenate, Multiply, Average
La compilación del modelo es un paso crucial antes de iniciar el entrenamiento. Aquí definimos el optimizador, la función de pérdida y las métricas que evaluarán el rendimiento:
modelo.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy']
)
TensorFlow ofrece varios optimizadores como SGD, Adam, RMSprop o Adagrad, cada uno con sus propias características y casos de uso recomendados. Igualmente, podemos elegir entre diversas funciones de pérdida según el tipo de problema, como BinaryCrossentropy para clasificación binaria, MeanSquaredError para regresión o KLDivergence para distribuciones probabilísticas.
Una vez compilado el modelo, podemos entrenarlo con el método fit():
## Supongamos que x_train e y_train son nuestros datos de entrenamiento
history = modelo.fit(
x_train, y_train,
epochs=10,
batch_size=64,
validation_split=0.2,
callbacks=[
keras.callbacks.EarlyStopping(patience=3, restore_best_weights=True),
keras.callbacks.ModelCheckpoint('mejor_modelo.keras', save_best_only=True),
keras.callbacks.TensorBoard(log_dir='./logs')
]
)
Los callbacks son funciones que se ejecutan en determinados momentos durante el entrenamiento y permiten automatizar tareas como detener el entrenamiento cuando no hay mejora (EarlyStopping), guardar el mejor modelo (ModelCheckpoint) o registrar métricas para su visualización posterior (TensorBoard).
El objeto history devuelto por fit() contiene información valiosa sobre el proceso de entrenamiento:
import matplotlib.pyplot as plt
## Visualizar la evolución del entrenamiento
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Pérdida entrenamiento')
plt.plot(history.history['val_loss'], label='Pérdida validación')
plt.title('Evolución de la pérdida')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Precisión entrenamiento')
plt.plot(history.history['val_accuracy'], label='Precisión validación')
plt.title('Evolución de la precisión')
plt.legend()
plt.tight_layout()
plt.show()
Una vez entrenado, podemos evaluar el rendimiento del modelo en un conjunto de datos de prueba:
resultados = modelo.evaluate(x_test, y_test, verbose=1)
print(f"Pérdida en test: {resultados[0]:.4f}")
print(f"Precisión en test: {resultados[1]:.4f}")
Y realizar predicciones con nuevos datos:
predicciones = modelo.predict(nuevos_datos)
Las arquitecturas de redes neuronales son muy diversas y se adaptan a diferentes tipos de problemas. Algunas arquitecturas fundamentales incluyen:
- Redes fully-connected (MLP): Para datos tabulares y problemas sencillos
- Redes convolucionales (CNN): Para procesar datos con estructura de rejilla como imágenes
- Redes recurrentes (RNN, LSTM, GRU): Para secuencias y datos temporales
- Redes con atención: Para capturar dependencias a larga distancia en secuencias
- Autoencoders: Para reducción de dimensionalidad y aprendizaje no supervisado
- Redes generativas adversarias (GAN): Para generar nuevos datos similares a los de entrenamiento
Keras facilita la implementación de estas arquitecturas mediante sus capas predefinidas. Por ejemplo, una red neuronal recurrente para procesamiento de texto:
modelo = keras.Sequential([
layers.Embedding(input_dim=10000, output_dim=128, input_length=100),
layers.Bidirectional(layers.LSTM(64, return_sequences=True)),
layers.Bidirectional(layers.LSTM(32)),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(1, activation='sigmoid')
])
Una característica poderosa de Keras es la capacidad de crear capas personalizadas para implementar funcionalidades específicas:
class CapaPersonalizada(layers.Layer):
def __init__(self, unidades=32, **kwargs):
super(CapaPersonalizada, self).__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='pesos'
)
self.b = self.add_weight(
shape=(self.unidades,),
initializer='zeros',
trainable=True,
name='sesgo'
)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
def get_config(self):
config = super(CapaPersonalizada, self).get_config()
config.update({'unidades': self.unidades})
return config
Además de las capas personalizadas, podemos crear funciones de pérdida y métricas personalizadas para problemas específicos:
## Función de pérdida personalizada
def focal_loss(gamma=2.0, alpha=0.25):
def focal_loss_fn(y_true, y_pred):
pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
pt_1 = tf.clip_by_value(pt_1, 1e-9, 1.0)
pt_0 = tf.clip_by_value(pt_0, 1e-9, 1.0)
return -tf.reduce_sum(alpha * tf.pow(1. - pt_1, gamma) * tf.math.log(pt_1)) - \
tf.reduce_sum((1-alpha) * tf.pow(pt_0, gamma) * tf.math.log(1. - pt_0))
return focal_loss_fn
## Métrica personalizada
class F1Score(keras.metrics.Metric):
def __init__(self, name='f1_score', **kwargs):
super(F1Score, self).__init__(name=name, **kwargs)
self.precision = keras.metrics.Precision()
self.recall = keras.metrics.Recall()
def update_state(self, y_true, y_pred, sample_weight=None):
self.precision.update_state(y_true, y_pred, sample_weight)
self.recall.update_state(y_true, y_pred, sample_weight)
def result(self):
p = self.precision.result()
r = self.recall.result()
return (2 * p * r) / (p + r + keras.backend.epsilon())
def reset_state(self):
self.precision.reset_st
Otros módulos de este curso
Redes neuronales
Lecciones de este módulo
Explora todas las lecciones disponibles en Redes neuronales
Todos los módulos del curso
Navega entre los módulos de TensorFlow
Explora más sobre TensorFlow
Descubre más recursos de TensorFlow
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, TensorFlow es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.