TensorFlow: Preprocesados y preparación

TensorFlow
TensorFlow
Actualizado: 14/03/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

El preprocesado de datos constituye una fase crítica en cualquier proyecto de aprendizaje automático. Antes de que un modelo pueda aprender patrones útiles, los datos deben ser transformados a un formato adecuado, limpiados de inconsistencias y preparados para maximizar la eficacia del entrenamiento. TensorFlow proporciona un conjunto completo de herramientas que facilitan estas tareas, permitiendo construir pipelines de datos eficientes y optimizados.

API tf.data: la base del preprocesado en TensorFlow

La API tf.data es el núcleo del ecosistema de preprocesado en TensorFlow, diseñada para construir pipelines de datos eficientes, flexibles y con alto rendimiento. Esta API permite cargar datos desde diferentes fuentes, transformarlos y entregarlos al modelo en lotes, todo dentro del grafo de computación de TensorFlow, lo que optimiza el rendimiento y evita cuellos de botella.

import tensorflow as tf
import numpy as np

# Crear un dataset simple desde un tensor
datos = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
dataset = tf.data.Dataset.from_tensor_slices(datos)

# Aplicar transformaciones
dataset = dataset.map(lambda x: x * 2)  # Multiplicar cada elemento por 2
dataset = dataset.batch(3)  # Agrupar en lotes de 3 elementos

# Iterar sobre el dataset
for lote in dataset:
    print(lote.numpy())

La creación de un dataset puede realizarse desde diversas fuentes como tensores, archivos TFRecord, archivos de texto o generadores de Python. Una vez creado, podemos aplicar una serie de transformaciones encadenadas para preparar los datos según nuestras necesidades.

Carga de diferentes tipos de datos

Datos tabulares y numéricos

Los datos tabulares pueden cargarse desde diferentes formatos como CSV, Excel o bases de datos. TensorFlow facilita la carga directa de archivos CSV:

csv_dataset = tf.data.experimental.make_csv_dataset(
    file_pattern="datos.csv",
    batch_size=32,
    column_names=["caracteristica1", "caracteristica2", "etiqueta"],
    label_name="etiqueta",
    num_epochs=1
)

for features_batch, labels_batch in csv_dataset:
    print(f"Características: {features_batch}")
    print(f"Etiquetas: {labels_batch}")
    break  # Solo mostramos el primer lote

Para conjuntos de datos más complejos o que requieren un preprocesado específico, podemos utilizar bibliotecas como pandas para la carga inicial y luego convertirlos a objetos tf.data.Dataset:

import pandas as pd

# Cargar datos con pandas
df = pd.read_csv("datos.csv")

# Separar características y etiquetas
features = df.drop("etiqueta", axis=1).values
labels = df["etiqueta"].values

# Crear dataset de TensorFlow
dataset = tf.data.Dataset.from_tensor_slices((features, labels))

Imágenes

El preprocesado de imágenes es crucial en tareas de visión por computador. TensorFlow proporciona funciones específicas para cargar y transformar imágenes:

def cargar_imagen(ruta_archivo):
    # Leer el archivo
    img_raw = tf.io.read_file(ruta_archivo)
    # Decodificar la imagen
    img = tf.io.decode_image(img_raw, channels=3, expand_animations=False)
    # Redimensionar
    img = tf.image.resize(img, [224, 224])
    # Normalizar valores a [0, 1]
    img = tf.cast(img, tf.float32) / 255.0
    return img

# Crear una lista de rutas de archivos
rutas_imagenes = tf.data.Dataset.list_files("imagenes/*.jpg")

# Aplicar la función de carga a cada ruta
dataset_imagenes = rutas_imagenes.map(cargar_imagen, num_parallel_calls=tf.data.AUTOTUNE)

La API tf.image ofrece numerosas funciones para transformar imágenes, incluyendo operaciones de redimensionado, recorte, rotación, ajuste de brillo y contraste, y muchas más. Estas operaciones pueden integrarse perfectamente en el pipeline de datos.

Datos de texto

El procesamiento de texto requiere transformar palabras o caracteres en representaciones numéricas que los modelos puedan entender. TensorFlow proporciona herramientas específicas para esta tarea:

# Lista de frases de ejemplo
frases = ["Hola mundo", "Aprendizaje automático", "TensorFlow es genial"]
dataset_texto = tf.data.Dataset.from_tensor_slices(frases)

# Crear un tokenizador y ajustarlo a los datos
tokenizador = tf.keras.preprocessing.text.Tokenizer()
tokenizador.fit_on_texts(frases)

# Convertir texto a secuencias de índices
def tokenizar(texto):
    secuencias = tokenizador.texts_to_sequences([texto.numpy().decode('utf-8')])
    return tf.constant(secuencias[0])

# Aplicar la tokenización a cada elemento
dataset_texto = dataset_texto.map(
    lambda texto: tf.py_function(func=tokenizar, inp=[texto], Tout=tf.int32)
)

Para manejar secuencias de diferentes longitudes, necesitamos aplicar padding para que todas tengan la misma dimensión:

def aplicar_padding(secuencia):
    return tf.pad(
        secuencia, 
        [[0, 50 - tf.shape(secuencia)[0]]], 
        "CONSTANT", 
        constant_values=0
    )[:50]  # Truncar si es más larga que 50

