5 puntos por GN⁺ 2025-11-03 | 1 comentarios | Compartir por WhatsApp
  • La retropropagación (backpropagation) es clave para el entrenamiento de redes neuronales, pero si no se entiende su funcionamiento interno pueden aparecer errores inesperados por tratarse de una “abstracción con fugas (leaky abstraction)”
  • Las funciones de activación sigmoid y tanh pueden hacer que el entrenamiento se detenga por el problema de desvanecimiento del gradiente (vanishing gradient) si la inicialización de pesos es incorrecta
  • ReLU puede provocar el fenómeno de ReLU muerta (dead ReLU), donde una neurona queda desactivada permanentemente cuando la entrada es 0 o menor
  • En las RNN, la multiplicación repetida de matrices puede causar explosión del gradiente (exploding gradient), y para evitarlo hace falta usar gradient clipping o LSTM
  • Si no se entiende cómo funciona la retropropagación, aunque el framework lo maneje automáticamente, la capacidad de depuración y mejora del modelo cae de forma importante

Por qué es necesario entender la retropropagación

  • En el curso CS231n de Stanford, las tareas están diseñadas para que los estudiantes implementen directamente la propagación hacia adelante y la retropropagación
    • Algunos estudiantes se quejan de que eso es innecesario porque frameworks como TensorFlow calculan la retropropagación automáticamente
  • Sin embargo, la retropropagación no es una abstracción completa sino una abstracción con fugas, así que si no se conoce su funcionamiento interno es difícil identificar por qué falla el entrenamiento
  • La actitud de pensar simplemente que “el framework se encarga solo” termina debilitando la capacidad de diseñar modelos y depurarlos

Desvanecimiento del gradiente en sigmoid

  • Las funciones no lineales sigmoid y tanh entran en estado de saturación (saturation) cuando el valor de entrada es grande, porque la salida se acerca a 0 o 1
    • En ese momento, el gradiente local z(1-z)* se vuelve 0 y durante la retropropagación se bloquea la propagación del gradiente
  • El gradiente máximo de sigmoid es 0.25, así que en cada paso la señal se reduce a 1/4 o menos
  • Como resultado, la velocidad de aprendizaje en las capas inferiores se vuelve notablemente más lenta que en las capas superiores
  • Por eso, al usar capas sigmoid, hay que poner especial atención en la inicialización de pesos y el preprocesamiento de datos

El problema de las ReLU muertas

  • ReLU es una función que hace que la salida sea 0 cuando la entrada es 0 o menor
    • Si en la propagación hacia adelante la salida de una neurona es 0, durante la retropropagación el gradiente también será 0, por lo que esa neurona puede quedar desactivada permanentemente
  • Durante el entrenamiento, una actualización grande de pesos o una tasa de aprendizaje alta puede hacer que la neurona quede fijada en un “estado muerto”
  • Incluso después del entrenamiento, puede ocurrir que una parte considerable de todas las neuronas siga produciendo 0
  • Por eso, al usar ReLU, son importantes el ajuste de la tasa de aprendizaje y la estrategia de inicialización

Explosión del gradiente en RNN

  • En una RNN simple, la misma matriz de estado oculto (Whh) se multiplica repetidamente en cada paso temporal
    • Durante la retropropagación, el gradiente converge a 0 o crece sin límite según el tamaño del eigenvalor (eigenvalue) de esa matriz
  • Si |b| < 1, ocurre desvanecimiento del gradiente; si |b| > 1, ocurre explosión del gradiente
  • Para evitarlo, lo habitual es aplicar gradient clipping o usar una arquitectura LSTM

Un caso de clipping incorrecto en código DQN

  • En una implementación de DQN basada en TensorFlow, se encontró código que aplicaba tf.clip_by_value directamente sobre delta (el error de Q)
    • Con ese enfoque, si delta se sale del rango, el gradiente se vuelve 0 y el entrenamiento se detiene
  • Como lo que se quería era gradient clipping, en su lugar debía usarse Huber loss
    • En el código de ejemplo, la pérdida de Huber se implementa de forma condicional combinando tf.square y tf.abs
  • Este problema se reportó en un issue de GitHub y se corrigió de inmediato

Conclusión

  • La retropropagación no es solo una herramienta de automatización, sino un sistema de asignación de crédito (credit assignment) que produce consecuencias complejas
  • Si no se entiende su funcionamiento interno, uno termina enfrentándose a inestabilidad del modelo, fallas de entrenamiento y límites para depurar
  • La retropropagación no es matemáticamente difícil, y se puede aprender de forma intuitiva mediante el curso y las tareas de CS231n
  • Entender la retropropagación mejora mucho la capacidad para diseñar redes neuronales y resolver problemas
  • Más que depender de la diferenciación automática del framework, lo importante es conocer el flujo real de la retropropagación

