Arquitecturas Clásicas
Comprensión del Mecanismo Transformer
El modelo Transformer revolucionó el procesamiento de secuencias mediante su arquitectura basada únicamente en mecanismos de atención. A diferencia de redes recurrentes, captura dependencias a largo plazo sin procesar secuencialmente los datos.
Fundamentos de Auto-Atención
El principio de atención implica asignar relevancia diferencial a distintas partes de la información. En contextos biológicos, los organismos focalizan recursos cognitivos en estímulos pertinentes. En deep learning, esto se materializa mediante tres componentes:
- Consulta (Query): Representa la información de búsqueda activa
- Clave (Key): Actúa como índice para la búsqueda
- Valor (Value): Contiene la información real a recuperar
La operación genera un resultado cuya dimensionalidad coincide con Value, ponderado por la similitud entre Query y Key. Esta arquitectura permite que el modelo determine dinámicamente qué partes de la entrada son más relevantes para cada predicción.
Descripción de BERT
Bidirectional Encoder Representations from Transformers emplea entrenamiento en dos fases: preentrenamiento masivo en texto no etiquetado y ajuste fino para tareas específicas. Utiliza embeddings de token, segmento y posición, siendo especialmente efectivo para comprensión de lenguaje natural, clasificación de texto y respuesta a preguntas.
Codificación Posicional: Necesidad y Variantes
Como el Transformer carece de recurrencia, requiere información explícita de posición. Las codificaciones absolutas (seno-coseno) añaden vectores fijos, mientras que las relativas como RoPE (Rotary Position Embedding) ofrecen ventajas superiores:
1. Percepción Mejorada de Posiciones Relativas
RoPE aplica transformaciones rotacionales a vectores de consulta y clave mediante matrices ortogonales. La atención resultante depende únicamente de la diferencia de posiciones, facilitando el aprendizaje de patrones locales y direccionales.
2. Extrapolación a Secuencias Largas
A diferencia de codificaciones fijas limitadas a longitudes de entrenamiento, RoPE generaliza naturalmente a secuencias más largas durante inferencia, manteniendo coherencia posicional.
3. Estabilidad Numérica
Al ser rotaciones, preservan la norma vectorial, evitando desviaciones numéricas que afectan la estabilidad del entrenamiento.
CNN vs Transformer: Aálisis Comparativo
Las Convolutional Neural Networks fueron diseñadas para datos grid-like, especialmente imágenes. Sus principios fundamentales son:
- Invarianza Espacial: Detección de patrones independiente de su ubicación
- Localidad: Conexiones locales limitadas al receptive field
El tamaño de salida se calcula mediante:
Altura_salida = ⌊(Altura_entrada - Altura_núcleo + 2×Relleno) / Paso⌋
Anchura_salida = ⌊(Anchura_entrada - Anchura_núcleo + 2×Relleno) / Paso⌋
Los rellenos (padding) preservan información de bordes; los pasos (stride) reducen dimensionalidad. Usualmente se usan núcleos de tamaño impar para simetría en el relleno.
Implementación Práctica de Convolución
import torch
def operacion_correlacion_bidimensional(tensor_entrada, nucleo):
"""Implementación manual de operación de correlación 2D"""
dimensiones_nucleo = nucleo.shape
altura_salida = tensor_entrada.shape[0] - dimensiones_nucleo[0] + 1
anchura_salida = tensor_entrada.shape[1] - dimensiones_nucleo[1] + 1
tensor_salida = torch.zeros((altura_salida, anchura_salida))
for indice_fila in range(altura_salida):
for indice_columna in range(anchura_salida):
ventana = tensor_entrada[indice_fila:indice_fila + dimensiones_nucleo[0],
indice_columna:indice_columna + dimensiones_nucleo[1]]
tensor_salida[indice_fila, indice_columna] = (ventana * nucleo).sum()
return tensor_salida
# Ejemplo de uso
datos_ejemplo = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
kernel_ejemplo = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
resultado = operacion_correlacion_bidimensional(datos_ejemplo, kernel_ejemplo)
Definición de Capa Convolucional Personalizada
class CapaConvolucional2D(torch.nn.Module):
def __init__(self, forma_nucleo):
super().__init__()
self.pesos = torch.nn.Parameter(torch.rand(forma_nucleo))
self.sesgo = torch.nn.Parameter(torch.zeros(1))
def forward(self, entrada):
return operacion_correlacion_bidimensional(entrada, self.pesos) + self.sesgo
Entrenamineto de Parámetros Convolucionales
import torch.nn as nn
capa_conv_predefinida = nn.Conv2d(1, 1, kernel_size=(1, 2), bias=False)
# Preparar tensores en formato (batch, canales, altura, anchura)
tensor_entrada = torch.randn(1, 1, 6, 8)
tensor_objetivo = torch.randn(1, 1, 6, 7)
tasa_aprendizaje = 0.03
for epoca in range(10):
prediccion = capa_conv_predefinida(tensor_entrada)
perdida = (prediccion - tensor_objetivo) ** 2
capa_conv_predefinida.zero_grad()
perdida.sum().backward()
with torch.no_grad():
capa_conv_predefinida.weight -= tasa_aprendizaje * capa_conv_predefinida.weight.grad
if (epoca + 1) % 2 == 0:
print(f'Iteración {epoca+1}: Pérdida = {perdida.sum():.4f}')
Capas de Normalización
BatchNorm vs LayerNorm: Distinciones Críticas
Ambas técnicas estandarizan características (media 0, varianza 1), pero difieren en el eje de cálculo:
- BatchNorm: Calcula estadísticas por característica a través del batch. Para entrada 2D, normaliza cada columna; para 3D, normaliza cada canal por batch.
- LayerNorm: Calcula estadísticas por muestra. Para cada ejemplo, normaliza todos sus valores independientemente del batch.
En tareas secuenciales (NLP), LayerNorm es preferible porque:
- Las secuencias tienen longitudes variables con relleno (padding)
- BatchNorm promedia sobre posiciones rellenadas, distorsionando estadísticas
- LayerNorm opera por secuencia, evitando este problema
Optimizadores en Deep Learning
Función Principal
Los optimizadores ajustan parámetros del modelo para minimizar la función de pérdida mediante:
- Cálculo de gradientes via retropropagación
- Actualización de pesos con estrategias específicas
- Gestión dinámica de tasa de aprendizaje
- Aceleración de convergencia mediante técnicas como momento
Algoritmos Comunes
- SGD: Descenso estocástico clásico
- Momentum: Añade inercia a las actualizaciones
- Adagrad: Tasas adaptativas por parámetro
- RMSprop: Corrige decaimiento excesivo de Adagrad
- Adam: Combina momento y adaptividad
AdaW: Optimizador con Decaimiento Adaptativo
AdaW integra decaimiento de pesos dinámico en Adam, ajustando penalizaciones según la magnitud de actualizaciones. Esto mejora generalización sin requerir sintonización manual intensiva del factor de decaimiento.
Funciones de Pérdida
Pérdida de Log-Likelihood Negativa (NLL)
Para clasificación, NLL mide la discrepancia entre distribución predicha y etiqueta real:
L = -log(p(y|x))
Se combina con softmax: primero se convierten logits a probabilidades logarítmicas, luego se calcula la pérdida respecto a la clase verdadera.
Ejemplo en PyTorch
import torch
import torch.nn as nn
import torch.nn.functional as F
# Logits del modelo (sin normalizar)
logits = torch.tensor([[2.5, 1.0, 3.2]])
# Clase objetivo
clase_real = torch.tensor([2])
# Convertir a log-probabilidades
log_probs = F.log_softmax(logits, dim=-1)
# Calcular pérdida
criterio_nll = nn.NLLLoss()
perdida = criterio_nll(log_probs, clase_real)
print(f'Valor de pérdida: {perdida.item():.4f}')
Métodos de Ajuste Fino
Técnicas Universales para Grandes Modelos
- LoRA: Adaptación de Rank Bajo - entrena matrices de proyección pequeñas
- QLoRA: Versión cuantizada de LoRA para eficiencia de memoria
- Prefix Tuning: Optimiza embeddings prefijos estacionales
Específicos para Modelos de Difusión
- ControlNet: Control de generación mediante condiciones espaciales
- Adapter Tuning: Módulos adaptativos plug-and-play
Funciones de Activación
Propósito y Necesidad
Las funciones de activación introducen no-linearidad, permitiendo a las redes aprender patrones complejos. Sin ellas, composiciones de funciones afines seguirían siendo afines, limitando la capacidad expresiva.
Variantes Principales
- ReLU: f(x) = max(0, x). Derivada constante (0 o 1), mitiga desvanecimiento de gradientes. No diferenciable en 0 (se define derivada=0).
- Sigmoid: f(x) = 1/(1+e^-x). Suave pero con gradientes que tienden a cero, causando saturación. Actualmente restringida a salidas probabilísticas.
Cuestiones Adicionales
Sobreajuste: Identificación y Mitigación
El sobreajuste ocurre cuando el error de entrenamiento es significativamente menor que el de validación. Sus causas principales son:
- Complejidad excesiva del modelo: Capacidad superior a la necesaria para el problema
- Datos insuficientes: Muestras no representativas de la distribución real
Estrategias de Regularización
- Penalización de pesos: Restricciones L1/L2 en los parámetros
- Dropout: Desactivación aleatoria de neuronas durante entrenamiento. Rompe co-adaptación entre unidades, forzando robustez. La tasa típica oscila entre 0.2 y 0.5.
Propagación: Forward y Backward
Forward Pass: Cálculo secuencial de activaciones desde entrada hasta salida, almacenando valores intermedios.
Computational Graph: Estructura que registra operaciones y dependencias para derivación automática.
Backward Pass: Aplicación de la regla de la cadena para calcular gradientes de parámetros, recorriendo la red en orden inverso. Requiere retención de activaciones intermedias, incrementando el consumo de memoria durante entrenamiento versus inferencia.