Saltar a contenido

Modelos de Secuencia a Secuencia (Seq2Seq)

Navegación en esta sección

Capítulos anteriores: - Redes Neuronales Recurrentes (RNN) — RNN, GRU, LSTM, BRNN. - Incrustaciones de Palabras (Word Embeddings) — vectores semánticos, Word2Vec, GloVe.

Estás en Modelos de Secuencia a Secuencia (arquitectura encoder-decoder, Beam Search, BLEU y el cuello de botella del vector de contexto).

1 Introducción a los modelos Seq2Seq

Hemos visto que las RNN pueden procesar secuencias de entrada y generar secuencias de salida. Sin embargo, hay una categoría de problemas donde la longitud de la entrada y la salida no coinciden: traducción automática (una frase en español puede tener más o menos palabras que su traducción en inglés), generación de subtítulos para imágenes, o resumen de texto.

Para estos casos se utiliza la arquitectura codificador-decodificador (Encoder-Decoder), también conocida como red neuronal secuencia a secuencia (Seq2Seq).

La frase en francés “Jean visite Afrique en septembre” se traduce al inglés como “Jane is visiting Africa in September” (5 palabras de entrada → 6 palabras de salida).

  1. El Codificador: Una RNN (GRU o LSTM) lee la frase en francés palabra por palabra. Al final, genera un vector de contexto que resume toda la información de la frase.
  2. El Decodificador: Otra RNN toma el vector de contexto y genera la traducción en inglés, palabra por palabra, hasta producir el token <EOS> (fin de secuencia).

La misma arquitectura se aplica a problemas donde la entrada y la salida son de tipos diferentes:

  1. El Codificador: Una CNN pre-entrenada (como AlexNet o ResNet) procesa la imagen y extrae un vector de características (por ejemplo, de 4096 dimensiones) eliminando la capa Softmax final.
  2. El Decodificador: Una RNN toma este vector de características y genera la descripción palabra por palabra: “un gato sentado en una silla”.

2 Arquitectura del Codificador-Decodificador

2.1 El Codificador (Encoder)

El codificador es una RNN (típicamente LSTM o GRU) que procesa la secuencia de entrada palabra por palabra:

  1. Cada palabra se convierte en su vector de incrustación (embedding) mediante la matriz \(E\).
  2. Los vectores de incrustación se introducen secuencialmente en las celdas LSTM/GRU.
  3. Al final de la secuencia, el estado oculto final \(a^{<T>}\) forma el vector de contexto.

2.1.1 ¿Cómo acumula información el codificador?

El estado oculto \(a^{<t>}\) se va actualizando en cada paso. Cada \(a^{<t>}\) contiene un resumen de todas las palabras vistas hasta ese momento:

\[ a^{<1>} = \text{LSTM}(x^{<1>}, a^{<0>}) \]
\[ a^{<2>} = \text{LSTM}(x^{<2>}, a^{<1>}) \]
\[ \vdots \]
\[ a^{<T>} = \text{LSTM}(x^{<T>}, a^{<T-1>}) \]

Ejemplo con “Jean visite Afrique en septembre”:

Paso 1: "Jean"      → embedding_1 → LSTM → a⟨1⟩ (resumen de "Jean")
Paso 2: "visite"    → embedding_2 → LSTM → a⟨2⟩ (resumen de "Jean visite")
Paso 3: "Afrique"   → embedding_3 → LSTM → a⟨3⟩ (resumen de las 3 palabras)
Paso 4: "en"        → embedding_4 → LSTM → a⟨4⟩
Paso 5: "septembre" → embedding_5 → LSTM → a⟨5⟩ ← ESTE es el vector de contexto

El vector de contexto \(a^{<T>}\) no es la suma de los embeddings, sino que la LSTM va acumulando información paso a paso. Cada \(a^{<t>}\) contiene un resumen de todas las palabras \(x^{<1>}, \dots, x^{<t>}\).

2.2 El Decodificador (Decoder)

El decodificador es otra RNN que genera la secuencia de salida. Funciona de forma autoregresiva: cada palabra predicha se convierte en la entrada del siguiente paso.

2.2.1 Flujo completo paso a paso

Supongamos que el codificador procesó “Jean visite Afrique en septembre” y generó el vector de contexto \(a^{<5>}_{\text{enc}}\).