1 comentarios

 
GN⁺ 2025-11-03
Comentarios de Hacker News
  • Aquí parece que backpropagation se está llevando una mala fama injustificada.
    En realidad, esta discusión trata menos sobre backpropagation en sí y más sobre qué tan imperfectas son las abstracciones de los gradients y las variantes de gradient descent dentro del proceso de optimización.
    Backpropagation es solo un algoritmo para calcular la derivada de una función compuesta, y problemas como el vanishing gradient que aparece al apilar varias sigmoids no son culpa de backpropagation, sino de las propiedades de la función en sí.
    La razón por la que se hace que la gente implemente el backward pass a mano es para que, al calcular las derivadas directamente, puedan sentir cómo actúan los términos exponenciales.

    • Entiendo lo que dices, pero en este caso creo que esa “aclaración menor” no resulta muy útil.
      El punto central es que en ciertas situaciones no se pueden abstraer los detalles de backpropagation, incluido el cálculo de gradients.
      Eso pasa especialmente cuando usas gradient descent, y quizá sea menos problemático con otros algoritmos de optimización global.
      Como en la práctica la única forma de calcular gradients en deep learning es backpropagation, esta filtración de la abstracción es algo real.
    • No me parece una aclaración menor, sino una refutación válida a un marco conceptual equivocado.
      Respeto la contribución de Karpathy, pero sus textos y charlas a menudo difuminan las distinciones conceptuales, lo que genera malentendidos.
      Dado su nivel, uno esperaría mayor precisión.
  • La contribución educativa de Karpathy al deep learning es realmente enorme.
    Desde textos cortos hasta su texto clásico sobre RNN, además de sus clases en YouTube y proyectos en GitHub, todo es excelente.
    El recientemente publicado nanochat también es un gran ejemplo: un ejemplo completo, pequeño y claro ayuda muchísimo a quienes están aprendiendo.

    • Les recomendé los textos de Karpathy a colegas muy metidos en LLM, pero para mi sorpresa no les interesaron.
      Después me di cuenta de que les interesaba más confiar en los LLM y usarlos que entenderlos.
      En la práctica, parecían más atraídos por discusiones especulativas como “una sociedad donde máquinas inteligentes hagan todo el trabajo” que por cómo funcionan realmente los LLM.
    • La forma de trabajar de Karpathy es interesante.
      En vez de simplemente “preguntarle a ChatGPT”, él busca por su cuenta, lee código y encuentra bugs.
      Ese enfoque exploratorio es el aprendizaje de verdad.
  • En la maestría hice una tarea de implementar backpropagation a mano a partir de un paper.
    Consistía en escribir el forward y el backward pass usando solo operaciones matemáticas, y fue la mejor experiencia de aprendizaje de ese año.
    Es el tipo de ejercicio que uno casi nunca haría por iniciativa propia, pero cuando te obligan resulta de enorme ayuda.

    • La diferencia de comprensión entre solo leer el paper y implementarlo en código es gigantesca.
    • Yo lo implementé en Java cuando iba en la prepa, y lo más difícil fue escribir por mi cuenta la multiplicación de matrices.
      Hice una UI para visualizar cómo cambiaban los pesos y los sesgos durante el entrenamiento.
    • Me pregunto si ese paper está disponible públicamente.
  • Me daba curiosidad la relación entre backpropagation y el optimizer.
    SGD simplemente avanza en la dirección del gradient, pero optimizers más sofisticados como Adam no usan el gradient de forma directa, sino que aplican normalización, momentum, clipping y otras técnicas.
    Entonces, ¿de verdad hace falta calcular el gradient exacto, o basta con conocer una dirección aproximada?

    • En la práctica, el gradient se aproxima con minibatches pequeños, así que cada paso es ruidoso, pero curiosamente ese ruido puede ayudar al rendimiento.
      Hay trabajos relacionados como papers sobre el ruido en SGD y estudios de visualización.
      Pero aproximar la dirección “más o menos” es peligroso, porque la curvatura (Hessian) de la función de loss cambia bruscamente.
    • “¿No basta con conocer la dirección en vez del gradient exacto?” es una pregunta vieja.
      De hecho, de ideas como esa surgió stochastic gradient descent, y también enfoques como Direct Feedback Alignment.
      También es interesante el resumen de Ben Recht sobre la relación entre optimización y reinforcement learning.
    • Backpropagation calcula derivadas exactas al nivel de la precisión numérica.
      Lo importante no es tanto el valor de la función de loss como la forma del gradient y de la curvatura.
      Optimizers como Adam estiman en primera aproximación la sensibilidad de escala de cada parámetro y ajustan el gradient en consecuencia.
      Una optimización de orden superior no es posible con funciones no lineales como ReLU.
    • Ajustar el gradient no es un “fudge”.
      Es una medida esencial para resolver el problema del vanishing gradient.
      En espacios de alta dimensión, incluso errores pequeños pueden tener efectos grandes, así que calcular el gradient con precisión es muy importante.
    • El cálculo en sí no es difícil.
      El problema empieza ya desde cómo calcular esa “dirección aproximada”.
      Incluso optimizers avanzados como AdamW siguen usando el gradient como pieza central.
  • Por allá de 2016, da la impresión de que se usaban mucho más seguido trucos como el gradient clipping.
    Por ejemplo, en el paper de 2013 de Alex Graves, Sequence Generation with RNNs, se menciona que usó clipping para evitar gradients explosivos en LSTM.
    Yo mismo sentí tanto la importancia de backpropagation que tomé incluso un curso especializado solo sobre PyTorch autograd.

    • Antes parece que había muchos de estos trucos porque se experimentaba con arquitecturas de red más variadas.
      Ahora los frameworks ya soportan clipping, y la comprensión de los problemas de entrenamiento ha mejorado.
      Pero el problema no ha desaparecido: ReLU y GELU siguen siendo activaciones por defecto, y el entrenamiento de LLM todavía se parece bastante a un “arte negro”.
      El Smol Training Playbook de Hugging Face es prueba de ello.
  • A largo plazo, quizá convenga entrenar modelos robustos a la diversidad de funciones de activación.
    Por ejemplo, si durante el entrenamiento se alternaran aleatoriamente ReLU, Swish, GELU, etc., se podría obtener un efecto de regularización parecido al de dropout.
    Así, en inferencia se podría cambiar por la función computacionalmente más barata.

  • El título original, “Yes you should understand backprop”, es mucho más claro y mejor.

    • Precisamente porque backpropagation es una abstracción que tiene filtraciones, es importante construir intuición haciéndolo a mano.
      Si el código hace demasiadas cosas por ti, es fácil caer en la ilusión de que “funciona por magia”.
      En posgrado me ayudó mucho haber calculado convolución y backpropagation a mano.
  • La pregunta “si el framework calcula automáticamente el backward pass, ¿por qué tendría que escribirlo yo?”
    suena preocupante porque sigue la misma lógica que “si ya existe la calculadora, ¿para qué aprender suma?”.

    • También hay una objeción.
      Así como es útil entender compiladores, algoritmos de ordenamiento o cómo funcionan los transistores, aprender backpropagation también tiene valor.
      Pero como el tiempo de aprendizaje es limitado, la cuestión clave es si esto aporta más que estudiar otros temas.
      Vale la pena aprender backpropagation porque, si no entiendes su funcionamiento interno, es difícil reconocer modos de falla ocultos.
      Yo también lo he implementado varias veces, y tiene justo la complejidad adecuada para evaluar un lenguaje nuevo.
  • Cuando empecé a aprender deep learning, backpropagation se sentía casi como magia.
    Pero cuando lo implementé por mi cuenta, vi que era solo una secuencia de cálculos sencillos, y eso me dio mucha más confianza para depurar o encontrar por qué el loss se estancaba.
    A cualquiera que esté aprendiendo deep learning le recomendaría implementarlo a mano al menos una vez.

  • También hay una postura contraria.
    No creo que los estudiantes necesiten implementar backpropagation en NumPy.
    Los problemas de filtración de BackProp los resuelven los investigadores con nuevos optimizers, y los desarrolladores solo tienen que encontrar buenos hiperparámetros.

    • Pero el propósito de la universidad es formar investigadores.
    • Decir “solo hay que elegir un buen optimizer” es un malentendido.
      Parte del problema surge en el diseño del modelo o el loop de entrenamiento.
      Por ejemplo, gradient clipping no es el valor por defecto en la mayoría de los frameworks.
      Este texto está dirigido a lectores con una perspectiva investigadora o académica.
    • El problema no es el optimizer, sino las propiedades de las derivadas de las funciones de activación.
      Si no entiendes cómo se comportan los gradients de funciones como sigmoid o ReLU, no puedes resolver los problemas de explosión o desvanecimiento.
    • Si se trata de una clase de CS en Stanford, es natural implementar directamente los principios básicos.
      Para crear una arquitectura nueva hay que entender cómo funciona backpropagation; si no, el entrenamiento falla o el rendimiento empeora.
    • El problema es dejar sin explorar lo que no sabes.
      Solo al atravesar la abstracción puedes descubrir las verdaderas áreas desconocidas (unknown unknowns).