Les informations pratiques concernant le déroulement de l’unité d’enseignement RCP209 « Apprentissage, réseaux de neurones et modèles graphiques » au Cnam se trouvent dans ce préambule.

Cours - Introduction à l’apprentissage profond (deep learning)

[Diapositives du cours]

Calcul des gradients

Considérons une entrée \(\mathbf{x_i} \in \mathbb{R}^d\). On note \(\hat{\mathbf{y_i}} = (y_{1,i}, y_{2,i}, \dots, y_{K, i})\) le vecteur des prédictions (\(K\) classes) et \(\mathbf{y_i^*}\) le vecteur de la vérité terrain pour l’example \(\mathbf{x_i}\).

On rappelle que :

\[l_\text{CE}(\hat{\mathbf{y_i}}, \mathbf{y_i}^*) = - \sum_{c'=1}^K y^*_{c',i} \log(\hat{y}_{c',i})\]
\[\hat{y}_{c,i} = \operatorname{softmax}(s_{c,i}) = \frac{\exp(s_{c,i})}{\sum_{c'=1}^K \exp(s_{c',i})}\]
\[\mathbf{s_i} = \mathbf{W} \mathbf{h} + \mathbf{b}\]
  • Dans le cas de la régression logistique : \(\mathbf{h} = \mathbf{x_i}\).

  • Dans le cas du perceptron multi-couche : \(\mathbf {h} = \sigma(\mathbf{W^h} \mathbf{x_i} + \mathbf{b^h})\)

Étape 1 : \(\nabla_\mathbf{\hat{y_i}} l_\text{CE}\)

Pour commencer, nous allons calculer la dérivée partielle de l’entropie croisée, c’est-à-dire du coût \(l_\text{CE}\), par rapport à la \(c\)-ième composant \(\hat{y}_{c,i}\) du vecteur de prédictions :

\[\begin{align} \frac{\partial l_\text{CE}}{\partial \hat{y_{c,i}}} &= \frac{\partial}{\partial \hat{y_{c,i}}}\left( - \sum_{c'=1}^K y^{*}_{c',i} \log (\hat{y_{c',i}}) \right)\\ &= -\sum_{c'=1}^K \frac{\partial}{\partial \hat{y_\text{c,i}}} \left(y^{*}_{c',i} \log (\hat{y_{c',i}})\right)\\ \end{align}\]

Soit \(c^*\) la classe de la vérité terrain (c’est-à-dire la vraie classe de \(\mathbf{x_i}\). Alors \(y^*_\text{c*, i} = 1\) et \(y^*_\text{c', i} = 0\) pour \(c' \neq c^*\). Les termes de la somme de l’équation précédente sont tous nuls à l’exception du cas \(c' = c^*\) :

\[\begin{align} \frac{\partial l_\text{CE}}{\partial \hat{y_{c,i}}} &= - \frac{\partial}{\partial \hat{y_{c,i}}} (y_{c^*,i} \log (\hat{y}_{c^*,i})) &= - \frac{\partial}{\partial \hat{y_{c,i}}} \log (\hat{y}_{c^*,i}) ~~~~\text{car}~~~~ y_{c^*,i} = 1\\ \end{align}\]

Donc pour tout \(c \neq c^*, \frac{\partial l_\text{CE}}{\partial \hat{y_{c,i}}} = 0\). Dans le cas \(c = c^*\), alors :

\[\frac{\partial l_\text{CE}}{\partial \hat{y_{c^*,i}}} = - \frac{\partial \log{\hat{y}_{c^*,i }}}{\partial \hat{y_{c^*,i}}} = - \frac{1}{\hat{y}_{c^*,i }}\]

Autrement dit, le gradient s’écrit :

\[\nabla_{\mathbf{\hat{y}_i}} l_\text{CE} = (0, \dots, \underbrace{\frac{-1}{\hat{y}_{c^*, i}}}_{\text{composante}~ c^*} , \dots, 0)\]

ce qui peut se réécrire comme la multiplication élément par élément (\(\odot\)) entre \(\frac{1}{\hat{y}_{c^*,i}}\) et un vecteur binaire \(\delta_{c, c^*}\):

\[\nabla_{\mathbf{\hat{y}_i}} l_\text{CE} = \frac{-1}{\hat{y}_{c^*, i}} \odot (0, \dots, \underbrace{1}_{\text{composante}~ c^*} , \dots, 0) = \frac{-1}{\hat{y}_{c^*, i}} \odot \mathbf{\delta_{c,c^*}}\]

Étape 2 : \(\nabla_\mathbf{s_i} l_\text{CE}\)

Par chain rule (théorème de dérivation des fonctions composées), on a l’égalité :

\[\frac{\partial l_\text{CE}}{\mathbf{s_i}} = \frac{\partial l_\text{CE}}{\partial \mathbf{\hat{y_i}}} \frac{\partial \mathbf{\hat{y_i}}}{\partial \mathbf{s_i}}\]

Pour calculer les gradients de l’entropie croisée par rapport aux activations avant softmax (logits), on doit donc calculer tous les coefficients \(\frac{\partial {\hat{y_{p,i}}}}{\partial {s_{q,i}}}\) de la matrice Jacobienne :

\[\frac{\partial \hat{y_{p,i}}}{\partial s_{q,i}} = \frac{\partial~\text{softmax}(s_{p,i})}{\partial s_{q,i}} = \frac{\partial \left(\frac{\exp(s_{p,i})}{\sum_{p'=1}^K \exp(s_{p',i})}\right)}{\partial s_{q,i}}\]

Par le théorème de dérivation du quotient de deux fonctions (\((\frac{u}{v})' = \frac{uv' - u'v}{v^2}\)):

\[\begin{align} \frac{\partial \hat{y_{p,i}}}{\partial s_{q,i}} &= \frac{\frac{\partial}{\partial s_{q,i}} \left(\exp(s_{p,i})\right)\sum_{p'=1}^K \exp(s_{p',i}) - \exp(s_{p,i}) \frac{\partial}{\partial s_{q,i} } \left(\sum_{p'=1}^K \exp(s_{p',i})\right)}{\left(\sum_{p'=1}^K \exp(s_{p',i})\right)^2}\\ \end{align}\]

Il faut distinguer deux cas :

\[\frac{\partial}{\partial s_{q,i}} \exp(s_{p,i}) = \begin{cases} 0 & \text{si} & p\neq q\\ \exp(s_{p,i}) & \text{si} & p = q\\ \end{cases}\]

Pour cette raison, la dérivation de la somme au numérateur donne dans tous les cas :

\[\frac{\partial}{\partial s_{q,i} } \left(\sum_{p'=1}^K \exp(s_{p',i})\right) = \sum_{p'=1}^K \frac{\partial}{\partial s_{q,i} } \exp(s_{p',i}) = \exp(s_{q,i})\]

donc la dérivée partielle se réécrit :

\[\begin{align} \frac{\partial \hat{y_{p,i}}}{\partial s_{q,i}} &= \frac{\frac{\partial}{\partial s_{q,i}} \left(\exp(s_{p,i})\right)\sum_{p'=1}^K \exp(s_{p',i}) - \exp(s_{p,i}) \exp(s_{q,i})}{\left(\sum_{p'=1}^K \exp(s_{p',i})\right)^2}\\ \end{align}\]