Paso 0: Inicialización - El vector de contexto del codificador se copia como estado inicial del decodificador: - \(a^{<0>}_{\text{dec}} = a^{<5>}_{\text{enc}}\) - \(C^{<0>}_{\text{dec}} = C^{<5>}_{\text{enc}}\)

Paso 1: Primera palabra - Entrada: token <SOS> (inicio de secuencia) - El decodificador calcula: \(a^{<1>}_{\text{dec}} = \text{LSTM}(\text{<SOS>}, a^{<0>}_{\text{dec}})\) - Una capa Softmax convierte \(a^{<1>}_{\text{dec}}\) en probabilidades sobre el vocabulario - Seleccionamos la palabra con mayor probabilidad: “Jane”

Paso 2: Segunda palabra - Entrada: “Jane” (la palabra que acabamos de predecir) - El decodificador calcula: \(a^{<2>}_{\text{dec}} = \text{LSTM}(\text{"Jane"}, a^{<1>}_{\text{dec}})\) - Softmax → seleccionamos: “is”

Paso 3: Tercera palabra - Entrada: “is” - \(a^{<3>}_{\text{dec}} = \text{LSTM}(\text{"is"}, a^{<2>}_{\text{dec}})\) - Softmax → seleccionamos: “visiting”

Paso 4-6: Continuamos igual - “visiting” → predice “Africa” - “Africa” → predice “in” - “in” → predice “September” - “September” → predice <EOS> (fin de secuencia) → paramos

Decodificador:

  <SOS>  →  LSTM  →  Softmax  →  "Jane"
                                     │
  "Jane" →  LSTM  →  Softmax  →  "is"
                                     │
  "is"   →  LSTM  →  Softmax  →  "visiting"
                                     │
  ...continúa hasta <EOS>...
Componente Función
Vector de contexto \(a^{<T>}_{\text{enc}}\) Se copia como estado inicial \(a^{<0>}_{\text{dec}}\) del decodificador
Token <SOS> Primera entrada del decodificador (indica “empieza a generar”)
Capa Softmax Convierte cada estado oculto en probabilidades sobre el vocabulario
Autoregresivo La palabra predicha se usa como entrada del siguiente paso
Token <EOS> Indica “para de generar” (fin de secuencia)

2.3 Entrenamiento del modelo

Durante el entrenamiento, el codificador y el decodificador se entrenan conjuntamente:

  1. Predicción palabra a palabra: En cada paso \(t\), el decodificador produce una distribución Softmax sobre el vocabulario.
  2. Función de pérdida: Se utiliza la entropía cruzada (Cross-Entropy) para comparar la distribución predicha con la palabra real.
  3. Pérdida total: La suma de las pérdidas de todos los pasos de tiempo.
  4. Retropropagación: El gradiente se propaga hacia atrás a través de ambas secciones (codificador y decodificador).

2.3.1 Enmascaramiento (Masking) para secuencias de distinta longitud

Cuando las secuencias de entrenamiento tienen longitudes diferentes, se rellenan con tokens de padding. El enmascaramiento asegura que: - La pérdida para los tokens de padding se ignora. - Si el modelo se detiene antes de generar todas las palabras reales, se penaliza por detenerse temprano.

En traducción automática no queremos una traducción aleatoria (como haría un modelo de lenguaje con muestreo). Queremos encontrar la traducción más probable que maximice \(P(Y | X)\).

La búsqueda voraz elige la palabra más probable en cada paso. Pero una elección localmente óptima no siempre conduce al mejor resultado global. Por ejemplo, “Jane is going to…” puede tener mayor probabilidad inicial que “Jane is visiting…”, pero la frase completa resultante puede ser peor.

La Búsqueda de Haz mantiene un registro de las \(b\) secuencias parciales más prometedoras en cada paso (donde \(b\) es el ancho del haz, típicamente \(b = 3\) a \(b = 10\) en producción).

3.2.1 Paso 1: Primera palabra

El decodificador calcula la probabilidad de cada palabra del vocabulario como primera palabra de la traducción. Se seleccionan las \(b\) palabras con mayor probabilidad.

Por ejemplo, con \(b = 3\): - “Jane” (\(P = 0.45\)) - “In” (\(P = 0.15\)) - “September” (\(P = 0.10\))

