Retropropagación, la derivación matemática paso a paso
Índice de contenidos
- Puntos clave
- Preparación: notación y la regla de la cadena
- El error de la capa de salida
- Propagación del error hacia atrás
- Gradientes de pesos y sesgos
- Las cuatro ecuaciones de la retropropagación
- Preguntas frecuentes
- ¿Por qué se multiplica por la transpuesta de los pesos?
- ¿En qué se diferencia la retropropagación del descenso de gradiente?
- ¿Hace falta guardar las activaciones de la pasada hacia delante?
- Conclusión
- Fuentes
La retropropagación aplica la regla de la cadena para repartir el error de una red capa por capa. Primero se calcula el error de la última capa, luego se propaga hacia atrás y con él se obtienen los gradientes de todos los pesos y sesgos en una sola pasada, resumidos en cuatro ecuaciones.
La retropropagación no es magia, es la regla de la cadena aplicada con orden. Entrenar una red consiste en mover cada peso en la dirección que reduce el error, y para eso hace falta el gradiente de la pérdida respecto a cada parámetro. Calcularlo peso a peso sería carísimo; la retropropagación lo obtiene todo en una sola pasada hacia atrás. Esta guía deriva ese proceso paso a paso hasta llegar a las cuatro ecuaciones que lo resumen. La misma explicación está disponible en inglés.
Puntos clave
- La retropropagación calcula el gradiente de la pérdida $L$ respecto a todos los pesos y sesgos aplicando la regla de la cadena de la última capa hacia la primera.
- El punto de partida es el error de la capa de salida, $\boldsymbol{\delta}$, que combina cuánto cambia la pérdida con la activación y cuánto cambia la activación con la entrada $\mathbf{z}$.
- Ese error se propaga hacia atrás multiplicando por la transpuesta de la matriz de pesos de la capa siguiente: $\boldsymbol{\delta}^{(l)} = \left((\mathbf{W}^{(l+1)})^{\top}\boldsymbol{\delta}^{(l+1)}\right) \odot f'(\mathbf{z}^{(l)})$.
- Con $\boldsymbol{\delta}$ de cada capa, el gradiente del sesgo es el propio $\boldsymbol{\delta}$ y el de los pesos es $\boldsymbol{\delta}^{(l)}(\mathbf{a}^{(l-1)})^{\top}$.
- Todo el algoritmo cabe en cuatro ecuaciones y un solo par de pasadas: una hacia delante y otra hacia atrás, publicadas por Rumelhart, Hinton y Williams en 1986.
Preparación: notación y la regla de la cadena
Antes de derivar nada conviene fijar la notación, que es la misma del mapa de las matemáticas de las redes neuronales. Cada capa $l$ recibe las activaciones de la capa anterior, calcula una suma ponderada y les aplica una función de activación:
$$\begin{aligned} \mathbf{z}^{(l)} &= \mathbf{W}^{(l)}\mathbf{a}^{(l-1)} + \mathbf{b}^{(l)} \ \mathbf{a}^{(l)} &= f(\mathbf{z}^{(l)}) \end{aligned}$$
Aquí $\mathbf{W}^{(l)}$ es la matriz de pesos, $\mathbf{b}^{(l)}$ el vector de sesgos, $\mathbf{z}^{(l)}$ la entrada ponderada y $\mathbf{a}^{(l)}$ la activación. La entrada de la red es $\mathbf{a}^{(0)} = \mathbf{x}$ y la salida final es $\mathbf{a}^{(L)}$ en la última capa. La pérdida $L$ compara esa salida con la respuesta correcta.
La herramienta que lo conecta todo es la regla de la cadena: si la pérdida depende de $\mathbf{a}$, que depende de $\mathbf{z}$, que depende de $\mathbf{W}$, entonces la derivada de la pérdida respecto a $\mathbf{W}$ es el producto de esas derivadas encadenadas. La retropropagación es, literalmente, esa cadena recorrida de derecha a izquierda para no repetir cálculos. Como escribe Michael Nielsen en su capítulo dedicado al tema, «la retropropagación nos da una visión detallada de cómo cambiar los pesos y los sesgos modifica el comportamiento global de la red».
El error de la capa de salida
El primer eslabón es el error de la última capa, que definimos como la sensibilidad de la pérdida a la entrada ponderada $\mathbf{z}$:
$$\boldsymbol{\delta}^{(L)} = \frac{\partial L}{\partial \mathbf{a}^{(L)}} \odot f'(\mathbf{z}^{(L)})$$
El símbolo $\odot$ es el producto elemento a elemento (producto de Hadamard). La lectura es intuitiva: $\frac{\partial L}{\partial \mathbf{a}^{(L)}}$ mide cuánto empeora la pérdida si cambia la salida, y $f'(\mathbf{z}^{(L)})$ mide cuánto cambia la salida si cambia $\mathbf{z}$. Su producto dice cuánta culpa del error tiene cada neurona de salida.
Aunque a $\boldsymbol{\delta}$ lo llamamos «error», no es la pérdida en sí, sino su sensibilidad respecto a la entrada ponderada $\mathbf{z}$. Esa distinción es la que permite encadenar capas: cada $\boldsymbol{\delta}$ mide culpa local, no error total.
Un ejemplo concreto: con la pérdida cuadrática $L = \tfrac{1}{2}(\mathbf{a}^{(L)}-\mathbf{y})^2$, el primer factor es simplemente $\mathbf{a}^{(L)}-\mathbf{y}$, la diferencia entre lo predicho y lo real. Si además la activación es la sigmoide, $f'(z) = f(z)\,(1-f(z))$, que vale como mucho $0{,}25$ y explica por qué las capas profundas aprenden despacio, el llamado gradiente que se desvanece.
Propagación del error hacia atrás
Aquí está el corazón del algoritmo. Conociendo el error $\boldsymbol{\delta}^{(l+1)}$ de una capa, queremos el de la capa anterior sin recalcular nada desde cero. La regla de la cadena, aplicada a través de la suma ponderada de la capa siguiente, da:
$$\boldsymbol{\delta}^{(l)} = \left((\mathbf{W}^{(l+1)})^{\top}\boldsymbol{\delta}^{(l+1)}\right) \odot f'(\mathbf{z}^{(l)})$$
Multiplicar por la transpuesta $(\mathbf{W}^{(l+1)})^{\top}$ reparte el error de la capa $l+1$ entre las neuronas de la capa $l$ según cuánto contribuyó cada una. Después, el producto de Hadamard con $f'(\mathbf{z}^{(l)})$ lo filtra por la pendiente local de la activación. Repitiendo esta fórmula desde la última capa hasta la primera obtenemos el $\boldsymbol{\delta}$ de todas las capas: por eso el método se llama retropropagación, porque el error viaja hacia atrás.
Ver la derivación
Partimos de $\delta^{(l)}_j = \dfrac{\partial L}{\partial z^{(l)}_j}$ y encadenamos a través de todas las entradas $z^{(l+1)}_k$ de la capa siguiente, ya que $z^{(l+1)}_k = \sum_j W^{(l+1)}_{kj}\,f(z^{(l)}_j)+b^{(l+1)}_k$. La regla de la cadena da $\delta^{(l)}_j = \sum_k \dfrac{\partial L}{\partial z^{(l+1)}_k}\dfrac{\partial z^{(l+1)}_k}{\partial z^{(l)}_j} = \sum_k \delta^{(l+1)}_k\,W^{(l+1)}_{kj}\,f'(z^{(l)}_j)$. Reescribiendo la suma $\sum_k \delta^{(l+1)}_k\,W^{(l+1)}_{kj}$ como el producto matriz-vector $(\mathbf{W}^{(l+1)})^{\top}\boldsymbol{\delta}^{(l+1)}$ y sacando factor común $f'(z^{(l)}_j)$ con el producto de Hadamard se obtiene $\boldsymbol{\delta}^{(l)} = \left((\mathbf{W}^{(l+1)})^{\top}\boldsymbol{\delta}^{(l+1)}\right) \odot f'(\mathbf{z}^{(l)})$.
Esta recursión es lo que hace el algoritmo eficiente. En lugar de calcular una derivada independiente por cada uno de los, digamos, millones de pesos, reutilizamos el $\boldsymbol{\delta}$ ya calculado de la capa posterior. El coste total es equivalente a unas dos pasadas por la red, no a una por parámetro.
Gradientes de pesos y sesgos
Con el $\boldsymbol{\delta}$ de cada capa en la mano, los gradientes que de verdad buscamos salen casi solos. El del sesgo es directo, porque $\mathbf{z}$ depende de $\mathbf{b}$ con derivada 1:
$$\frac{\partial L}{\partial \mathbf{b}^{(l)}} = \boldsymbol{\delta}^{(l)}$$
Y el de los pesos combina el error de la capa con la activación que entró en ella, que es la fórmula de la portada:
$$\frac{\partial L}{\partial \mathbf{W}^{(l)}} = \boldsymbol{\delta}^{(l)}(\mathbf{a}^{(l-1)})^{\top}$$
La interpretación es limpia: un peso recibe un gradiente grande cuando su neurona de destino tiene mucho error ($\boldsymbol{\delta}$ alto) y su neurona de origen estuvo muy activa ($\mathbf{a}$ alto). Un peso entre dos neuronas apagadas apenas se mueve. Con estos gradientes, el descenso de gradiente actualiza cada parámetro restando $\eta\nabla L$, con una tasa de aprendizaje $\eta$ que suele empezar en torno a $0{,}01$.
Las cuatro ecuaciones de la retropropagación
Todo lo anterior se condensa en las cuatro ecuaciones que Michael Nielsen popularizó en el capítulo 2 de su libro:
$$\begin{aligned} \text{BP1:}\quad & \boldsymbol{\delta}^{(L)} = \frac{\partial L}{\partial \mathbf{a}^{(L)}} \odot f'(\mathbf{z}^{(L)}) \ \text{BP2:}\quad & \boldsymbol{\delta}^{(l)} = \left((\mathbf{W}^{(l+1)})^{\top}\boldsymbol{\delta}^{(l+1)}\right) \odot f'(\mathbf{z}^{(l)}) \ \text{BP3:}\quad & \frac{\partial L}{\partial \mathbf{b}^{(l)}} = \boldsymbol{\delta}^{(l)} \ \text{BP4:}\quad & \frac{\partial L}{\partial \mathbf{W}^{(l)}} = \boldsymbol{\delta}^{(l)}(\mathbf{a}^{(l-1)})^{\top} \end{aligned}$$
BP1 arranca el error en la salida, BP2 lo propaga hacia atrás, y BP3 y BP4 lo convierten en gradientes. El algoritmo completo es: una pasada hacia delante para guardar todos los $\mathbf{z}$ y $\mathbf{a}$, luego BP1, después BP2 repetida capa a capa, y por último BP3 y BP4 en cada capa. Aunque la idea del gradiente en modo inverso se remonta al trabajo de Seppo Linnainmaa en 1970, fue el artículo de 1986 el que la convirtió en el estándar del aprendizaje profundo.
Preguntas frecuentes
¿Por qué se multiplica por la transpuesta de los pesos?
Porque en la pasada hacia delante la matriz $\mathbf{W}^{(l+1)}$ transforma las activaciones de la capa $l$ en las entradas de la capa $l+1$. Al ir hacia atrás recorremos esa misma conexión en sentido inverso, y la operación que revierte esa transformación lineal es multiplicar por la transpuesta $(\mathbf{W}^{(l+1)})^{\top}$. Así el error se reparte respetando qué peso conectó con qué neurona.
¿En qué se diferencia la retropropagación del descenso de gradiente?
Son dos etapas distintas. La retropropagación solo calcula el gradiente, es decir, la dirección de máxima subida del error. El descenso de gradiente es quien usa ese gradiente para actualizar los pesos, dando un paso en la dirección contraria con tamaño $\eta$. Uno mide, el otro se mueve.
¿Hace falta guardar las activaciones de la pasada hacia delante?
Sí. Las ecuaciones BP2 y BP4 necesitan los valores de $\mathbf{z}^{(l)}$ y $\mathbf{a}^{(l-1)}$ de cada capa. Por eso el entrenamiento consume tanta memoria: hay que retener las activaciones intermedias hasta que la pasada hacia atrás las utiliza para calcular los gradientes.
Conclusión
Derivar la retropropagación deja de ser intimidante cuando se ve como lo que es: la regla de la cadena aplicada con un orden que evita recalcular. Se empieza por el error de la salida, se propaga hacia atrás con la transpuesta de los pesos y se leen los gradientes de sesgos y pesos, todo en cuatro ecuaciones. El siguiente paso natural es implementarlas sobre la propagación hacia delante y comprobar los gradientes con diferencias finitas.
Fuentes
- Neural Networks and Deep Learning, capítulo 2 (Michael Nielsen)
- Deep Learning (Goodfellow, Bengio y Courville)
- Backpropagation (Wikipedia)
- Learning representations by back-propagating errors (Nature, 1986)
Ruta: Entrenamiento: descenso de gradiente y retropropagación