Cas \(p = q\) :

On remplace \(q\) par \(p\) dans l’équation précédente, partout au numérateur :

\[\begin{align} \frac{\partial \hat{y_{p,i}}}{\partial s_{p,i}} &= \frac{\underbrace{\frac{\partial}{\partial s_{p,i}} \left(\exp(s_{p,i})\right)}_\text{dérivée de $\exp$}\sum_{p'=1}^K \exp(s_{p',i}) - \exp(s_{p,i}) \exp(s_{p,i})}{\left(\sum_{p'=1}^K \exp(s_{p',i})\right)^2}\\ &= \frac{\exp(s_{p,i}) \S - \exp(s_{p,i}) \exp(s_{p,i})}{(\sum_{p'=1}^K \exp(s_{p',i}))^2}\\ &= \frac{\exp(s_{p,i})\left(\S - \exp(s_{p,i})\right)}{(\sum_{p'=1}^K \exp(s_{p',i}))^2}\\ &= \underbrace{\frac{\exp(s_{p,i})}{\S}}_\text{softmax de $s_{p,i}$} \cdot \frac{\sum_{p'=1}^K \exp(s_{p',i}) - \exp(s_{p,i})}{\S}\\ &= \hat{y}_{p,i} \cdot (1 - \underbrace{\frac{\exp(s_{p,i})}{\sum_{p'=1}^K \exp(s_{p',i})}}_{\text{softmax de } s_{p,i}})\\ &= \hat{y}_{p,i} \cdot (1 - \hat{y}_{p,i}) \end{align}\]