3.2.2 Paso 2: Segunda palabra

Para cada una de las \(b\) candidatas, el modelo considera todas las palabras posibles como segunda palabra. Se calcula la probabilidad acumulada de cada secuencia de 2 palabras:

\[ P(y^{<1>}, y^{<2>} | X) = P(y^{<1>} | X) \cdot P(y^{<2>} | y^{<1>}, X) \]

De las \(b \times |V|\) combinaciones posibles, se seleccionan las \(b\) con mayor probabilidad acumulada.

3.2.3 Pasos sucesivos

El proceso se repite: en cada paso se expanden las \(b\) secuencias candidatas y se podan a las \(b\) mejores. El algoritmo termina cuando se genera <EOS> o se alcanza una longitud máxima.

3.3.1 Uso de logaritmos

Multiplicar muchas probabilidades pequeñas produce inestabilidad numérica. En su lugar, se suman logaritmos:

\[ \log P(Y | X) = \sum_{t=1}^{T_y} \log P(y^{<t>} | y^{<1>}, \dots, y^{<t-1>}, X) \]

3.3.2 Normalización por longitud

La suma de logaritmos penaliza las secuencias largas (más términos negativos). Se normaliza dividiendo por la longitud:

\[ \text{Score}(Y) = \frac{1}{T_y^\alpha} \sum_{t=1}^{T_y} \log P(y^{<t>} | \cdot) \]

donde \(\alpha \approx 0.7\) es un hiperparámetro que controla la agresividad de la normalización.

3.3.3 Elección del ancho del haz \(b\)

  • \(b = 1\): Equivale a búsqueda voraz (rápida pero subóptima).
  • \(b = 10\): Punto de partida común en producción.
  • \(b = 1000\text{--}3000\): Usado en investigación, pero lento y con alto consumo de memoria.

4 Análisis de errores: ¿Beam Search o Modelo?

Cuando la traducción es incorrecta, es crucial diagnosticar si el fallo es del algoritmo de búsqueda o del modelo RNN subyacente.

Dados: - \(Y^*\): Traducción correcta (humana). - \(\hat{Y}\): Traducción incorrecta (generada por el modelo).

Se comparan dos probabilidades:

Condición Culpable Solución
$P(Y^* X) > P(\hat{Y} X)$
$P(Y^* X) \le P(\hat{Y} X)$

5 Evaluación: Puntuación BLEU

La traducción automática tiene múltiples traducciones válidas para una misma frase. El BLEU score (Bilingual Evaluation Understudy) evalúa automáticamente la calidad de una traducción comparándola con una o más referencias humanas.

5.1 Componentes del BLEU

  1. Precisión modificada (Modified Precision): Cuenta cada palabra de la traducción de la máquina hasta el número máximo de veces que aparece en alguna referencia. Esto evita que “the the the” obtenga puntuación alta.

  2. Precisión de N-gramas: Mide la precisión de secuencias de \(n\) palabras consecutivas (unigramas, bigramas, trigramas, 4-gramas) para capturar tanto la elección de palabras como el orden.

  3. Penalización por brevedad (Brevity Penalty): Penaliza traducciones más cortas que las referencias, evitando que el modelo obtenga alta precisión generando frases muy cortas.

5.2 Importancia histórica

El BLEU score proporcionó por primera vez una métrica objetiva, numérica y reproducible para evaluar traducción automática sin necesidad de evaluadores humanos, acelerando enormemente la investigación en el campo.

6 El cuello de botella del vector de contexto

El principal problema de la arquitectura codificador-decodificador básica es que toda la información de la secuencia de entrada debe comprimirse en un único vector de contexto de longitud fija.

  • Para frases cortas (5-10 palabras), el vector de contexto captura adecuadamente el significado.
  • Para frases largas (más de 30-40 palabras), la información del inicio de la frase se diluye. El vector de contexto se convierte en un resumen de las últimas palabras, perdiendo el contexto de las primeras.

Este problema se conoce como el cuello de botella del vector de contexto y se manifiesta como una degradación de la puntuación BLEU a medida que aumenta la longitud de las frases.

La solución: El mecanismo de atención, que permite al decodificador “mirar” directamente a todos los estados ocultos del codificador en cada paso de tiempo, asignando pesos de atención a los estados más relevantes para la palabra que se está generando.