Retropropagación intuitiva: cómo las redes aprenden de sus errores
En la Parte 1, Lina construyó una sola neurona que predecía si un visitante de BookSight compraría. Tomaba entradas —tiempo en la página y artículos en el carrito—, las multiplicaba por pesos, sumaba un sesgo y comprimía el resultado en una probabilidad. Pero ella misma eligió esos pesos. Una red neuronal real tiene que descubrirlos por su cuenta.
¿Cómo lo hace? Aprende cometiendo errores. El proceso se llama Retropropagación. Suena a cálculo aterrador. En realidad, es solo una forma de asignar culpas cuando las predicciones fallan.
El momento ‘Ups’: Por qué hay que trabajar hacia atrás
Imagina que eres Lina, la ingeniera de ML junior de BookSight, revisando las predicciones de compras de ayer. Tu neurona analizó el comportamiento de un visitante y predijo solo un 40% de probabilidad de que comprara; no muy segura. Pero de todos modos compró.
Para mejorar el modelo, no descartas todos los pesos y empiezas de nuevo. Trabajas hacia atrás. ¿Qué parte del cálculo fue demasiado cautelosa? Quizás weight_cart no fue lo suficientemente agresivo, o el bias redujo la puntuación en exceso. Buscas las entradas específicas que causaron el error.
El “Forward Pass” es la neurona realizando su predicción. La “Loss” es qué tan errónea resultó ser esa predicción. La retropropagación (backpropagation) consiste en recorrer hacia atrás ese cálculo para averiguar qué peso ajustar y en qué medida.
Así es como medimos ese momento de “Ups” en el código. Llamamos a esto la Función de Pérdida (Loss Function). Una común es el Error Cuadrático Medio (MSE) — en esencia, “elevar al cuadrado la distancia entre la predicción y la verdad”.
def calculate_error(prediction, actual_target):
# How far off were we?
distance = prediction - actual_target
# Square it so the error is always positive
# (and to penalize big mistakes more than small ones)
loss = distance ** 2
return loss
# Let's say the customer WAS a buyer (target=1.0), but the neuron guessed 0.4
print(f"Loss: {calculate_error(0.4, 1.0):.4f}") # Output: 0.3600
distance = prediction - actual_target— Calcula la diferencia bruta entre lo que la neurona predijo (0.4) y lo que realmente ocurrió (1.0). Una distancia negativa significa que la neurona subestimó; una positiva significa que sobreestimó.loss = distance ** 2— Elevar al cuadrado la distancia hace dos cosas: vuelve positivo cada error (para que las subestimaciones y sobreestimaciones no se cancelen) y penaliza los errores grandes de forma desproporcionada respecto a los pequeños.- La llamada de prueba pasa
0.4(la predicción de la neurona) y1.0(el resultado real — el visitante sí compró). El resultado es0.36, lo que nos indica que la neurona se equivocó de manera significativa en este ejemplo.
Una pérdida de 0.36 nos dice que estamos equivocados. Si la pérdida fuera 0.0, la predicción sería perfecta. El objetivo del aprendizaje es acercar este número lo más posible a cero.
La regla de la cadena: Es solo un juego de teléfono descompuesto
Esta es la parte más difícil de la retropropagación: ¿cómo sabemos qué peso específico causó el error? Si la predicción fue incorrecta, ¿fue weight_cart o fue el bias?
Piense en la red como un juego de teléfono descompuesto.
- El Peso afecta la Suma.
- La Suma afecta la Predicción.
- La Predicción afecta la Pérdida.
Para ver cómo el Peso afecta la Pérdida, multiplique las sensibilidades a lo largo de la cadena. Digamos que un cambio de 1 unidad en weight_cart cambia la suma en 2: este visitante tenía 2 artículos en su carrito. Un cambio de 1 unidad en la suma entonces cambia la predicción en 0.8. Por lo tanto, un cambio de 1 unidad en weight_cart cambia la predicción en .
En términos matemáticos, esta es la Regla de la Cadena: simplemente descubrir cuánto “empuje” tiene cada palanca sobre el resultado final. Llamamos a este “empuje” total el Gradiente.
# Let's simulate two connected parts: weight_cart -> Prediction
weight_cart = 0.5
items_in_cart = 2.0
# Sensitivity 1: How much does weight_cart affect the result?
# If result = weight_cart * items_in_cart, the sensitivity is just items_in_cart.
derivative_weight_to_output = items_in_cart
# Sensitivity 2: How much does the output affect the loss?
# (Simplified for this example)
derivative_output_to_loss = 0.8
# The Chain Rule: Multiply them to find the total 'blame' for the weight
gradient = derivative_weight_to_output * derivative_output_to_loss
print(f"weight_cart's gradient is: {gradient}") # Output: 1.6
derivative_weight_to_output = items_in_cart— La sensibilidad de la predicción aweight_cartes simplementeitems_in_cart(2.0), porqueprediction = weight_cart * items_in_cart. Cambiar el peso en 1 unidad cambia la predicción en 2 unidades.derivative_output_to_loss = 0.8— Un sustituto simplificado de la sensibilidad de la pérdida respecto a la predicción. En una red sigmoide completa, esta sería la derivada de la función sigmoide en el valor de predicción actual.gradient = derivative_weight_to_output * derivative_output_to_loss— La regla de la cadena en una sola línea: multiplique las dos sensibilidades locales para obtener la “culpa” total asignada aweight_cart. El resultado (1.6) indica que un pequeño aumento enweight_cartaumentará la pérdida en 1.6× esa cantidad.
Ese 1.6 nos dice: incremente weight_cart un poco hacia arriba y el error aumentará en 1.6 veces esa cantidad. Para mejorar, movemos el peso en la dirección opuesta.
Veamos qué pasa: Una retropropagación manual en Python
Pongamos esto en un script real pero diminuto. Enseñaremos a weight_cart usando un ejemplo: un visitante con 2 artículos en su carrito que, en retrospectiva, resultó ser un comprador decidido. Antes de que la función Sigmoid comprima cualquier cosa en una probabilidad, queremos que la puntuación ponderada bruta para un caso como este se sitúe alrededor de 10 — lo suficientemente grande para que, tras pasar por Sigmoid, el modelo esté esencialmente seguro. Usaremos una Tasa de aprendizaje, que es simplemente un número pequeño que nos impide reaccionar de forma exagerada y cambiar los pesos demasiado rápido.
weight_cart = 0.5
items_in_cart = 2.0
target_raw_score = 10.0
learning_rate = 0.1
for i in range(3):
# 1. Forward Pass (Make a guess)
prediction = weight_cart * items_in_cart
loss = (prediction - target_raw_score) ** 2
# 2. Calculate Gradient (The 'Blame')
# The math: 2 * (prediction - target) * items_in_cart
gradient = 2 * (prediction - target_raw_score) * items_in_cart
# 3. Update Weight (Nudge it in the right direction)
weight_cart = weight_cart - (learning_rate * gradient)
print(f"Step {i+1}: Prediction={prediction:.2f}, Loss={loss:.2f}, New Weight={weight_cart:.2f}")
target_raw_score = 10.0— La puntuación previa a Sigmoid deseada. Una puntuación bruta de 10 pasaría por la sigmoide como ≈0.99995, haciendo que el modelo esté casi seguro de que este visitante es un comprador.learning_rate = 0.1— Un tamaño de paso pequeño que evita que el peso se dispare demasiado en una sola actualización — la red “aprende” en incrementos pequeños en lugar de saltar a extremos.prediction = weight_cart * items_in_cart— El paso hacia adelante: simplemente la suma ponderada. No hay sesgo ni activación en este ejemplo simplificado, por lo que la predicción es el producto directo.loss = (prediction - target_raw_score) ** 2— Pérdida MSE: elevar al cuadrado la diferencia entre la predicción actual y el objetivo. En la primera iteración esto es (1.0 − 10.0)² = 81.0.gradient = 2 * (prediction - target_raw_score) * items_in_cart— La derivada completa aplicando la regla de la cadena del MSE con respecto aweight_cart. El factor de 2 proviene de derivar el cuadrado;(prediction - target)indica qué tan sensible es la pérdida a la predicción;items_in_cartindica qué tan sensible es la predicción aweight_cart. Multiplícalos y obtendrás el gradiente total.weight_cart = weight_cart - (learning_rate * gradient)— Descenso del gradiente: mueve el peso en dirección opuesta al gradiente (se resta, porque el gradiente apunta hacia el aumento de la pérdida). La tasa de aprendizaje ajusta la magnitud de cada paso.
Observa la salida. La pérdida comienza alta en 81.00 y cae rápido—3.24 después del paso 1, luego 0.13 después del paso 2. Para el tercer paso, weight_cart se ha movido de 0.5 hasta 4.96, y la predicción (9.64) está casi en nuestro objetivo de 10. Estamos observando cómo la red aprende.
Pérdida por Error Cuadrático Medio (MSE)
La pérdida es la diferencia al cuadrado entre la predicción y el objetivo .
La regla de la cadena: Gradiente de la pérdida respecto a un peso
El gradiente de la pérdida con respecto a un peso es igual al producto de (1) qué tan sensible es la pérdida a la predicción, y (2) qué tan sensible es la predicción al peso — cada sensibilidad “local” multiplicada a lo largo de la cadena.
Para el ciclo de entrenamiento específico anterior, donde :
Actualización de pesos (Descenso del gradiente)
El peso se desplaza en la dirección opuesta al gradiente, escalado por la tasa de aprendizaje .
| Lenguaje sencillo | Símbolo estadístico | Equivalente en Python |
|---|---|---|
| Predicción (suma ponderada) | prediction | |
| Valor objetivo | target_raw_score | |
| Peso para los artículos del carrito | weight_cart | |
| Artículos del carrito (entrada) | items_in_cart | |
| Pérdida (MSE) | loss = (prediction - target_raw_score) ** 2 | |
| Gradiente de la pérdida respecto al peso | gradient = 2 * (prediction - target) * items_in_cart | |
| Tasa de aprendizaje | learning_rate | |
| Paso de actualización del peso | weight_cart = weight_cart - (learning_rate * gradient) |
El gradiente desvaneciente: Por qué las redes profundas se ‘cansan’
Aquí está el problema. Una red profunda tiene muchas capas. Para encontrar la culpa de la primera capa, multiplicas las sensibilidades de cada capa que viene después de ella.
Si esas sensibilidades son pequeñas — digamos, 0.1 — y las multiplicas una y otra vez (), la señal se reduce casi a cero. Ese es el Problema del Gradiente Desvanecido. Las primeras capas nunca aprenden, porque la señal de “culpa” desde el final nunca las alcanza. Simplemente se quedan ahí con sus pesos aleatorios originales.
gradient = 1.0
for layer in range(1, 11):
# Imagine each layer squashes the signal by half
gradient = gradient * 0.5
print(f"Layer {layer} gradient: {gradient:.5f}")
gradient = 1.0— Comienza con una señal de gradiente a su máxima fuerza en la capa de salida de la red.gradient = gradient * 0.5— Cada capa multiplica el gradiente entrante por 0.5, simulando una capa cuya sensibilidad es menor que 1. Esto es lo que sucede cuando las funciones de activación como la sigmoide comprimen sus entradas: sus derivadas son números pequeños.- El bucle recorre 10 capas. Para la capa 10, el gradiente ha decaído a 0.00098 — menos del 0.1% de su fuerza original. La actualización de pesos para la primera capa sería tan minúscula que, en la práctica, nunca cambia, sin importar cuántos pasos de entrenamiento ejecutes.
Para la capa 10, el gradiente es 0.00098. La señal es tan débil que el peso apenas se mueve. Construir redes muy profundas fue imposible durante décadas, hasta que los investigadores encontraron formas de mantener viva la señal. Veremos esos trucos cuando lleguemos a Atención.
Resumen: El baile de 3 pasos del aprendizaje
El aprendizaje en la IA no es magia; es un ciclo:
- Predecir (Forward): Haz una estimación usando los pesos actuales.
- Medir (Loss): Observa qué tan lejos estuvo la estimación.
- Distribuir la culpa (Backprop): Usa la regla de la cadena para encontrar qué pesos causaron el error y luego ajústalos ligeramente.
La red es simplemente una máquina que se autocorrige. Así que ahora sabemos cómo aprende un solo camino, y el modelo de Lina puede aprender de sus errores. Pero hay un problema. A medida que las redes se vuelven más profundas, esa asignación de culpa comienza a fallar. La Parte 3 explica el Problema del gradiente desvaneciente.
Comprueba tu comprensión
Las preguntas a continuación van desde el recuerdo simple hasta el diseño abierto, siguiendo aproximadamente la taxonomía de Bloom.
Recordar ¿Qué mide la función de pérdida, y qué nos diría una pérdida de 0.0 sobre una predicción?
Comprender
Con sus propias palabras, explique qué nos permite calcular la regla de la cadena sobre weight_cart, y por qué la necesitamos en lugar de simplemente adivinar en qué dirección mover cada peso.
Aplicar
Utilizando la fórmula de gradiente de este artículo (gradient = 2 * (prediction - target) * items_in_cart), calcule el gradiente para un visitante con items_in_cart = 3, donde el prediction actual es 2.0 y target_raw_score es 10.0. ¿La actualización del peso aumentaría o disminuiría weight_cart?
Analizar
En el bucle de entrenamiento, la pérdida disminuyó de 81.00 a 3.24 a 0.13—una caída enorme al principio, y luego caídas mucho más pequeñas. Explique por qué el gradiente (y por lo tanto el tamaño de cada actualización de peso) se reduce naturalmente a medida que weight_cart se acerca al valor correcto, utilizando la fórmula del gradiente en sí.
Evaluar La demostración del gradiente que desaparece asume que cada capa comprime la señal exactamente a la mitad. Critique esa simplificación: ¿qué tendría que ser cierto sobre las capas de una red real para que la conclusión de “la señal muere para la capa 10” se cumpla realmente, y cuándo podría no cumplirse?
Crear Diseñe un patrón hipotético de sensibilidad por capas (una secuencia de multiplicadores, uno por capa) para una red de 10 capas donde el gradiente no desaparezca en la capa final. ¿Qué requiere su patrón que sea cierto sobre las sensibilidades de la mayoría de las capas, y por qué eso evita el problema que describe este artículo?
Artículos relacionados
- Redes neuronales, sin cálculo: Lo que realmente sucede dentro de una sola neurona
- Por qué mueren las redes profundas: Resolviendo el gradiente evanescente
Referencias y lecturas adicionales
- Rumelhart, D. E., Hinton, G. E., & Williams, R. J. (1986). “Learning representations by back-propagating errors.” Nature, 323, 533–536. — El artículo fundamental que introdujo la retropropagación como un algoritmo práctico para entrenar redes neuronales multicapa.
- Retropropagación (Wikipedia) — Una descripción detallada del algoritmo de retropropagación, incluyendo su derivación matemática y su contexto histórico.
Aplica lo que aprendiste
Tema: Cómo la retropropagación rastrea el error de predicción hacia atrás a través de una cadena de sensibilidades locales para asignar la culpa a los pesos individuales, y por qué esa cadena puede romperse en redes profundas.
Dibuja un mapa mental (papel, Excalidraw, Miro — lo que sea) con al menos estos nodos:
- Paso hacia adelante
- Función de pérdida (MSE)
- Regla de la cadena
- Gradiente
- Tasa de aprendizaje
- Actualización de pesos (Descenso de gradiente)
- Desvanecimiento del gradiente
reference-backpropagation.md
y al menos estas aristas:
- Paso hacia adelante → Función de pérdida (MSE)
- Regla de la cadena → Gradiente
- Gradiente → Actualización de pesos (Descenso de gradiente)
Rúbrica: los 8 nodos nombrados presentes; las 3 aristas requeridas dibujadas; una arista extra propia con una justificación de una oración sobre por qué la añadiste.
Lina envió el servicio de bucle de entrenamiento de BookSight a producción durante la noche. Esta mañana, el panel de monitoreo muestra que la pérdida está aumentando con cada paso de entrenamiento — empezando en 81.00, luego saltando a 262.44 y subiendo desde allí. El servicio está empeorando el modelo, no mejorándolo.
Entregable: Un informe de depuración breve (≤ 200 palabras) que (1) identifique el error intencional en la línea de actualización de pesos, (2) explique el mecanismo — por qué añadir el gradiente en lugar de restarlo dirige el peso hacia una pérdida mayor, y (3) muestre la línea de código corregida. Ejecuta el bucle con errores, confirma que la pérdida diverge; luego arréglalo y confirma que la pérdida cae 81.00 → 3.24 → 0.13 como muestra el artículo.
Rúbrica:
- Identifica la línea errónea específica:
weight_cart = weight_cart + (learning_rate * gradient)— el signo es incorrecto - Explica el mecanismo: el gradiente apunta en la dirección de aumento de la pérdida; añadirlo mueve el peso en la dirección incorrecta (la predicción se vuelve negativa, la pérdida explota)
- Muestra el código corregido:
weight_cart = weight_cart - (learning_rate * gradient) - Confirma que el bucle corregido reproduce la secuencia de pérdida del artículo (81.00 → 3.24 → 0.13) y que el peso alcanza ~4.96
Reproduce las mecánicas centrales de retropropagación de Rumelhart, Hinton, & Williams (1986) —tal como se simplifican en este artículo— y luego rompe el supuesto del gradiente desvanecido.
Breve: Implementa las cuatro ecuaciones del artículo (pérdida MSE, gradiente por regla de la cadena, actualización de pesos, propagación del gradiente desvanecido) en el conjunto de datos sintético de BookSight. Luego ejecuta la ablación: reemplaza la sensibilidad uniforme por capa de 0.5 del artículo por un patrón de sensibilidad de tu propio diseño donde el gradiente sobrevive hasta la capa 10. Compara ambos patrones lado a lado y explica por qué el tuyo evita el desvanecimiento.
Punto de partida: projects/attention-from-scratch-a-deep-p02-backpropagation-intuitively-how-networks-learn-fro/backprop-impl.py
Entregable: Un script de Python completado más un informe de 150–250 palabras que contenga: (1) la secuencia de pérdida reproducida del bucle de entrenamiento de 3 pasos del artículo (81.00 → 3.24 → 0.13), (2) el valor final del gradiente en la capa 10 para el patrón de sensibilidad de 0.5 del artículo frente a tu patrón alternativo, y (3) una explicación de un párrafo sobre qué propiedad de tu patrón evita el desvanecimiento.
Rúbrica:
-
mse_lossdevuelve 0.36 para prediction=0.4, target=1.0 (coincide con el artículo) -
compute_gradientdevuelve −36.0 para los valores del primer paso del artículo (prediction=1.0, target=10.0, items=2.0) - El bucle de entrenamiento reproduce la pérdida 81.00 → 3.24 → 0.13 y el peso alcanza ~4.96
- La demostración del gradiente desvanecido llega a ~0.00098 en la capa 10 con sensitivity=0.5
- El gradiente final del patrón de ablación en la capa 10 es ≥ 0.01 (es decir, no se desvanece)
- El informe explica que el patrón alternativo requiere que las sensibilidades de la mayoría de las capas sean ≥ 1.0, evitando la multiplicación repetida por valores subunitarios que causa el desvanecimiento
Esta traducción fue generada automáticamente y puede contener errores. Si el idioma inglés es tu preferencia, puedes leer el artículo original en inglés .
Artículos relacionados
- Aprendizaje Profundo En revisión
Por qué las computadoras ven mejor con las CNN: una guía intuitiva para el reconocimiento de imágenes
Aprende por qué las CNN superan a las redes densas en el reconocimiento de imágenes utilizando filtros deslizantes, pesos compartidos y pooling para detectar patrones espaciales de manera eficiente.
- Aprendizaje Profundo En revisión
LSTMs y GRUs: Dándole memoria a las redes
Aprende cómo las LSTMs y GRUs usan memoria con compuertas para superar el gradiente desvaneciente, reteniendo señales tempranas a lo largo de secuencias largas para lograr mejores predicciones de secuencias.
- Aprendizaje Profundo En revisión
Referencia: Optimizadores
Una referencia que cubre los optimizadores de redes neuronales desde GD hasta AdamW, con programación de la tasa de aprendizaje, árboles de decisión y guía práctica para cada arquitectura.
- Aprendizaje Profundo En revisión
Atención de múltiples cabezas y codificación posicional: Dándole al Transformer un sentido de dirección
Descubre cómo la codificación posicional le otorga a los Transformers noción del orden de las palabras y la atención de múltiples cabezas rastrea múltiples patrones a la vez en esta guía práctica.
¿Buscas otra cosa?
Busca en todos los artículos por título, resumen o tema.