5 points par GN⁺ 2025-11-03 | 1 commentaires | Partager sur WhatsApp
  • La rétropropagation (backpropagation) est au cœur de l’apprentissage des réseaux de neurones, mais si l’on ne comprend pas son fonctionnement interne, elle peut provoquer des erreurs inattendues dans une structure d’« abstraction qui fuit » (leaky abstraction)
  • Les fonctions d’activation sigmoid et tanh peuvent entraîner un vanishing gradient si l’initialisation des poids est incorrecte, au point de bloquer l’apprentissage
  • ReLU peut provoquer le phénomène de dead ReLU, où un neurone devient définitivement inactif lorsque son entrée est inférieure ou égale à 0
  • Dans les RNN, des multiplications répétées de matrices peuvent entraîner un exploding gradient ; pour l’éviter, il faut utiliser le gradient clipping ou des LSTM
  • Sans compréhension du fonctionnement de la rétropropagation, même si le framework la gère automatiquement, les capacités de debugging et d’amélioration du modèle chutent fortement

Pourquoi il faut comprendre la rétropropagation

  • Dans le cours CS231n de Stanford, les devoirs demandent aux étudiants d’implémenter eux-mêmes la propagation avant et la rétropropagation
    • Certains étudiants se plaignent que ce soit inutile, puisque des frameworks comme TensorFlow calculent automatiquement la rétropropagation
  • Mais la rétropropagation n’est pas une abstraction complète, c’est une abstraction qui fuit : sans comprendre son fonctionnement interne, il devient difficile d’identifier pourquoi l’apprentissage échoue
  • Se contenter de dire que « le framework s’en occupe » conduit à une dégradation des compétences en conception de modèles et en debugging

Le vanishing gradient avec la sigmoid

  • Les fonctions non linéaires sigmoid et tanh entrent en saturation lorsque la valeur d’entrée est grande, et la sortie se rapproche alors de 0 ou de 1
    • À ce moment-là, le gradient local z(1-z)* devient nul, ce qui bloque la propagation du gradient pendant la rétropropagation
  • Le gradient maximal d’une sigmoid est de 0,25 ; à chaque passage, le signal est donc réduit à 1/4 ou moins
  • En conséquence, la vitesse d’apprentissage des couches inférieures devient nettement plus lente que celle des couches supérieures
  • Lorsqu’on utilise des couches sigmoid, il faut donc accorder une attention particulière à l’initialisation des poids et au prétraitement des données

Le problème des dead ReLU

  • ReLU est une fonction qui renvoie 0 lorsque l’entrée est inférieure ou égale à 0
    • Si, en propagation avant, la sortie d’un neurone est 0, alors pendant la rétropropagation, le gradient devient lui aussi 0, et ce neurone peut devenir définitivement inactif
  • Pendant l’apprentissage, de grosses mises à jour de poids ou un taux d’apprentissage élevé peuvent figer un neurone dans un « état mort »
  • Il arrive aussi qu’après l’apprentissage, une part importante des neurones du réseau produise 0
  • Avec ReLU, le réglage du taux d’apprentissage et la stratégie d’initialisation sont donc essentiels

L’exploding gradient dans les RNN

  • Dans un RNN simple, la même matrice d’état caché (Whh) est multipliée de façon répétée à chaque pas de temps
    • Lors de la rétropropagation, selon la taille des valeurs propres (eigenvalues) de cette matrice, le gradient peut converger vers 0 ou croître à l’infini
  • Si |b| < 1, on obtient un vanishing gradient ; si |b| > 1, un exploding gradient se produit
  • Pour l’éviter, on applique en général du gradient clipping ou on utilise une architecture LSTM

Exemple de mauvais clipping dans du code DQN

  • Dans une implémentation DQN basée sur TensorFlow, on a trouvé du code qui appliquait directement tf.clip_by_value au delta (erreur Q)
    • Avec cette approche, dès que le delta sort de l’intervalle, le gradient devient nul et l’apprentissage s’arrête
  • L’intention était de faire du gradient clipping ; il faut donc utiliser à la place une Huber loss
    • Dans l’exemple de code, la perte de Huber est implémentée de manière conditionnelle en combinant tf.square et tf.abs
  • Le problème a été signalé via une issue GitHub et corrigé immédiatement

Conclusion

  • La rétropropagation n’est pas un simple outil d’automatisation, mais un mécanisme d’attribution du crédit (credit assignment) qui entraîne des conséquences complexes
  • Sans compréhension de son fonctionnement interne, on se heurte à l’instabilité des modèles, aux échecs d’apprentissage et aux limites du debugging
  • La rétropropagation n’est pas difficile mathématiquement, et on peut l’apprendre de manière intuitive grâce au cours CS231n et à ses devoirs
  • Comprendre la rétropropagation améliore fortement la conception des réseaux de neurones et la capacité à résoudre les problèmes
  • Plutôt que de dépendre uniquement de la différentiation automatique du framework, il est important de maîtriser le flux réel de la rétropropagation

