El gradiente que se desvanece

El gradiente que se desvanece

28 min de lectura

La lección anterior, sobre backpropagation through time (BPTT), cerró con un gradiente exacto y un cabo suelto. Exacto porque el sondeo numérico lo confirmó casilla por casilla; suelto porque la forma de calcularlo repite un mismo gesto sin que nadie mirara sus consecuencias: para arrastrar el error de una posición a la de más atrás hay que multiplicarlo por la matriz recurrente Whh\mathbf{W}_{hh}, y en una secuencia de cuarenta tokens ese producto se repite casi cuarenta veces. Esta lección mide qué le hace al gradiente repetir la misma multiplicación tantas veces seguidas, y encuentra el número de Whh\mathbf{W}_{hh} que le pone techo al resultado.

Y no es una curiosidad numérica: en juego está la única razón para preferir una RNN a la red del principio del bloque. Toma una reseña que arranca con Dudo que a alguien le sirva y, treinta palabras más tarde, cierra con su valoración. Ese Dudo inicial invierte el signo de todo lo que viene después, pero la red solo puede aprender esa conexión si el gradiente calculado en la última palabra consigue volver hasta la primera. Si por el camino se apaga, la red jamás registrará que el principio importaba, y la memoria que la definía se quedará, en la práctica, en memoria de lo reciente.

Antes de mirar la matriz entera, quítale coordenadas hasta que quede una sola. Con dh=1d_h = 1 el estado es un número, Whh\mathbf{W}_{hh} es un número ww, y arrastrar el error un paso hacia atrás es multiplicarlo por ww. Repetir el paso dd veces lo multiplica por wdw^{d}.

Y wdw^{d} no tiene término medio. Si ∣w∣<1\lvert w \rvert < 1 se hunde: con w=0.5w = 0.5, cuarenta pasos dejan el error en 0.540≈9×10−130.5^{40} \approx 9 \times 10^{-13}, doce órdenes de magnitud por debajo de donde salió. Si ∣w∣>1\lvert w \rvert > 1 se dispara: 1.540≈1.1×1071.5^{40} \approx 1.1 \times 10^{7}. Solo ∣w∣=1\lvert w \rvert = 1 mantiene el error en su tamaño, y es un filo de un solo punto: basta desviarse un pelo para caer a un lado o al otro. Con más de una coordenada, ww pasa a ser una matriz y su papel se reparte entre dos números que la formalización separa enseguida: uno le pone techo al gradiente paso a paso, máscara incluida; el otro marca el ritmo de la matriz multiplicada por sí misma, a la larga. El explorable enseña el segundo, el radio espectral, en una recurrencia sin máscara (todas las pendientes de la tanh⁡\tanh en 11). Deslízalo a un lado y a otro de 11 y verás las dos mitades del fenómeno: por debajo, la curva se desploma; por encima, se va por arriba.

El gradiente de una recurrencia sin máscara, en órdenes de magnitud, según cuántos pasos tenga que retroceder. Por debajo de un radio espectral de 1 se desvanece; por encima, explota; y cuanto más larga es la secuencia, más extremo el resultado: la recta se inclina, nunca se dobla.

El producto que conecta dos posiciones

Volvamos a la recurrencia hacia atrás de la lección anterior y sigámosla más de un paso. Allí, el error de un paso salía del siguiente con dos gestos (transportar y enmascarar):

δt=(Whh⊤δt+1)⊙(1−ht⊙ht).\boldsymbol{\delta}_t = \left(\mathbf{W}_{hh}^{\top}\boldsymbol{\delta}_{t+1}\right) \odot \left(\mathbf{1} - \mathbf{h}_t \odot \mathbf{h}_t\right).

El ⊙\odot con la pendiente de la tanh⁡\tanh es multiplicar por una matriz diagonal (diag ⁣(1−ht⊙ht)\text{diag}\!\left(\mathbf{1} - \mathbf{h}_t \odot \mathbf{h}_t\right), con esas pendientes en la diagonal y ceros fuera), así que un paso de la vuelta multiplica δt+1\boldsymbol{\delta}_{t+1} por dos matrices: primero Whh⊤\mathbf{W}_{hh}^{\top}, luego esa diagonal. Encadena la recurrencia desde el último paso hasta uno lejano kk y las dos se repiten, una pareja por posición:

