Autograd : le forward construit le graphe, backward le redescend

Idée

Quand on calcule la sortie, le programme note silencieusement la suite des opérations sur un carnet. Quand on demande la dérivée, il relit le carnet a l'envers en appliquant la règle de la chaîne.

Pourquoi

Quand on écrit A = forward(X, parametres) puis loss = log_loss(A, Y), pytorch enregistre silencieusement la suite des opérations dans un graphe orienté. L'appel loss.backward() parcourt ce graphe a l'envers en appliquant la règle de la chaîne et depose dans parametres['W1'].grad, parametres['b1'].grad, etc., les dérivées partielles de la loss par rapport à chaque coefficient. Ce que l'on aurait calculé à la main avec quatre dérivées imbriquees, le graphe le fait en une instruction.

Outil

Règle de la chaîne $(f \circ g)' = f'(g) \cdot g'$ vue en spé MPSI : ici elle s'appliqué recursivement le long du graphe, mais c'est exactement la même règle.

Formule

Dans la boucle d'apprentissage (cellule 18), on trouve loss.backward(); optimizer.step(); optimizer.zero_grad(). Le commentaire signale : 'sinon ils sont cumules'. Decrire ce qui se passe si l'on retire zero_grad() : qu'arrive-t-il a parametres['W1'].grad après deux itérations ? Pourquoi ce comportement par defaut de pytorch (cumul plutot que remise a zero automatique) est-il en fait utile dans certaines situations ?

Piège

Par défaut, Pytorch libère le graphe après le premier backward(). Appeler une 2e fois lève RuntimeError: Trying to backward through the graph a second time. Pour le faire, il faut loss.backward(retain_graph=True). Cas typique : on veut analyser plusieurs gradients dérivés de la même loss, on oublie le flag.