Este es el módulo más importante de todo el pilar de cálculo. Backpropagation — el algoritmo con el que se entrena toda red neuronal — no es más que el chain rule multivariable aplicado con eficiencia sobre un grafo de cómputo. Cuando lo derives a mano una vez, el deep learning deja de ser una caja negra para siempre.
Why this matters for ML
Este es el módulo más importante de todo el pilar de cálculo. Backpropagation — el algoritmo con el que se entrena toda red neuronal — no es más que el chain rule multivariable aplicado con eficiencia sobre un grafo de cómputo. Cuando lo derives a mano una vez, el deep learning deja de ser una caja negra para siempre.
Concepts covered
Chain rule multivariable
Computational graphs
Forward pass y backward pass
Backpropagation derivada desde el chain rule
Reverse-mode automatic differentiation (idea)
Intuition first
🎬 3Blue1Brown Neural Networks cap. 3 ("What is backpropagation really doing?") y cap. 4 ("Backpropagation calculus"). Es, literalmente, este módulo en video. Míralo dos veces.
Theory & key results
Chain rule multivariable: si z depende de variables intermedias u1,…,uk que a su vez dependen de t:
dtdz=i=1∑k∂ui∂zdtdui.
En forma matricial es producto de Jacobians (Calc-06): para z=f(y), y=g(x),
Jz/x=Jz/yJy/x.
Computational graph: representa un cálculo como un grafo de operaciones. Ejemplo (una neurona con loss):
x⋅wa=wx+bz=a+bσy^=σ(z)lossL=(y^−y)2.
Forward pass: calcula los valores de izquierda a derecha (obtienes y^ y L).
Backward pass (backprop): calcula las derivadas de L respecto a cada parámetro, de derecha a izquierda, multiplicando derivadas locales (chain rule). Para el grafo de arriba:
∂y^∂L=2(y^−y),∂z∂y^=σ(z)(1−σ(z)),∂a∂z=1,∂w∂a=x.
Encadenando:
∂w∂L=∂y^∂L⋅∂z∂y^⋅∂a∂z⋅∂w∂a=2(y^−y)σ(z)(1−σ(z))x.
Y ∂b∂L es igual pero con ∂b∂a=1 en vez de x.
Por qué "backward": compartir subresultados. Calcular de atrás hacia adelante reutiliza ∂(nodo)∂L una sola vez por nodo → coste lineal en el tamaño del grafo. Eso es reverse-mode autodiff, lo que hacen PyTorch/TensorFlow por ti.
Backward: ∂y^∂L=2(0.622−1)=−0.756; σ′(z)=0.622⋅0.378≈0.235; entonces ∂w∂L=−0.756⋅0.235⋅1⋅x=−0.178 y ∂b∂L=−0.178 (con x=1 coinciden).
Un paso de GD (η=0.1): w←0.5−0.1(−0.178)=0.518 → la loss baja.
Notebook exercises (by hand)
Dibuja el computational graph de L=(σ(wx+b)−y)2 y marca cada derivada local.
Deriva ∂L/∂w y ∂L/∂b del ejercicio 1 con el chain rule.
Para z=f(u,v), u=x2, v=xy: calcula ∂z/∂x con la versión de suma del chain rule.
Extiende el ejemplo a dos neuronas en serie (x→h→y^) y encuentra ∂L/∂w1 (la primera capa) — verás aparecer el producto de factores.
Explica por qué backprop es más eficiente que calcular cada derivada por separado.
¿Qué le pasa al gradient si muchos factores σ′(z) (≤0.25) se multiplican en cadena? (Pista: vanishing gradients.)
Python lab
import numpy as np
def sigmoid(z): return 1/(1+np.exp(-z))
# forward + backward de una neurona, a mano
x, w, b, y = 1.0, 0.5, 0.0, 1.0
a = w*x + b; z = a; yhat = sigmoid(z); L = (yhat - y)**2
# backward
dL_dyhat = 2*(yhat - y)
dyhat_dz = yhat*(1 - yhat)
dL_dw = dL_dyhat * dyhat_dz * x
dL_db = dL_dyhat * dyhat_dz * 1
print("L:", L, " dL/dw:", dL_dw, " dL/db:", dL_db)
# verifica con gradiente numérico
def loss(w, b): return (sigmoid(w*x+b) - y)**2
h = 1e-6
num_w = (loss(w+h,b) - loss(w-h,b)) / (2*h)
print("dL/dw numérico:", num_w, " vs analítico:", dL_dw) # coinciden
Reto (adelanto del capstone): implementa backprop para una red de 2 capas con varias neuronas usando Jacobians/matrices.
Examen final 📝
Intenta cada nivel antes de abrir las soluciones.
🟡 Medio
Con z=u2, u=3x+1: calcula dz/dx con el chain rule y evalúa en x=1.
Con z=f(u,v), u=x2, v=sinx: escribe dz/dx en términos de ∂z/∂u, ∂z/∂v.
🟠 Medio-difícil
Para L=(σ(wx+b)−y)2 con x=2,w=0.5,b=0,y=0: haz forward pass y backward pass y da ∂L/∂w numérico.
Red de dos capas escalares: h=σ(w1x), y^=w2h, L=(y^−y)2. Deriva ∂L/∂w1 con el chain rule (verás factores multiplicándose capa a capa).
🔴 Difícil
Deriva las ecuaciones de backprop para una capa vectorial z=Wx+b, a=σ(z): expresa ∂W∂L, ∂b∂L y ∂x∂L en términos de δ=∂z∂L (usa matrix calculus, Calc-09).
Explica el problema de vanishing gradients: si una red profunda encadena n capas sigmoid, ¿por qué ∂L/∂(peso de la 1ª capa) tiende a 0? Estima el orden de magnitud si cada factor σ′≤0.25 y hay 10 capas, y menciona cómo ReLU mitiga esto.
δ=∂a∂L⊙σ′(z). Entonces ∂W∂L=δx⊤ (outer product), ∂b∂L=δ, ∂x∂L=W⊤δ (esto propaga el gradiente a la capa anterior).
∂L/∂w1 incluye el producto de n factores σ′(zk)≤0.25; con 10 capas, ≲0.2510≈10−6 → el gradiente casi desaparece y la 1ª capa apenas aprende. ReLU tiene derivada 1 en la región activa (no ≤0.25), así que no encoge el gradiente multiplicativamente.