δk=(∏t=kT−1diag ⁣(1−ht⊙ht)Whh⊤)δT∈Rdh.\boldsymbol{\delta}_k = \left(\prod_{t=k}^{T-1} \text{diag}\!\left(\mathbf{1} - \mathbf{h}_t \odot \mathbf{h}_t\right)\mathbf{W}_{hh}^{\top}\right)\boldsymbol{\delta}_T \in \mathbb{R}^{d_h}.

El producto tiene T−kT - k parejas, una por cada paso entre kk y TT (la distancia que el error recorre). Y dentro de cada pareja, la misma Whh⊤\mathbf{W}_{hh}^{\top} que en todas las demás: esto no es una capa distinta por posición, como lo eran los bloques Wt(1)\mathbf{W}^{(1)}_t de la primera capa concatenada de la lección sobre por qué el MLP falla con secuencias, sino una sola matriz elevada, en la práctica, a la potencia de la distancia. Ese es el gesto que la lección anterior repetía sin mirarlo.

Por qué decae o explota

Un producto de matrices es difícil de mirar; su tamaño, no. Toma normas a los dos lados y usa que la norma de un producto no supera el producto de las normas:

∥δk∥≤∥δT∥∏t=kT−1∥diag ⁣(1−ht⊙ht)∥∥Whh⊤∥.\lVert \boldsymbol{\delta}_k \rVert \le \lVert \boldsymbol{\delta}_T \rVert \prod_{t=k}^{T-1} \left\lVert \text{diag}\!\left(\mathbf{1} - \mathbf{h}_t \odot \mathbf{h}_t\right)\right\rVert \left\lVert \mathbf{W}_{hh}^{\top}\right\rVert.

Ese ∥⋅∥\lVert \cdot \rVert ya no mide un vector: mide una matriz. Para una matriz A\mathbf{A} cualquiera se define como

∥A∥=max⁡v≠0∥Av∥∥v∥,\lVert \mathbf{A} \rVert = \max_{\mathbf{v} \neq \mathbf{0}} \frac{\lVert \mathbf{A}\mathbf{v} \rVert}{\lVert \mathbf{v} \rVert},

el mayor factor por el que A\mathbf{A} puede estirar la longitud de un vector, tomando el peor caso sobre todas las direcciones posibles. Esa definición es la que deja ∥Av∥≤∥A∥∥v∥\lVert \mathbf{A}\mathbf{v} \rVert \le \lVert \mathbf{A} \rVert \lVert \mathbf{v} \rVert cierta para cualquier v\mathbf{v} (multiplica la definición por ∥v∥\lVert \mathbf{v} \rVert) y, aplicada dos veces seguidas, la que da ∥AB∥≤∥A∥∥B∥\lVert \mathbf{A}\mathbf{B} \rVert \le \lVert \mathbf{A} \rVert \lVert \mathbf{B} \rVert: B\mathbf{B} estira como mucho ∥B∥\lVert \mathbf{B} \rVert, y A\mathbf{A} después estira ese resultado como mucho ∥A∥\lVert \mathbf{A} \rVert más.

Los dos factores de cada pareja tienen un techo. Para una matriz diagonal ese máximo es directo: diag(d)\text{diag}(\mathbf{d}) estira cada coordenada por su propia entrada, así que el peor caso es alinear v\mathbf{v} con la mayor en valor absoluto, y ∥diag(d)∥=max⁡i∣di∣\lVert \text{diag}(\mathbf{d}) \rVert = \max_i \lvert d_i \rvert. Aquí cada entrada de la diagonal es una pendiente de la tanh⁡\tanh (una por coordenada de ht\mathbf{h}_t): nunca pasa de 11, y en cuanto esa coordenada se satura se acerca a 00. Son las bandas rojas que el explorador de activaciones de la lección sobre funciones de activación ya te dejó ver. La mayor de todas esas pendientes, en todos los pasos de kk a T−1T - 1, es por tanto también ≤1\le 1; llámala γ\gamma. El de Whh⊤\mathbf{W}_{hh}^{\top} es la misma definición sin la comodidad de la diagonal: el único hecho nuevo que necesitas aquí es que una matriz estira la longitud de un vector como mucho por su mayor valor singular σmax⁡\sigma_{\max}, así que multiplicar por ella dd veces la estira, a lo sumo, por σmax⁡d\sigma_{\max}^{d}. Junta las dos cotas sobre las T−kT - k parejas:

∥δk∥≤(γ σmax⁡)T−k∥δT∥.\lVert \boldsymbol{\delta}_k \rVert \le \left(\gamma\,\sigma_{\max}\right)^{T-k}\lVert \boldsymbol{\delta}_T \rVert.