Cas \(p \neq q\) :

\[\begin{align} \frac{\partial \hat{y_{p,i}}}{\partial s_{q,i}} &= \frac{\underbrace{\frac{\partial}{\partial s_{q,i}} \left(\exp(s_{p,i})\right)}_{0 \text{ car } p \neq q} \sum_{p'=1}^K \exp(s_{p',i}) - \exp(s_{p,i}) \exp(s_{q,i})}{\left(\sum_{p'=1}^K \exp(s_{p',i})\right)^2}\\ &= \frac{0 - \exp{s_{p,i} \exp{s_{q,i}}}}{(\sum_{p'=1}^K \exp(s_{p',i}))^2}\\ &= -\underbrace{\frac{\exp(s_{p,i})}{\sum_{p'=1}^K \exp(s_{p',i})}}_\text{softmax de $s_{p,i}$} \cdot \underbrace{\frac{\exp(s_{q,i})}{\S}}_\text{softmax de $s_{q,i}$}\\ &= - \hat{y_{p, i}} \; \hat{y_{q, i}} \end{align}\]

Cas général

Notons \(\delta_{p,q}\) le delta de Kroneker qui vaut 1 si \(p=q\) et 0 sinon :

\[\delta_{p,q} = \begin{cases} 1 ~~~p = q \\ 0 ~~~p \neq q \end{cases}\]

En combinant les deux cas précédents, il vient finalement :

\[\frac{\partial \hat{y_{p,i}}}{\partial s_{q,i}} = \hat{y}_{p,i} (\delta_{p,q} - \hat{y}_{q,i})\]

Le gradient qui nous intéresse \(\nabla_\mathbf{s_i} l_\text{CE}\) s’obtient finalement par le produit du gradient \(\nabla_\mathbf{\hat{y}_i} l_\text{CE}\) calculé à l’étape 1 et de la matrice jacobienne calculé à l’étape 2.

On rappelle que le gradient vaut :

\[\nabla_\mathbf{\hat{y}_i} l_\text{CE} = \left(0, 0, \dots, \underbrace{\frac{-1}{\hat{y}_{c^*, i}}}_{c^*}, \dots, 0 \right)^T\]

et que la matrice jacobienne calculée précédemment s’écrit :

\[J_\mathbf{\hat{y}_i}(\mathbf{s}_i) = \begin{pmatrix}{ \dfrac {\partial \hat{y}_{1,i}}{\partial s_{1, i}}} & \cdots &{\dfrac {\partial \hat{y}_{1, i}}{\partial s_{k, i}}}\\ \vdots & \ddots & \vdots \\ {\dfrac {\partial \hat{y}_{k, i}}{\partial s_{1, i}}} & \cdots & {\dfrac {\partial y_{k, i}}{\partial s_{k, i}}} \end{pmatrix} = \begin{pmatrix}{ \hat{y}_{1,i} (1 - \hat{y}_{1,i})} & \cdots & {- \hat{y}_{1,i} \hat{y}_{k,i}}\\ \vdots & \ddots & \vdots \\ {- \hat{y}_{k,i} \hat{y}_{1,i}} & \cdots & {\hat{y}_{k,i} (1 - \hat{y}_{k,i})} \end{pmatrix}\]

Le gradient par rapport aux activations \(\mathbf{s_i}\) s’écrit donc :

\[\nabla_\mathbf{s_i} l_\text{CE} = J_\mathbf{\hat{y}_i}(\mathbf{s}_i) \nabla_\mathbf{\hat{y}_i} l_\text{CE} = \begin{pmatrix}{ \hat{y}_{1,i} (1 - \hat{y}_{1,i})} & \cdots & {- \hat{y}_{1,i} \hat{y}_{k,i}}\\ \vdots & \ddots & \vdots \\ {- \hat{y}_{k,i} \hat{y}_{1,i}} & \cdots & {\hat{y}_{k,i} (1 - \hat{y}_{k,i})} \end{pmatrix} \begin{pmatrix} 0\\ \vdots\\ \frac{-1}{\hat{y}_{c^*, i}}\\ \vdots\\ 0 \end{pmatrix}\]

