Idée
On demande à un objet de retenir l'arbre des opérations effectuees sur lui ; quand on dit 'remonte', il calcule mecaniquement les dérivées en remontant cet arbre.
Pourquoi
Au lieu de calculer les dérivées à la main, on demande a Pytorch de retenir, à chaque opération realisee sur un tenseur marque requires_grad=True, l'arbre des opérations effectuees. A l'appel de loss.backward(), l'objet remonte cet arbre en composant les dérivées (règle de la chaîne appliquée mecaniquement) et stocke le résultat dans .grad de chaque tenseur d'entrée. C'est l'analogue automatique de la derivation composée $\dfrac{d(f \circ g)}{dx} = f'(g(x)) \cdot g'(x)$ vue en analyse de spé, mais sur un graphe quelconque.
Outil
Règle de la chaîne $\dfrac{d(f \circ g)}{dx} = f'(g(x)) \cdot g'(x)$ de l'analyse de spé, appliquée mecaniquement sur un graphe d'opérations.
Formule
Le notebook montre la séquence forward_t → log_loss_t → loss.backward(). Sans regarder, expliquer ce que fait précisément backward() au moment où on l'appelle, et où les gradients sont stockés ensuite (quel attribut de quel objet).
Piège
Pytorch cumule les gradients dans .grad d'une itération a l'autre. Si on oublie l'appel optimizer.zero_grad() après chaque optimizer.step(), les gradients se somment de boucle en boucle, ce qui mene a des pas effectifs incoherents et fait diverger l'apprentissage. Le PDF p7 (apprentissage_t) et p10 (apprentissage 2-couches) le rappelle systematiquement par le commentaire # remise a zero des gradients (sinon ils sont cumules). Erreur frequente d'un MPSI débutant en Pytorch.