Ahí está el exponente, y con él la única condición que se sostiene pase lo que pase por el camino. El error que llega a la posición kk es, como mucho, el del final multiplicado por γ σmax⁡\gamma\,\sigma_{\max} elevado a la distancia. Si γ σmax⁡<1\gamma\,\sigma_{\max} < 1, el gradiente se desvanece sin remedio: el techo cae en picado con la distancia y el gradiente no puede pasar por encima de él, valgan lo que valgan las máscaras. Como γ≤1\gamma \le 1, σmax⁡<1\sigma_{\max} < 1 ya lo garantiza por sí solo, y la saturación solo añade margen. Lo contrario no se cumple. Si γ σmax⁡>1\gamma\,\sigma_{\max} > 1, el techo deja de sujetar el gradiente y este puede explotar, pero nada lo obliga: esa desigualdad es necesaria para la explosión, no suficiente.

La cota, además, suele sobrar: un vector concreto rara vez se estira el máximo en cada paso. Lo que Whh\mathbf{W}_{hh} hace de verdad al multiplicarse por sí misma, a la larga, lo mide otro número, su radio espectral ρ(Whh)\rho(\mathbf{W}_{hh}) (el mayor de los módulos de sus valores propios), que nunca pasa de σmax⁡\sigma_{\max}. En una recurrencia sin máscara, con todas las pendientes en 11, el producto es una potencia de Whh⊤\mathbf{W}_{hh}^{\top}, y ahí ρ\rho sí decide: por debajo de 11 el gradiente se hunde, por encima se dispara, y entre las dos cosas no hay más que ese filo. Es el número que el explorable te dejó mover.

Con las máscaras de por medio, ρ\rho deja de ser una garantía: el producto alterna Whh⊤\mathbf{W}_{hh}^{\top} con diagonales y ya no es la potencia de una sola matriz. Lo que se sostiene entonces es γ σmax⁡<1\gamma\,\sigma_{\max} < 1, y por eso es esa la condición de verdad. No necesitas calcular valores propios en esta lección; lo que sí hace falta es saber que ρ\rho existe, que marca el ritmo de la matriz sola y que nunca supera a σmax⁡\sigma_{\max}.

Ver por qué el radio espectral deja de decidir cuando entran las máscaras

En una recurrencia sin máscara el producto es (Whh⊤)d\left(\mathbf{W}_{hh}^{\top}\right)^{d}, y lo que se cumple a la larga es que ∥(Whh⊤)d∥1/d\left\lVert \left(\mathbf{W}_{hh}^{\top}\right)^{d}\right\rVert^{1/d} tiende al radio espectral ρ(Whh)\rho(\mathbf{W}_{hh}) cuando dd crece. Por eso ahí ρ<1\rho < 1 garantiza el desvanecimiento y ρ>1\rho > 1 hace crecer sin freno la norma de la potencia, aunque para una distancia corta la cota con σmax⁡\sigma_{\max} vaya por delante del ritmo real.

Con la tanh⁡\tanh, lo que se repite ya no es Whh⊤\mathbf{W}_{hh}^{\top} sino cada pareja, y una máscara puede apagar justo la coordenada que frenaba el crecimiento. Toma Whh⊤=(22−2−2)\mathbf{W}_{hh}^{\top} = \begin{pmatrix} 2 & 2 \\ -2 & -2 \end{pmatrix}. Su cuadrado es la matriz nula, así que ρ=0\rho = 0 y su potencia muere en dos pasos. Pero si la máscara vale diag(1, 0.1)\text{diag}(1,\ 0.1) en cada paso, cada pareja es (22−0.2−0.2)\begin{pmatrix} 2 & 2 \\ -0.2 & -0.2 \end{pmatrix}, cuyo radio espectral es 1.81.8, y el producto crece como 1.8d1.8^{d}. La condición real no se contradice: aquí γ=1\gamma = 1 y σmax⁡=4\sigma_{\max} = 4, y un γ σmax⁡=4\gamma\,\sigma_{\max} = 4 nunca prometió que el gradiente se hundiera.

Compruébalo con una matriz de verdad, sin reducirla a una sola coordenada: numpy.linalg trae svd para σmax⁡\sigma_{\max} y eig para los valores propios que dan ρ\rho.

import numpy as np

W = np.array([[0.5, 4.0],
[0.0, 0.5]])