Comme toutes les composantes du vecteur sont nulles, sauf la \(c^*\)-ième, cela revient à sélectionner la colonne d’indice \(c^*\) de la matrice jacobienne :

\[\nabla_\mathbf{s_i} l_\text{CE} = \frac{-1}{\hat{y}_{c^*, i}} \begin{pmatrix} \hat{y}_{1, i} \hat{y}_{c^*, i}\\ \vdots\\ \hat{y}_{c^*, i} (1 - \hat{y}_{c^*, i})\\ \vdots\\ \hat{y}_{k, i} \hat{y}_{c^*, i} \end{pmatrix} = - \begin{pmatrix} \hat{y}_{1, i}\\ \vdots\\ 1 - \hat{y}_{c^*, i}\\ \vdots\\ \hat{y}_{k, i} \end{pmatrix} = - \underbrace{\begin{pmatrix} \hat{y}_{1, i}\\ \vdots\\ \hat{y}_{c^*, i}\\ \vdots\\ \hat{y}_{k, i} \end{pmatrix}}_{\mathbf{\hat{y}_i}} + \underbrace{ \begin{pmatrix} 0\\ \vdots\\ 1\\ \vdots\\ 0 \end{pmatrix}}_{\mathbf{y_i}^*} = \mathbf{y_i}^* - \mathbf{\hat{y}_i}\]

On note cette quantité \(\delta_i = \mathbf{y_i}^* - \mathbf{\hat{y}_i}\).

Étape 3 : \(\frac{\partial \mathbf{s_i}}{\partial \mathbf{W}}\)

Par chain rule toujours, il nous suffit d’avoir la matrice jacobienne de dimension \((K, LK)\)\(L \times K\) est le nombre de paramètres de la matrice \(W\) de la couche cachée :

\[\frac{\partial \mathbf{s_i}}{\partial W} = \begin{pmatrix} \frac{\partial s_{i,1}}{\partial W_{1,1}} & \cdots & \frac{\partial s_{i,1}}{\partial W_{L,K}}\\ \vdots & \ddots & \vdots\\ \frac{\partial s_{i,K}}{\partial W_{1,1}} & \cdots & \frac{\partial s_{i,K}}{\partial W_{L,K}}\\ \end{pmatrix}\]
\[\frac{\partial s_{i,m}}{\partial W_{n,o}} = \frac{\partial}{\partial W_{n,o}} \left( h_i \underbrace{W_{.,m}}_{\text{colonne}~m} + b_{m}\right) = \frac{\partial}{\partial W_{n,o}} \left(\sum_{p=1}^L h_{i,p} W_{p,m} + b_{m}\right) = \begin{cases} h_{i,n} & \text{si}~o = m\\ 0 & \text{sinon}\\ \end{cases}\]

Étape 4 : tout ensemble

\[\frac{\partial l_i}{\partial W} = \begin{pmatrix} \frac{\partial l_i}{\partial W_{1, 1}} & \cdots & \frac{\partial l_i}{\partial W_{1, K}}\\ \vdots & \ddots & \vdots\\ \frac{\partial l_i}{\partial W_{L, 1}} & \cdots & \frac{\partial l_i}{\partial W_{L, K}}\\ \end{pmatrix}\]

Par chain rule :