dataset_texto = dataset_texto.map(aplicar_padding)

Limpieza y transformación de datos

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Manejo de valores faltantes

Los valores faltantes son un problema común en conjuntos de datos reales. Para manejarlos, podemos utilizar diversas técnicas como:

def manejar_valores_faltantes(features):
    # Reemplazar NaN con un valor predeterminado
    features = {k: tf.where(tf.math.is_nan(v), tf.zeros_like(v), v) 
               for k, v in features.items()}
    
    # O imputar con la media (calculada previamente)
    medias = {"caracteristica1": 3.5, "caracteristica2": 2.7}
    features = {k: tf.where(tf.math.is_nan(v), tf.constant(medias[k], dtype=v.dtype), v) 
               for k, v in features.items()}
    
    return features

dataset = dataset.map(lambda x, y: (manejar_valores_faltantes(x), y))

Normalización y estandarización

La normalización de datos es esencial para muchos algoritmos de aprendizaje automático, ya que ayuda a que el proceso de entrenamiento sea más estable y eficiente:

def normalizar_min_max(x):
    # Normalización a [0, 1]
    min_val = tf.reduce_min(x)
    max_val = tf.reduce_max(x)
    return (x - min_val) / (max_val - min_val)

def estandarizar(x):
    # Estandarización (media 0, desviación estándar 1)
    media = tf.reduce_mean(x)
    desv_std = tf.math.reduce_std(x)
    return (x - media) / desv_std

# Aplicar normalización a cada característica
dataset = dataset.map(
    lambda x: {k: normalizar_min_max(v) for k, v in x.items()}
)

En la práctica, es recomendable calcular las estadísticas (mínimo, máximo, media, desviación estándar) sobre el conjunto de entrenamiento y aplicar las mismas transformaciones al conjunto de validación y prueba:

# Calcular estadísticas sobre el conjunto de entrenamiento
estadisticas = {}
for batch in dataset_entrenamiento:
    for key, tensor in batch.items():
        if key not in estadisticas:
            estadisticas[key] = {"min": float('inf'), "max": float('-inf'), 
                                "sum": 0, "count": 0, "sum_squared": 0}
        
        estadisticas[key]["min"] = min(estadisticas[key]["min"], tf.reduce_min(tensor))
        estadisticas[key]["max"] = max(estadisticas[key]["max"], tf.reduce_max(tensor))
        estadisticas[key]["sum"] += tf.reduce_sum(tensor)
        estadisticas[key]["count"] += tf.size(tensor)
        estadisticas[key]["sum_squared"] += tf.reduce_sum(tf.square(tensor))

# Calcular media y desviación estándar
for key in estadisticas:
    estadisticas[key]["mean"] = estadisticas[key]["sum"] / estadisticas[key]["count"]
    varianza = (estadisticas[key]["sum_squared"] / estadisticas[key]["count"]) - tf.square(estadisticas[key]["mean"])
    estadisticas[key]["std"] = tf.sqrt(varianza)

# Función de normalización usando las estadísticas calculadas
def normalizar_con_estadisticas(features):
    return {k: (v - estadisticas[k]["mean"]) / estadisticas[k]["std"] 
            for k, v in features.items()}

# Aplicar a los conjuntos de datos
dataset_entrenamiento = dataset_entrenamiento.map(normalizar_con_estadisticas)
dataset_validacion = dataset_validacion.map(normalizar_con_estadisticas)

Codificación de variables categóricas

Las variables categóricas deben transformarse en representaciones numéricas. TensorFlow ofrece diversas opciones para esta codificación:

# One-hot encoding
def one_hot_encoding(valor, num_categorias):
    return tf.one_hot(valor, depth=num_categorias)

# Ejemplo para una variable categórica con 5 posibles valores
dataset = dataset.map(
    lambda x, y: ({**x, "categoria_one_hot": one_hot_encoding(x["categoria"], 5)}, y)
)

# Embedding para categorías con alta cardinalidad
embedding_layer = tf.keras.layers.Embedding(input_dim=1000, output_dim=16)

def aplicar_embedding(x):
    categoria_embedding = embedding_layer(x["categoria"])
    return {**x, "categoria_embedding": categoria_embedding}

dataset = dataset.map(aplicar_embedding)

Partición de datos

La división adecuada del conjunto de datos en entrenamiento, validación y prueba es fundamental para evaluar correctamente el rendimiento del modelo:

def particionar_dataset(dataset, proporciones):
    """
    Particiona un dataset en múltiples subconjuntos según las proporciones dadas.
    
    Args:
        dataset: Dataset a particionar
        proporciones: Lista de proporciones para cada partición (debe sumar 1)
        
    Returns:
        Lista de datasets particionados
    """
    assert sum(proporciones) == 1.0, "Las proporciones deben sumar 1"
    
    # Obtener el tamaño total del dataset
    dataset = dataset.cache()
    tamanio = 0
    for _ in dataset:
        tamanio += 1
    
    # Crear índices aleatorios
    indices = tf.range(tamanio)
    indices = tf.random.shuffle(indices)
    
    # Calcular los puntos de corte
    puntos_corte = [0]
    for i in range(len(proporciones) - 1):
        puntos_cort

Completa TensorFlow y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración