English · Español
03 — Gradientes desvanecientes y explosivos a lo largo del tiempo¶
🇪🇸 Si en una RNN el gradiente se desvanece, no es magia: es álgebra. Al hacer BPTT multiplicas \(t\) veces la misma matriz Jacobiana, y los autovalores de esa matriz controlan si el resultado se hace cero o infinito. LSTM/GRU "arreglan" esto poniendo un camino aditivo donde la multiplicación repetida no ocurre.
Este archivo deriva, sin trapicheos, por qué las RNN vanilla no pueden aprender dependencias de largo alcance, y por qué el camino aditivo de LSTM/GRU es el arreglo estructural.
El planteamiento¶
Tenemos una RNN vanilla entrenada por descenso de gradiente sobre una pérdida de secuencia:
donde \(L_t\) es la pérdida por token (entropía cruzada entre la distribución predicha \(\hat y_t\) y el siguiente token verdadero \(y_t\)).
Dinámica forward:
Para entrenar, necesitamos \(\frac{\partial L}{\partial \theta}\) para cada parámetro \(\theta \in \{W_{hh}, W_{xh}, W_{ho}, b_h, b_o\}\). El gradiente respecto a \(W_{hh}\) es el interesante — determina si el modelo puede aprender dependencias de largo alcance.
BPTT: la regla de la cadena desenrollada¶
El gradiente de la pérdida total respecto a un estado oculto \(h_t\) fluye desde cada paso posterior que dependa de \(h_t\). Concretamente:
Cada sumando se descompone vía la regla de la cadena por cada estado oculto intermedio:
Ese producto sobre \(j\) es el bit crucial. Tenemos:
Así que:
(Dado que \(\frac{d}{dz} \tanh(z) = 1 - \tanh^2(z)\), y aplicamos elementwise.)
Ahora el producto pasa a ser:
Este es el producto de \((k - t)\) matrices, cada una conteniendo una aplicación de \(W_{hh}\). El producto \(W_{hh}^{k-t}\) (modulado por los términos diagonales de la derivada de \(\tanh\)) es el Jacobiano desenrollado en el tiempo.
Por qué este producto se desvanece o explota¶
Hecho de álgebra lineal: cuando multiplicas un vector por \(W_{hh}\) muchas veces, el resultado está dominado por el autovalor de mayor magnitud de \(W_{hh}\). Formalmente, si \(\lambda_\text{max}\) es el radio espectral de \(W_{hh}\), entonces \(\|W_{hh}^k v\| \sim |\lambda_\text{max}|^k \|v\|\) para \(v\) genérico y \(k\) grande.
Tres casos:
- \(|\lambda_\text{max}| < 1\): el producto \(W_{hh}^k\) se contrae geométricamente hacia cero. Tras \(k = 20\) aplicaciones con \(|\lambda_\text{max}| = 0{,}7\), la norma es \(0{,}7^{20} \approx 8 \times 10^{-4}\). El gradiente del token 20 hacia el token 0 es esencialmente cero. El modelo no puede aprender dependencias de largo alcance — las actualizaciones del gradiente sobre los pesos relevantes son despreciables.
- \(|\lambda_\text{max}| > 1\): el producto crece geométricamente. Tras 20 pasos con \(|\lambda_\text{max}| = 1{,}5\), la norma es \(1{,}5^{20} \approx 3300\). El gradiente explota; el entrenamiento es inestable; los pesos divergen a NaN salvo que se recorten explícitamente.
- \(|\lambda_\text{max}| = 1\): caso marginal. Estable en el régimen lineal; la no-linealidad tanh aún causa problemas porque \(1 - \tanh^2(z) \leq 1\), y cuando \(|z|\) es grande (tanh saturado), la derivada colapsa a ~0, lo que contrae el gradiente igualmente.
La elección "bien condicionada" \(|\lambda_\text{max}| = 1\) existe en inicialización: la inicialización ortogonal de \(W_{hh}\) da \(|\lambda_\text{max}| = 1\). Pero el entrenamiento aleja los pesos de esta inicialización. No hay punto estable.
La contribución de la saturación de tanh¶
Incluso si \(W_{hh}\) tiene \(|\lambda_\text{max}| = 1\), el factor diagonal \(\text{diag}(1 - \tanh^2(z_j))\) contrae el gradiente siempre que \(|z_j|\) sea grande.
- \(\tanh(0) = 0\), así que la derivada en cero es \(1\).
- \(\tanh(\pm 3) \approx \pm 0{,}995\), así que la derivada ahí es \(1 - 0{,}99 = 0{,}01\).
Si la pre-activación \(z_j\) alguna vez empuja a alguna unidad oculta al régimen saturado, el gradiente de esa unidad se vuelve casi-cero para ese paso temporal (time step). Una vez que el gradiente ha sido matado en algún paso del producto, no puede recuperarse. La saturación de tanh es una trampa unidireccional.
Por eso a veces se usa ReLU (que tiene derivada \(1\) para \(z > 0\)) en RNNs — su derivada no satura en un lado. Pero ReLU tiene sus propias patologías (unidades muertas, sin contracción cuando \(|\lambda_\text{max}| > 1\)), y tanh sigue siendo el default en las formulaciones estándar de RNN.
Lo que esto significa para nuestro corpus de gramática de verbos¶
Nuestras secuencias son cortas (6–12 tokens), así que los gradientes desvanecientes/explosivos no son un problema serio dentro de una sola fila. Una RNN vanilla entrenada sobre I work, you work, he ___ debería converger bien porque el gradiente solo tiene que fluir hacia atrás ~8 pasos.
Pero el laboratorio 03 de la Fase 14 demuestra el fallo sobre una versión estirada de la tarea: una secuencia artificial de longitud 50 (quizás una cadena larga de triples pronombre-verbo-separador, o una secuencia diseñada donde la respuesta depende de un token 30 pasos atrás). Sobre esa tarea estirada, el gradiente desvaneciente es visible empíricamente — la norma del gradiente en el paso 30 es órdenes de magnitud menor que en el paso 1, y el modelo no puede aprender la dependencia de largo alcance.
Este es el puente empírico a la Fase 15. Las RNN vanilla están bien para nuestro corpus (secuencias cortas). Fallan catastróficamente cuando la dependencia es larga. La promesa arquitectónica de attention es "no importa cuán atrás esté el token relevante, el gradiente fluye en un paso" — y derivaremos por qué en la Fase 15.
El parche de GRU/LSTM: el camino aditivo¶
La recurrencia GRU:
Cuando \(z_t \approx 0\), esto es \(h_t \approx h_{t-1}\). El estado en el tiempo \(t\) es esencialmente el estado en el tiempo \(t - 1\), sin multiplicación matricial entremedias.
Esto significa que el Jacobiano \(\frac{\partial h_t}{\partial h_{t-1}} \approx I\) (la matriz identidad), no \(\text{diag}(\ldots) \cdot W_{hh}\). Multiplicar por \(I\) muchas veces es solo \(I\) — sin contracción, sin expansión.
Por supuesto, \(z_t\) no es exactamente cero en todas partes — las puertas son entrenables, y la GRU sí actualiza su estado cuando debe. Pero la opción de saltarse la multiplicación está construida en la arquitectura. El modelo puede aprender, paso a paso, a dejar que los gradientes pasen limpiamente.
LSTM hace lo mismo con su estado de celda \(c_t = f_t \odot c_{t-1} + i_t \odot \tilde c_t\). Cuando \(f_t \approx 1\) e \(i_t \approx 0\), el estado de celda se preserva idénticamente. El gradiente fluye hacia atrás por el camino \(f_t \odot c_{t-1}\) sin multiplicación matricial.
Por qué esto es un parche, no un arreglo. El camino aditivo deja que los gradientes fluyan hacia atrás si las puertas eligen dejarlos. Entrenar las puertas para que lo hagan requiere que los gradientes fluyan hacia atrás también por las puertas, lo cual es recursivo. En la práctica, las LSTM/GRU se entrenan de forma más estable que las RNN vanilla pero aún luchan en secuencias mucho más largas de ~100 tokens. El problema fundamental — que un estado de dimensión fija debe codificar una historia arbitrariamente larga — permanece.
Observación empírica: lo que mostrará el laboratorio¶
El laboratorio 03 plotea la norma del gradiente \(\|\partial L_T / \partial h_t\|\) vs \(t\) para una secuencia de longitud 50, con \(L_T\) una pérdida en el paso final. Tres líneas:
- RNN vanilla. La línea cae como un acantilado, ~3 órdenes de magnitud por cada 10 pasos. Para \(t = 20\) (30 pasos desde la pérdida), el gradiente es computacionalmente indistinguible de cero.
- GRU. La línea cae pero más gradualmente, quizás 1 orden de magnitud por cada 10 pasos. El gradiente en \(t = 20\) es pequeño pero no nulo.
- LSTM (si la implementas). Similar a GRU. A veces un poco mejor, a veces un poco peor, dentro del ruido de la elección de inicialización y sesgos de puertas.
Este plot es la figura titular de la Fase 14. Compromételo; referéncialo desde PHASE_14_REPORT.md.
Recorte de gradiente (mencionado, diferido)¶
Incluso con GRU/LSTM, los gradientes pueden ocasionalmente explotar — por ejemplo, cuando un batch particularmente malo produce una pre-activación extrema que empuja a una puerta a un régimen descontrolado. La mitigación estándar es el recorte de gradiente: si \(\|\nabla L\|_2 > c\) (para algún umbral \(c\), típicamente 1.0 o 5.0), re-escala el gradiente para que tenga norma \(c\).
No entrenamos en la Fase 14, así que no necesitamos recorte aquí. Pero ten en cuenta: cualquier bucle de entrenamiento de la Fase 18 que opere sobre un modelo recurrente debe recortar. Sin recorte, el entrenamiento divergirá en el primer batch desafortunado.
Cómo leer la fórmula BPTT de un vistazo¶
Emerge un patrón. Mira la fórmula del gradiente una vez más:
Tres piezas, en producto:
- El gradiente "aguas abajo" \(\partial L_k / \partial h_k\). Lo que la pérdida piensa del estado en el paso \(k\). Fijo.
- El producto Jacobiano sobre el tiempo. Multiplicación repetida por \(W_{hh}\) (modulada por tanh). Este es el factor de desvanecimiento/explosión.
- (Implícita) la influencia "aguas arriba" sobre los gradientes de parámetros. La contribución de cada paso a \(\partial L / \partial W_{hh}\) involucra el mismo producto. La patología es global.
El patrón de "Jacobiano de actualización-de-estado aplicado muchas veces" recurre en cada arquitectura recurrente profunda. La mitigación en los modelos recurrentes modernos (Mamba, RetNet) es restringir la actualización de estado a ser un operador lineal con un espectro controlado — fundamentalmente una versión más estricta de "inicialización ortogonal que se mantiene ortogonal".
Attention, por contraste, esquiva el problema por completo. Fase 15.
Lo que esta fase NO cubre¶
- BPTT truncado. Un truco de entrenamiento donde el gradiente se computa solo sobre los últimos \(k\) pasos, ignorando la dependencia de estados anteriores. Útil en la práctica; territorio de la Fase 18.
- Backward pass de LSTM/GRU. Solo esbozo. La derivación completa serían 4–6 páginas y no es un entregable de la Fase 14.
- Esquemas de inicialización para \(W_{hh}\). Init ortogonal, init identidad, Le-init. La Fase 10 cubre la inicialización en general; la elección específica de RNN se menciona en un párrafo.
- Análisis espectral de \(W_{hh}\) entrenado. ¿Qué hacen los autovalores durante el entrenamiento? Pregunta interesante; fuera del alcance.
- Conexiones residuales recurrentes. Un workaround previo a los LSTM (Le et al. 2015). Mencionado una vez.
- Conexión con ecuaciones diferenciales. RNNs como ODEs discretizadas por Euler (Chen et al. 2018 NeuralODE). Fuera del alcance.
Un ejercicio antes del laboratorio¶
Dado \(W_{hh} = 0{,}7 I_d\) (una identidad escalada), ¿cuánto vale \(\|\partial h_{20} / \partial h_0\|\)? Asume que las derivadas de tanh son todas iguales a 1 (sin saturación; mejor caso).
Tres órdenes de magnitud abajo en 20 pasos con la mejor no-linealidad. Ahora imagina el caso realista donde las derivadas de tanh son a veces \(0{,}5\) o \(0{,}1\) — la contracción es mucho peor.
Este es el hecho empírico que motiva la totalidad de GRU, LSTM, attention, transformers, y la IA (AI) moderna.
Teoría completa. Siguiente: lab/00-tokenize-corpus.md.