\[\frac{\partial l_i}{\partial W_{l,k}} = \frac{\partial{l_i}}{\partial \mathbf{s_{i}}_{,k'}} \frac{\partial \mathbf{s_{i}}_{,k'}}{\partial W_{l,k}} = (\mathbf{y_i}_{,k'}^* - \mathbf{y_i}_{,k'}) \frac{\partial \mathbf{s_i}_{,k'}}{\partial W_{l,k}} = \begin{cases} (\mathbf{y_i}_{,k}^* - \mathbf{y_i}_{,k}) h_{i,l} & \text{si } k = k'\\ 0 & \text{sinon} \end{cases}\]

Donc :

\[\frac{\partial l_i}{\partial W} = \begin{pmatrix} \delta_{i,1} h_{i,1} & \cdots & \delta_{i,K} h_{i,1}\\ \vdots & \ddots & \vdots\\ \delta_{i,1} h_{i,L} & \cdots & \delta_{i,K} h_{i,L}\\ \end{pmatrix} = \delta_i h_i^T = \begin{pmatrix} \mathbf{y_i}_{,1}^* - \mathbf{y_i}_{,1}\\ \vdots\\ \mathbf{y_i}_{,K}^* - \mathbf{y_i}_{,K}\\ \end{pmatrix} \begin{pmatrix} \delta_{i,1} h_{i,1} & \cdots & \delta_{i,K} h_{i,L}\\ \end{pmatrix}\]

Sur un batch de \(B\) examples, l’équation se réécrit :

\[\frac{\partial l}{\partial W} = \frac{1}{N} \sum_{i=1}^N \frac{\partial l_i}{\partial W} = \frac{1}{N} \sum_{i=1}^N \delta_i h_i^T \]

ou encore, matriciellement :

\[\frac{\partial l}{\partial W} = \frac{1}{N} H^T \Delta \]

Étape 5 :

Dans le cas de la régression logistique, \(x = h\) et on s’arrête là. Pour un perceptron multi-couche à une couche cachée, il faut encore calculer les gradients pour la couche d’entrée. On note \(h = \sigma(u)\) et \(u = W^h x + b^h\), où \(\sigma\) est la fonction sigmoïde \(x \rightarrow \frac{1}{1+ e^{-x}}\).

\[\frac{\partial L}{\partial W^h} = \frac{1}{N} \sum_{i=1} \underbrace{\frac{\partial l_i}{\partial y_i} \frac{\partial y_i}{\partial s_i}}_{\delta_i} \frac{\partial s_i}{\partial h_i} \frac{\partial h_i}{\partial u_i} \frac{\partial u_i}{\partial W^h} \]

En décomposant, il nous reste à calculer :

\[\frac{\partial s_i}{\partial h_i} = \frac{\partial}{\partial h_i} \left (h_i W + b \right) = W^T % TODO: à redémontrer \]

et :

\[\begin{align} \frac{\partial h_i}{\partial u_i} = \frac{\partial}{\partial u_i} \sigma(u_i) &= \begin{pmatrix} \frac{\partial \sigma(u_{i,1})}{\partial u_{i,1}} & \cdots & \frac{\partial \sigma(u_{i,1})}{\partial u_{i,L}}\\ \vdots & \ddots & \vdots\\ \frac{\partial \sigma(u_{i,L})}{\partial u_{i,1}} & \cdots & \frac{\partial \sigma(u_{i,L})}{\partial u_{i,L}} \end{pmatrix} = \begin{pmatrix} \frac{\partial \sigma(u_{i,1})}{\partial u_{i,1}} & \cdots & 0\\ \vdots & \ddots & \vdots\\ 0 & \cdots & \frac{\partial \sigma(u_{i,L})}{\partial u_{i,L}} \end{pmatrix} \\ &= \text{diag}_k \left( \frac{\partial \sigma(u_{i,k})}{\partial u_{i,k}} \right) = \text{diag}_k \left(\sigma(u_{i,k}) \cdot (1 - \sigma(u_{i,k}) \right) % TODO: à vérifier + détailler \end{align} \]

En effet, la dérivée de la fonction sigmoïde est :

\[\begin{align} \sigma'(x) &= \left(\frac{1}{1+ e^{-x}}\right)' = - \frac{(1 + e^{-x})'}{(1 + e^{-x})^2} = - \frac{- e^{-x}}{(1 + e^{-x})^2} = \underbrace{\frac{1}{1 + e^{-x}}}_\text{sigmoïde} \cdot \frac{e^{-x}}{1 + e^{-x}}\\ &= \sigma(x) \left(\frac{1 + e^{-x} - 1}{1 + e^{-x}} \right) = \sigma(x)\left(\underbrace{\frac{1 + e^{-x}}{1 + e^{-x}}}_{1} - \underbrace{\frac{1}{1 + e^{-x}}}_\text{sigmoïde}\right)\\ &= \sigma(x) \left(1 - \sigma(x)\right) \end{align} \]

Finalement, on peut calculer le gradient par rapport à \(W^h\) :

\[\frac{\partial l_i}{\partial W^h} = \frac{\partial l_i}{\partial u_i} \frac{\partial u_i}{\partial W^h} = x_i^T \delta_i W^T \odot \sigma(u_i) \odot (1 - \sigma(u_i)) % TODO: finaliser \]