Soit f:T→R une fonction diffeˊrentiable, ouˋT est l’espace des tenseurs.Le gradient de f en A∈T est le tenseur ∇f(A)∈T deˊfini par :∀dA∈T, t.q. ddA(−1)=dA(−1),Df(A)[dA]=⟨∇f(A),dA⟩
Ceci se lit comme la variation de f évalué en A pour une petite variation dA quelconque.
Pour des scalaires, c'est la définition attendue:
dA=h∈R et Df(A)[h]=⟨f′(A),h⟩=h∗f′(A)=f(A+h)−f(A) pour h assez petit. (∇f(A)=f′(A))
Lorsqu'on a introduit le graphe, on a vu que les noeuds représentaient une opération et pointaient vers d'autres opérations (ou un scalaire si on était à la fin du graphe).
Ce scalaire (souvent noté L) représentera une fonction de perte. On reviendra sur cette fonction plus tard.
Il faut juste comprendre que L montrera les performances du modèle, donc que plus L est faible, mieux le modèle se comporte. On cherche donc à optimiser les paramètres selon L.
Pour ce faire, on va commencer par calculer les gradients de chaque tenseur selon l'ordre topologique donné précédemment.
On va donc commencer par L, car son gradient vaut 1 trivialement.
Puis, on va calculer le gradient de chaque noeud dans l'ordre topologique inversé en utilisant les gradients déjà calculés.
Le but et de calculer le gradiant de A, B (ou A) sachant le gradiant de f(A, B) (ou f(A))
Soit L:T→R différentiable et f:T→T. (appliquée élément par élément) (ex: tanh, ReLU)
On peut donc définir f′ comme la dérivée de f dans R (appliquable à un tenseur), car en réalité f:R→R, on l'a juste étendue pour l'appliquer sur chaque élément du tenseur.
Posons Y=f(A) et G=∇YLY=f(A)∈T
Un bout du graphe (l'application de f) ressemble donc à ça :
Notons d'abord que comme f agit point par point, avec i=(i1,...,iN) un indice (Ti est donc scalaire)
[Df(T)[dT]]i=f′(Ti)dTi⟹dY=Df(T)[dT]=f′(T)⊙dT.
où ⊙ signifie la multiplication élément par élément. (hadamard)
En développant L∘f et d'après la chain rule et la définition de la différentielle, on a :