1 commentaires

 
GN⁺ 2025-11-03
Commentaires sur Hacker News
  • On a l’impression que backpropagation se prend ici une mauvaise réputation de façon injustifiée
    En réalité, cette discussion porte moins sur la rétropropagation elle-même que sur à quel point les gradients et les variantes de gradient descent constituent une abstraction imparfaite du processus d’optimisation
    La rétropropagation n’est qu’un algorithme pour calculer la dérivée d’une fonction composée, et des problèmes comme la disparition du gradient causée par l’empilement de sigmoïdes ne sont pas des problèmes de rétropropagation, mais des propriétés de la fonction elle-même
    Si on demande aux gens d’implémenter eux-mêmes la backward pass, c’est pour qu’ils ressentent concrètement, en calculant directement les dérivées, comment les termes exponentiels interviennent

    • Je vois ce que tu veux dire, mais dans ce cas je pense que cette « correction mineure » n’est pas très utile
      L’essentiel, c’est que dans certaines situations on ne peut pas abstraire les détails de la rétropropagation, y compris le calcul du gradient
      C’est particulièrement vrai quand on utilise gradient descent, et le problème peut être moindre avec d’autres algorithmes d’optimisation globale
      Comme, en pratique aujourd’hui, la rétropropagation est la seule manière de calculer les gradients en deep learning, cette fuite d’abstraction est bien réelle
    • Ce n’est pas une correction mineure, mais une réfutation légitime d’un cadre conceptuel erroné
      Je respecte la contribution de Karpathy, mais ses textes et ses conférences ont souvent tendance à brouiller les distinctions conceptuelles, ce qui crée des malentendus
      À son niveau, on s’attend à une précision plus élevée
  • La contribution de Karpathy à l’enseignement du deep learning est vraiment énorme
    Des billets courts jusqu’au texte de référence sur les RNN, en passant par ses cours sur YouTube et ses projets GitHub, tout est excellent
    Le récent nanochat en est aussi un très bon exemple : un exemple complet, petit et clair aide énormément les personnes qui apprennent

    • J’ai recommandé les textes de Karpathy à des collègues très investis dans les LLM, et à ma surprise ils n’étaient pas intéressés
      Plus tard, j’ai compris qu’ils s’intéressaient davantage à faire confiance aux LLM et les utiliser qu’à les comprendre
      En pratique, le fonctionnement des LLM les intéressait moins que des discussions spéculatives du type « une société où des machines intelligentes font tout »
    • La manière de travailler de Karpathy est intéressante
      Au lieu de simplement « demander à ChatGPT », il cherche lui-même, lit le code et trouve des bugs
      Cette démarche d’exploration est un véritable apprentissage
  • En master, j’ai eu un devoir consistant à implémenter la rétropropagation à partir d’un article
    Il fallait écrire la forward pass et la backward pass uniquement avec des opérations mathématiques, et ça a été ma meilleure expérience d’apprentissage de l’année
    C’est le genre de travail qu’on ne fait pas spontanément, mais qui aide énormément quand on est obligé de le faire

    • L’écart de compréhension entre lire un article et l’implémenter soi-même en code est immense
    • Je l’avais implémentée moi-même en Java au lycée, et le plus difficile avait été d’écrire la multiplication matricielle à la main
      J’avais aussi créé une UI pour visualiser comment les poids et les biais évoluaient pendant l’entraînement
    • Je me demande si cet article est disponible publiquement
  • Je me suis interrogé sur la relation entre la rétropropagation et l’optimizer
    SGD se contente d’avancer dans la direction du gradient, mais des optimizers plus sophistiqués comme Adam n’utilisent pas le gradient tel quel : ils appliquent normalisation, momentum, clipping, etc.
    Dans ce cas, a-t-on vraiment besoin d’un gradient exact, ou suffit-il de connaître approximativement la bonne direction ?

    • En pratique, on approxime déjà le gradient avec de petits minibatchs, donc chaque étape est bruitée, mais ce bruit aide justement à améliorer les performances
      On peut citer les articles sur le bruit dans SGD et les travaux de visualisation
      Mais estimer la direction « à peu près » reste risqué — la courbure de la fonction de loss (Hessian) peut varier brutalement
    • « A-t-on seulement besoin de la direction plutôt que d’un gradient exact ? » est une vieille question
      En pratique, c’est ce type d’idée qui a donné stochastic gradient descent, et on trouve aussi des approches comme Direct Feedback Alignment
      Le résumé de Ben Recht sur le lien entre optimisation et apprentissage par renforcement est aussi intéressant
    • La rétropropagation effectue un calcul exact de la dérivée au niveau de la précision numérique
      Ce qui compte, ce n’est pas tant la valeur de la loss que la forme du gradient et de la courbure
      Des optimizers comme Adam ajustent le gradient en estimant, via une approximation du premier ordre, la sensibilité d’échelle de chaque paramètre
      Une optimisation d’ordre supérieur est impossible avec des fonctions non linéaires comme ReLU
    • Ajuster le gradient n’est pas un « fudge »
      C’est une mesure indispensable pour résoudre le problème du vanishing gradient
      Dans un espace de grande dimension, même une petite erreur peut avoir de gros effets, donc un calcul précis du gradient est très important
    • Le calcul différentiel en lui-même n’est pas difficile
      Le vrai problème, c’est déjà de savoir comment calculer cette « direction approximative »
      Même des optimizers avancés comme AdamW reposent toujours fondamentalement sur le gradient
  • Vers 2016, j’ai l’impression qu’on utilisait bien plus souvent des astuces comme le gradient clipping
    Par exemple, dans son article de 2013 Sequence Generation with RNNs, Alex Graves indique aussi avoir utilisé du clipping pour éviter l’explosion du gradient dans les LSTM
    J’avais même suivi un cours spécialisé uniquement sur l’autograd de PyTorch, tellement l’importance de la rétropropagation me paraissait claire

    • À l’époque, on expérimentait beaucoup de structures de réseau différentes, d’où la multiplication de ce genre d’astuces
      Aujourd’hui, les frameworks prennent en charge le clipping, et la compréhension des problèmes d’entraînement s’est améliorée
      Mais le problème lui-même n’a pas disparu — ReLU ou GELU restent des fonctions d’activation de base, et l’entraînement des LLM reste encore proche de l’« art noir »
      Le Smol Training Playbook de Hugging Face en est la preuve
  • À long terme, je pense qu’il pourrait être avantageux d’entraîner des modèles robustes à la diversité des fonctions d’activation
    Par exemple, on pourrait alterner aléatoirement entre ReLU, Swish, GELU, etc. pendant l’entraînement, afin d’obtenir une sorte d’effet de régularisation comparable au dropout
    On pourrait alors, à l’inférence, remplacer ces fonctions par celle qui coûte le moins cher en calcul

  • Le titre d’origine, « Yes you should understand backprop », était bien plus clair et meilleur

    • Justement parce que la rétropropagation est une abstraction qui fuit, il est important de construire son intuition en faisant les calculs soi-même
      Quand le code fait trop de choses à votre place, on tombe facilement dans l’illusion que « ça marche par magie »
      Le fait d’avoir calculé moi-même à la main les convolutions et la rétropropagation en école doctorale m’a beaucoup aidé
  • La question « si le framework calcule automatiquement la backward pass, pourquoi faudrait-il l’écrire soi-même ? »
    repose sur la même logique inquiétante que « pourquoi apprendre l’addition s’il existe des calculatrices ? »

    • Il y a aussi une objection
      De la même manière qu’il est utile de comprendre les compilateurs, les algorithmes de tri ou le fonctionnement des transistors, apprendre la rétropropagation a de la valeur
      Mais le temps d’apprentissage est limité, donc la vraie question est de savoir si cela est plus utile que d’autres sujets
      La rétropropagation mérite d’être étudiée parce que, si l’on ne comprend pas son fonctionnement interne, il devient difficile d’identifier ses modes de défaillance cachés
      Je l’ai moi-même implémentée plusieurs fois, et c’est exactement le bon niveau de complexité pour évaluer un nouveau langage
  • Quand j’ai commencé à apprendre le deep learning, la rétropropagation me paraissait quasi magique
    Mais en l’implémentant moi-même, j’ai découvert qu’il ne s’agissait que d’une suite de calculs simples, ce qui m’a donné bien plus de confiance pour déboguer ou comprendre pourquoi la loss stagnait
    Si vous apprenez le deep learning, je recommande de l’implémenter vous-même au moins une fois

  • Il existe aussi un point de vue opposé
    Je ne pense pas qu’il soit nécessaire que les étudiants implémentent la rétropropagation en NumPy
    Les problèmes de fuite d’abstraction de BackProp seront résolus par les chercheurs avec de nouveaux optimizers, et les développeurs n’auront plus qu’à trouver de bons hyperparamètres

    • Mais à l’université, l’objectif est précisément de former les étudiants comme chercheurs
    • Dire qu’« il suffit de choisir un bon optimizer » est une erreur
      Une partie du problème vient de la conception du modèle ou de la boucle d’entraînement
      Par exemple, le gradient clipping n’est pas la valeur par défaut dans la plupart des frameworks
      Ce texte s’adresse à des lecteurs ayant une perspective de recherche ou universitaire
    • Le problème, ce n’est pas l’optimizer, mais les propriétés différentielles des fonctions d’activation
      Si l’on ne comprend pas le comportement du gradient pour des fonctions comme sigmoid ou ReLU, on ne peut pas résoudre les problèmes d’explosion ou de disparition
    • Dans un cours d’informatique à Stanford, il est normal d’implémenter soi-même les principes fondamentaux
      Pour créer de nouvelles architectures de modèles, il faut comprendre le fonctionnement de la rétropropagation ; sinon, l’entraînement échoue ou les performances se dégradent
    • Le problème, c’est de rester ignorant de ce qu’on ignore
      C’est en perçant les abstractions qu’on découvre enfin les véritables zones d’ignorance (unknown unknowns)