sigma_max = np.linalg.svd(W, compute_uv=False)[0] # mayor valor singular
rho = np.max(np.abs(np.linalg.eig(W)[0])) # radio espectral

print("sigma_max = %.4f" % sigma_max)
print("rho = %.4f" % rho)
print()
print(" d ||W^d|| ||W^d||**(1/d)")
for d in [1, 5, 10, 20, 40]:
Wd = np.linalg.matrix_power(W, d)
norm_d = np.linalg.svd(Wd, compute_uv=False)[0]
print("%2d %9.2e %14.4f" % (d, norm_d, norm_d ** (1 / d)))
numpy

La primera ejecución descarga el intérprete de Python (~15 MB). Después queda en la caché del navegador y se reutiliza en todas las lecciones.

Para esta W\mathbf{W}, σmax⁡≈4.06\sigma_{\max} \approx 4.06 pero ρ=0.5\rho = 0.5: la cota con el valor singular sobrevalora el ritmo de la potencia por un factor de ocho. La tabla lo confirma. En d=1d = 1 la norma cruda ya vale σmax⁡\sigma_{\max} (coincide por construcción), y en d=5d = 5 sigue por encima de 11 (la potencia puede crecer durante varios pasos aunque ρ<1\rho < 1 garantice que, a la larga, se hunda). Para d=40d = 40 la norma cruda ya es minúscula y ∥Wd∥1/d\lVert \mathbf{W}^{d} \rVert^{1/d} baja de 0.580.58, cada vez más cerca de ρ=0.5\rho = 0.5: confirmando con números lo que el razonamiento de arriba solo afirmaba. Y los dos números responden a preguntas distintas: la potencia sola se hunde, pero con σmax⁡≈4.06\sigma_{\max} \approx 4.06 esta W\mathbf{W} no garantiza nada en cuanto entran las máscaras.

Verlo y recortarlo en NumPy

La primera celda reduce todo al caso de una coordenada y mira el exponente crudo; la segunda ataca la mitad del problema que sí tiene un parche barato.

El caso escalar no es un juguete: es la fórmula de arriba con dh=1d_h = 1, donde σmax⁡\sigma_{\max}, ρ\rho y ∣w∣\lvert w \rvert son el mismo número. Ejecútala y lee la fila del medio (w=1w = 1) contra las otras dos.

# W_hh de una sola coordenada es un numero w. Arrastrar el error d pasos hacia
# atras lo multiplica por w**d. La mascara del tanh (pendiente <= 1) solo lo
# encoge mas, asi que w = 1 ya es el caso mas favorable.
print(" w d=10 d=20 d=40")
for w in [0.5, 1.0, 1.5]:
print("%.1f %9.2e %9.2e %9.2e" % (w, w ** 10, w ** 20, w ** 40))

La primera ejecución descarga el intérprete de Python (~15 MB). Después queda en la caché del navegador y se reutiliza en todas las lecciones.

La primera fila se hunde, la última se dispara y la del medio no se mueve, tal como decía la intuición. Con w=0.5w = 0.5 el error llega a los cuarenta pasos convertido en 9×10−139 \times 10^{-13} de lo que era, y ningún descenso de gradiente aprende de una señal tan pequeña. Y esto es el mejor caso: la máscara del tanh⁡\tanh, en cuanto el estado se satura, lo empuja todavía más abajo.

La explosión, en cambio, tiene una respuesta directa. Si el problema es que la norma del gradiente crece sin freno, ponle un techo: fija un umbral κ\kappa y, cuando ∥g∥\lVert \mathbf{g} \rVert lo pase, reescala el gradiente para devolverlo justo a ese tamaño. Es el recorte del gradiente (gradient clipping):

g←g⋅min⁡ ⁣(1, κ∥g∥).\mathbf{g} \leftarrow \mathbf{g}\cdot\min\!\left(1,\ \frac{\kappa}{\lVert \mathbf{g} \rVert}\right).

El min⁡\min con 11 es la clave: si el gradiente ya es pequeño, el factor vale 11 y no lo toca; solo actúa sobre el que se ha pasado, y lo hace multiplicándolo por un número positivo, que cambia su longitud pero no su dirección. Compruébalo.

import numpy as np

rng = np.random.default_rng(1)
kappa = 5.0 # el techo que le ponemos a la norma


def recorta(g):
n = np.linalg.norm(g)
return g * min(1.0, kappa / n), n # factor <= 1: encoge o deja igual, no gira


