Redes Completamente convolucionales (FCN)
Fully Convolutional Networks (FCNs) son un tipo de arquitectura de red neuronal diseñada para tareas de procesamiento de imágenes, en particular para problemas que requieren predicciones a nivel de píxeles, como la segmentación de imágenes y la detección de bordes. Las FCNs son únicas en el sentido de que están construidas completamente con capas convolucionales y no utilizan capas densas (fully connected) al final, lo cual permite que la red mantenga la estructura espacial de las imágenes a lo largo del procesamiento.
Principales Características de las FCNs
- Capas Convolucionales en Todo el Modelo: Al eliminar las capas densas, las FCNs utilizan capas convolucionales en todos los niveles, lo que permite generar mapas de características con resolución espacial.
- Predicciones a Nivel de Píxel: En lugar de reducir una imagen a un solo valor o etiqueta, las FCNs pueden clasificar cada píxel de una imagen de acuerdo a su pertenencia a una clase, lo cual es ideal para segmentación.
- Tamaño de Entrada Flexible: Al no depender de capas densas, las FCNs pueden procesar imágenes de diferentes tamaños sin necesidad de ajustes, siempre y cuando se mantengan las proporciones de la arquitectura convolucional.
Ejemplo de Implementación en Keras para Segmentación de Imágenes
A continuación, un ejemplo básico de una FCN utilizando Keras para la tarea de segmentación de imágenes. Aquí utilizamos una arquitectura simplificada con algunas capas convolucionales y de pooling, y un proceso de upsampling para restablecer la resolución de la imagen de salida.
import tensorflow as tf
from tensorflow.keras import layers, models
# Dimensiones de la entrada
input_shape = (128, 128, 3) # Ejemplo con imágenes de tamaño 128x128 y 3 canales (RGB)
# Modelo FCN para segmentación de imágenes
def build_fcn(input_shape):
inputs = layers.Input(shape=input_shape)
# Bloque 1 de convoluciones
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
x = layers.MaxPooling2D((2, 2))(x)
# Bloque 2 de convoluciones
x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2))(x)
# Bloque 3 de convoluciones
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2))(x)
# Bloque 4 de convoluciones
x = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(x)
# Upsampling (restaurar resolución original)
x = layers.Conv2DTranspose(128, (3, 3), strides=(2, 2), padding='same', activation='relu')(x)
x = layers.Conv2DTranspose(64, (3, 3), strides=(2, 2), padding='same', activation='relu')(x)
x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), padding='same', activation='relu')(x)
# Salida: una capa convolucional final para clasificar cada píxel
outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(x)
# Construcción del modelo
model = models.Model(inputs, outputs)
return model
# Crear el modelo
fcn_model = build_fcn(input_shape)
fcn_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
fcn_model.summary()
Explicación del Ejemplo
- Capas Convolucionales y Pooling: La red comienza con varias capas convolucionales y de max pooling para extraer características de la imagen y reducir su tamaño.
- Upsampling o Transposed Convolutions: Después de extraer características, el modelo usa capas de convolución transpuesta (
Conv2DTranspose
) para aumentar la resolución nuevamente, de modo que la salida final tenga el mismo tamaño que la entrada. Esto permite una clasificación de cada píxel de la imagen. - Salida con Clasificación por Píxel: La última capa tiene una función de activación sigmoide que permite obtener una salida de segmentación binaria (ej., identificar qué píxeles pertenecen a una clase en particular).
Ejemplo de Segmentación en una Imagen Sintética
Para aplicar el modelo a una imagen y visualizar la predicción, podemos usar el siguiente ejemplo:
import numpy as np
import matplotlib.pyplot as plt
# Crear una imagen de ejemplo (input de tamaño 128x128)
example_image = np.random.rand(1, 128, 128, 3) # Imagen de prueba aleatoria
# Obtener la predicción del modelo
predicted_mask = fcn_model.predict(example_image)
# Mostrar la imagen y la máscara predicha
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title("Imagen de Entrada")
plt.imshow(example_image[0])
plt.subplot(1, 2, 2)
plt.title("Máscara Predicha")
plt.imshow(predicted_mask[0, :, :, 0], cmap="gray")
plt.show()
Aplicaciones de las FCNs
- Segmentación de Imágenes Médicas: Identificación de áreas específicas en escaneos médicos (ej., tumores en MRI).
- Visión en Automóviles Autónomos: Para identificar y clasificar cada píxel en una imagen de carretera, distinguiendo entre caminos, señales, peatones y otros elementos.
- Reconocimiento de Escenas: En visión por computadora, las FCNs permiten clasificar áreas completas de una imagen en diversas categorías (cielo, edificios, etc.).
Las FCNs son una poderosa herramienta cuando necesitamos clasificar cada píxel de una imagen, preservando la estructura espacial para tareas complejas en las que las relaciones espaciales son fundamentales.