for nombre, g in [("normal ", rng.normal(size=100) * 0.3),
("explotado", rng.normal(size=100) * 3.0)]:
g_rec, n = recorta(g)
coseno = float(g @ g_rec) / (n * np.linalg.norm(g_rec))
print("%s ||g|| = %6.2f -> ||recortado|| = %.2f (coseno con g: %.4f)"
% (nombre, n, np.linalg.norm(g_rec), coseno))
numpy

La primera ejecución descarga el intérprete de Python (~15 MB). Después queda en la caché del navegador y se reutiliza en todas las lecciones.

El gradiente normal pasa intacto; el explotado, con norma casi 3030, sale recortado a 5.005.00 exacto, y el coseno con el original es 11 (misma dirección, otro tamaño). El recorte salva el entrenamiento cuando el gradiente explota y no cuesta casi nada. Lo que no hace (y conviene decirlo en voz alta) es nada por el desvanecimiento: un gradiente que ya llegó valiendo 10−1310^{-13} tiene norma minúscula, el min⁡\min vale 11, y se queda como estaba.

Comprueba tu intuición

Cuatro preguntas: qué desvanece o explota el gradiente, qué arregla el recorte y qué no, si la máscara de la tanh⁡\tanh puede salvar la situación y qué se pierde cuando no.

¿Qué hace que el gradiente de una RNN se desvanezca o explote al retroceder por una secuencia larga?

El recorte del gradiente reescala g←g⋅min⁡ ⁣(1, κ/∥g∥)\mathbf{g} \leftarrow \mathbf{g}\cdot\min\!\left(1,\ \kappa/\lVert\mathbf{g}\rVert\right) cuando su norma pasa de un umbral κ\kappa. ¿Qué problema resuelve y cuál no?

La máscara 1−ht⊙ht\mathbf{1} - \mathbf{h}_t \odot \mathbf{h}_t que aparece en cada paso de la vuelta es la pendiente de la tanh⁡\tanh. Si el mayor valor singular de Whh\mathbf{W}_{hh} cumple σmax⁡<1\sigma_{\max} < 1, el gradiente se desvanece. ¿Puede la máscara rescatarlo?

¿Qué pierde una RNN cuando el gradiente que conecta el final de la secuencia con el principio se ha desvanecido?


El recorte le pone un techo a la explosión, pero deja el otro lado del problema donde estaba. Un gradiente que se ha multiplicado camino a cero no se recupera multiplicándolo por 11, y ninguna elección de Whh\mathbf{W}_{hh} arregla las dos cosas a la vez: bajar σmax⁡\sigma_{\max} por debajo de 11 para que no pueda explotar es justo lo que garantiza que se desvanezca. El problema no está en los pesos, sino en el camino: cualquier ruta que multiplique por la misma matriz en cada paso acaba en uno de los dos extremos.

La salida es cambiar el camino. Hace falta una vía por la que el estado avance de un paso al siguiente sumando, en lugar de volver a pasar por Whh\mathbf{W}_{hh}: sobre una suma el gradiente fluye sin multiplicarse una vez por posición, y así ni se hunde ni se dispara. Esa vía aditiva es el estado de celda de la LSTM (long short-term memory), y construirla (una compuerta cada vez, cada una arreglando un fallo concreto de la RNN vanilla) es la siguiente lección, sobre la LSTM: memoria con compuertas.

¿Te ha sido útil?
Para profundizar2 fuentes · 1 paper, 1 libro

De dónde sale lo de esta lección, y dónde seguir si quieres más. Nada de aquí hace falta para continuar el curso.

  • On the difficulty of training Recurrent Neural Networks
    paperPascanu, Mikolov y Bengio, 2013arXiv:1211.5063EN

    De aquí salen las dos piezas de la lección: la cota con la pendiente γ que garantiza el desvanecimiento (el radio espectral solo decide en el caso lineal) y el recorte de la norma del gradiente a un umbral. No toca las compuertas.

  • Gradient Flow in Recurrent Nets: the Difficulty of Learning Long-Term Dependencies
    libroHochreiter, Bengio, Frasconi y Schmidhuber, 2001A Field Guide to Dynamical Recurrent NetworksEN

    Su §2 demuestra lo que aquí ves en una gráfica: el error que retrocede por la secuencia decae o crece de forma exponencial en el número de pasos. Reúne las pruebas de 1991 y 1994; su §4 solo repasa arreglos, la LSTM entre ellos.