6. Réseaux de neurones multi-couches

Une seule unité linéaire ne trace qu'une frontière droite. Empiler de nombreuses unités simples avec une non-linéarité entre elles donne un réseau de neurones multi-couches, qui ajuste des frontières courbes et apprend ses propres caractéristiques. Ce module construit ce modèle en douceur : prendre la régression logistique du module précédent, la dessiner comme un graphe, et la rendre profonde, une étape à la fois. La recette est celle de chaque module : un modèle (des couches, exécutées par la propagation avant), une fonction de perte adaptée à la tâche, et la descente de gradient, désormais propulsée par la rétropropagation. L'histoire continue ensuite comme la pratique l'a imposé : les gradients disparaissent dans les piles profondes, de meilleures activations les raniment, les bonnes pratiques stabilisent l'entraînement, et la descente de gradient elle-même reçoit une amélioration. Ce module est la porte d'entrée du cours de Deep Learning, qui développe en profondeur chaque sujet abordé ici.

6.1 Linéaire contre non linéaire

Les classifieurs linéaires du module de classification linéaire séparent les classes par une seule frontière droite, si bien qu'un problème comme XOR, non linéairement séparable, est hors de portée. Courber la frontière demande quelque chose de non linéaire, et toute la question est de savoir d'où vient la non-linéarité. Régression linéaire y a déjà répondu une première fois, avec des fonctions de base \(\phi\) fixées à la main avant l'entraînement. Les réseaux y répondent autrement : ils apprennent eux-mêmes les caractéristiques. La section suivante construit cette machine à partir d'un modèle déjà connu.

6.2 Rendre la régression logistique profonde

6.2.1 La régression logistique comme réseau

Classification linéaire s'est terminée sur la régression logistique : un produit scalaire avec les poids \(w\) et une sigmoïde qui écrase le score en probabilité,

\[\boxed{ \hat{y} = \sigma(w^T x) }\]

avec la convention habituelle du cours : \(x\) est augmenté d'une constante \(x_0 = 1\), si bien que le poids \(w_0\) est le biais. Dessiné comme un graphe, c'est déjà un réseau, le plus petit possible. La couche d'entrée contient \(x\), constante comprise, et ne calcule rien. Un seul neurone de sortie fait tout le travail : multiplier par les poids, appliquer l'activation. Chaque neurone de ce module est exactement cette unité.

La régression logistique dessinée comme un réseau

Chaque arête porte un poids et le neurone applique \(\sigma\) à la somme pondérée. Le neurone fixé à \(1\) porte le biais : son poids est \(w_0\).

Remarque : le biais reste replié dans les poids tout au long de ce module, dessiné comme un neurone constant. Le cours de Deep Learning garde au contraire un vecteur de biais explicite \(b^{[l]}\), et signale ce changement de convention au moment de l'introduire.

6.2.2 Insérer une couche cachée

Rien n'oblige le neurone de sortie à lire l'entrée brute. Insérons quelques neurones entre l'entrée et la sortie, disons trois. Chacun est la même unité à produit scalaire que toujours, avec ses propres poids \(w_i\) et une activation non linéaire \(g\) :

\[a_i = g(w_i^T x), \qquad i = 1, 2, 3\]

Empilons les trois vecteurs de poids \(w_i^T\) comme lignes d'une matrice \(W^{[1]}\), et toute la couche tient en une ligne, \(a = g(W^{[1]} x)\). L'exposant entre crochets \([1]\) est nouveau, et il existe pour une raison prosaïque : le modèle a maintenant deux jeux de poids, chacun a donc besoin d'un nom. \([l]\) dit simplement à quelle couche un symbole appartient.

Le neurone de sortie n'a pas changé du tout. C'est toujours la régression logistique de la section 6.2.1, il lit simplement les trois valeurs apprises \(a\), augmentées d'une constante \(a_0 = 1\) (chaque couche reçoit un neurone de biais, exactement comme l'entrée), au lieu de l'entrée brute :

\[\boxed{ \hat{y} = \sigma\!\left(w^{[2]T} a\right) = \sigma\!\left(w^{[2]T}\, g(W^{[1]} x)\right) }\]

Prendre la régression logistique et insérer une couche cachée

Le neurone de sortie orange est identique dans les deux dessins. Rendre le modèle profond a changé ce qu'il lit : trois caractéristiques apprises \(a\) au lieu du \(x\) brut. Chaque couche porte son propre neurone constant \(1\), dont les poids sortants sont les biais.

Deux faits sur cette insertion portent toute l'histoire.

L'activation cachée doit être non linéaire. Si \(g\) était l'identité, les deux couches se réduiraient à une seule application linéaire,

\[\boxed{ W^{[2]}\!\left(W^{[1]} x\right) = W' x }\]

et la profondeur n'apporterait rien. C'est la non-linéarité qui rend l'empilement utile, et c'est elle qui met désormais XOR à portée.

La couche cachée apprend les caractéristiques. Le neurone de sortie reste un classifieur linéaire, le travail de la couche cachée est donc de déplacer les données là où les classes deviennent linéairement séparables. Elle joue exactement le rôle des fonctions de base \(\phi\) de Régression linéaire, avec une amélioration : \(\phi\) était fixée à la main avant l'entraînement, tandis que \(a\) est apprise des données, de bout en bout.

6.2.3 Comment faire une prédiction ?

Une couche cachée a fonctionné, alors répétons le geste : le vecteur \(a^{[1]}\) peut alimenter une deuxième couche cachée, dont la sortie \(a^{[2]}\) peut en alimenter une troisième, jusqu'à une couche de sortie qui produit \(\hat{y}\). La couche \(l\) possède sa matrice de poids \(W^{[l]}\) (une ligne par neurone, la couche de sortie ci-dessus avait donc l'unique ligne \(w^{[2]T}\)) et son activation \(g^{[l]}\). La largeur et la profondeur sont les boutons de capacité : plus d'unités et plus de couches donnent plus de paramètres et des frontières plus expressives, et, comme Concepts généraux l'a prévenu, plus de place pour surapprendre.

Couches d'entrée, cachées et de sortie

Chaque arête porte un poids de \(W^{[l]}\). Les neurones de biais constants ne sont pas dessinés.

Calculer la prédiction en lisant le réseau de gauche à droite s'appelle la propagation avant, et la formule générale ne fait que redire ce que les deux dernières sections ont construit, une fois par couche :

\[\boxed{ z^{[l]} = W^{[l]} a^{[l-1]}, \quad a^{[l]} = g^{[l]}\!\left(z^{[l]}\right), \quad a^{[0]} = x, \quad \hat{y} = a^{[L]} }\]

avec une convention à retenir : chaque \(a^{[l]}\), comme l'entrée, se lit avec son neurone de biais \(a^{[l]}_0 = 1\) ajouté en tête. Sous forme vectorisée, tout le mini-lot circule d'un coup, une opération matricielle par couche avec les exemples en colonnes, ce qui est à la fois plus clair et bien plus rapide :

\[\boxed{ Z^{[l]} = W^{[l]} A^{[l-1]} }\]

La propagation avant est la première moitié de chaque pas d'entraînement. La seconde moitié, la rétropropagation, parcourt le même câblage en sens inverse (section 6.4).

6.2.4 La formule sur le graphe

Chaque symbole de la formule de propagation avant vit quelque part sur le dessin du réseau. La figure ci-dessous les place un à un sur le plus petit réseau intéressant, deux entrées, une couche cachée de deux unités et une sortie :

Chaque terme de la propagation avant placé sur le réseau

À gauche : l'exposant \([l]\) nomme la couche, chaque arête porte un poids \(w^{[l]}_{ij}\), et les neurones fixés à \(1\) portent les biais \(w^{[l]}_{i0}\). À droite : à l'intérieur d'une unité, la somme pondérée donne \(z^{[l]}_i\), puis l'activation \(g\) la transforme en \(a^{[l]}_i\).

Symbole Nom Où il vit sur le graphe
\(l\), \(L\) indice de couche, nombre de couches la colonne d'unités (\(l = 0\) est l'entrée, ici \(L = 2\))
\(x = a^{[0]}\) l'entrée la colonne la plus à gauche
\(w^{[l]}_{ij}\) un poids le nombre porté par une arête : vers l'unité \(i\) de la couche \(l\), depuis l'unité \(j\) de la couche \(l-1\)
\(W^{[l]}\) la matrice de poids de la couche \(l\) toutes les arêtes qui arrivent dans la couche \(l\), une ligne par unité
\(x_0\), \(a^{[l]}_0\) le neurone de biais une unité fixée à \(1\) dans chaque couche, dont le poids sortant \(w^{[l]}_{i0}\) est le biais de l'unité \(i\)
\(z^{[l]}_i\) la pré-activation la somme pondérée que l'unité calcule avant d'appliquer \(g\)
\(g^{[l]}\) la fonction d'activation appliquée à l'intérieur de chaque unité de la couche \(l\)
\(a^{[l]}_i\) l'activation la valeur que l'unité envoie sur ses arêtes sortantes
\(\hat{y} = a^{[L]}\) la prédiction ce qui sort de la dernière couche

Faisons maintenant tourner ce réseau exact avec des nombres. Prenons \(x = (1, 2)\), augmenté en \((1, 1, 2)\) par le neurone de biais \(x_0 = 1\), la sigmoïde du module précédent comme activation partout, avec

\[W^{[1]} = \begin{pmatrix} 0 & 2 & -1 \\ -1 & 1 & 1 \end{pmatrix}, \qquad W^{[2]} = \begin{pmatrix} 0 & 1 & 1 \end{pmatrix}\]

La ligne \(i\) de \(W^{[1]}\) rassemble les poids des arêtes qui arrivent dans l'unité cachée \(i\), biais en tête. Couche 1, unité par unité :

\[z^{[1]}_1 = \underbrace{0}_{w^{[1]}_{10}} \cdot \underbrace{1}_{x_0} + \underbrace{2}_{w^{[1]}_{11}} \cdot \underbrace{1}_{x_1} + \underbrace{(-1)}_{w^{[1]}_{12}} \cdot \underbrace{2}_{x_2} = 0, \qquad a^{[1]}_1 = \sigma(0) = 0{,}5\] \[z^{[1]}_2 = -1 \cdot 1 + 1 \cdot 1 + 1 \cdot 2 = 2, \qquad a^{[1]}_2 = \sigma(2) \approx 0{,}88\]

L'unité cachée 1 tombe exactement sur zéro, le point milieu de la sigmoïde, elle sort donc \(0{,}5\), tandis que l'unité 2 se place haut sur la courbe. La couche de sortie répète les deux mêmes étapes, en lisant cette fois \(a^{[1]} = (0{,}5,\ 0{,}88)\), augmenté en \((1,\ 0{,}5,\ 0{,}88)\) par son propre neurone de biais, au lieu de \(x\) :

\[z^{[2]} = 0 \cdot 1 + 1 \cdot 0{,}5 + 1 \cdot 0{,}88 = 1{,}38, \qquad \hat{y} = a^{[2]} = \sigma(1{,}38) \approx 0{,}80\]

Le réseau prédit la classe 1 avec une probabilité d'environ \(0{,}80\). C'est tout ce que fait la propagation avant : multiplier par les poids des arêtes, neurone de biais compris, appliquer l'activation, à chaque unité de chaque couche.

6.3 La fonction de perte

Le corps du réseau ignore la tâche. La tâche vit dans la dernière couche : son activation met en forme \(\hat{y}\), et la perte compare \(\hat{y}\) à l'étiquette, en réutilisant les pertes de Concepts généraux et de Classification linéaire :

Tâche Activation de sortie Fonction de perte
régression identité erreur quadratique
classification binaire sigmoïde entropie croisée binaire
classification multiclasse softmax entropie croisée catégorielle
\[\boxed{ \hat{y} = \frac{1}{1 + e^{-z}} \quad\text{(binaire)} \qquad \hat{y}_c = \frac{e^{z_c}}{\sum_{j} e^{z_j}} \quad\text{(multiclasse)} }\]

Remarque : ce sont exactement les têtes de neurone de Classification linéaire. Un réseau est cette même tête posée sur des caractéristiques apprises plutôt que sur les entrées brutes.

6.4 Comment optimiser les paramètres ?

Rien de nouveau ici non plus : entraîner un réseau suit les mêmes étapes que chaque modèle de ce cours, alors parcourons-les dans l'ordre.

Étape 0 : poser l'objectif. Chercher les poids qui minimisent la perte plus un régulariseur qui les garde petits, la recette du maximum a posteriori de Régression linéaire :

\[\boxed{ W^\star = \arg\min_W \; L(W) + \lambda\, R(W), \qquad R(W) = \lVert W \rVert_1 \;\text{ ou }\; \lVert W \rVert_2^2 }\]

Étape 1 : choisir la perte. C'est la section 6.3, et son tableau porte l'avertissement qui va avec : la perte et l'activation de sortie se choisissent en paire. L'entropie croisée appelle une softmax (ou une sigmoïde), l'erreur quadratique une sortie identité.

Étape 2 : descendre le gradient. Mettre à jour chaque poids d'un petit pas contre son gradient, avec le taux d'apprentissage \(\alpha\), exactement la descente de gradient de Classification linéaire :

\[\boxed{ w^{[l]}_{ij} \leftarrow w^{[l]}_{ij} - \alpha\, \frac{\partial \left(L + \lambda R\right)}{\partial w^{[l]}_{ij}} }\]

Étape 3 : obtenir le gradient par rétropropagation. La pièce vraiment nouvelle est le calcul de ce gradient pour chaque poids d'une pile de couches. La rétropropagation y parvient avec la règle de dérivation en chaîne, en une passe avant et une passe arrière : la propagation avant met en cache chaque \(z^{[l]}\) et \(a^{[l]}\), puis la passe arrière propage le gradient de la perte couche par couche, de la sortie jusqu'à la première couche, en réutilisant le cache. Avec l'erreur de couche \(\delta^{[l]} = \partial L / \partial z^{[l]}\),

\[\boxed{ \delta^{[l]} = \left((W^{[l+1]})^T \delta^{[l+1]}\right) \odot g'^{[l]}\!\left(z^{[l]}\right), \qquad \frac{\partial L}{\partial W^{[l]}} = \delta^{[l]} (a^{[l-1]})^T }\]

Les neurones de biais s'intègrent gratuitement : constants, ils ne reçoivent aucune erreur (leur ligne de \((W^{[l+1]})^T \delta^{[l+1]}\) est simplement abandonnée), et comme \(a^{[l-1]}\) contient la constante \(1\), le même produit extérieur livre les gradients des biais avec le reste.

Passes avant et arrière

La propagation avant calcule et met en cache les activations, la rétropropagation renvoie le gradient de la perte par les mêmes arêtes. La leçon Rétropropagation du cours de Deep Learning la dérive pas à pas.

Exemple complet : un pas de descente de gradient sur le petit réseau

Reprenons le réseau de la section 6.2.4 exactement où la propagation avant l'a laissé : \(\bar{x} = (1, 1, 2)\), \(a^{[1]} = (0{,}5,\ 0{,}88)\), \(\hat{y} = 0{,}80\), et donnons une étiquette à l'exemple : la vraie classe est \(y = 0\). Prenons l'entropie croisée binaire de la section 6.3 sans régularisation (\(\lambda = 0\)), la perte vaut donc

\[L = -\ln(1 - \hat{y}) = -\ln(0{,}20) \approx 1{,}61\]

Le réseau se trompe avec assurance, et le gradient va le lui dire.

En arrière à travers la couche de sortie. Pour une sortie sigmoïde entraînée avec l'entropie croisée, l'erreur de sortie se réduit au familier \(\hat{y} - y\) de Classification linéaire :

\[\delta^{[2]} = \hat{y} - y = 0{,}80\]

Chaque poids de \(W^{[2]}\) reçoit \(\delta^{[2]}\) fois l'activation qu'il lit (la formule du produit extérieur, neurone de biais compris) :

\[\frac{\partial L}{\partial W^{[2]}} = \delta^{[2]} \left(\bar{a}^{[1]}\right)^T = 0{,}80 \cdot (1,\ 0{,}5,\ 0{,}88) = (0{,}80,\ 0{,}40,\ 0{,}70)\]

En arrière à travers la couche cachée. Chaque unité cachée prend sa part de l'erreur à travers son poids sortant, fois sa propre pente \(\sigma'(z) = \sigma(z)(1 - \sigma(z))\) :

\[\delta^{[1]}_1 = w^{[2]}_{11}\, \delta^{[2]}\, \sigma'(0) = 1 \cdot 0{,}80 \cdot 0{,}25 = 0{,}20, \qquad \delta^{[1]}_2 = 1 \cdot 0{,}80 \cdot 0{,}10 = 0{,}08\]

(le neurone de biais constant ne prend aucune erreur, et notez la petite pente \(0{,}10\) de l'unité 2 : la section 6.5 y reviendra). Puis le même produit extérieur contre \(\bar{x} = (1, 1, 2)\) :

\[\frac{\partial L}{\partial W^{[1]}} = \delta^{[1]}\, \bar{x}^T = \begin{pmatrix} 0{,}20 & 0{,}20 & 0{,}40 \\ 0{,}08 & 0{,}08 & 0{,}16 \end{pmatrix}\]

La mise à jour. L'étape 2 avec un \(\alpha = 1\) volontairement grand, pour rendre le mouvement visible :

\[W^{[2]} \leftarrow (0,\ 1,\ 1) - (0{,}80,\ 0{,}40,\ 0{,}70) = (-0{,}80,\ 0{,}60,\ 0{,}30)\] \[W^{[1]} \leftarrow \begin{pmatrix} 0 & 2 & -1 \\ -1 & 1 & 1 \end{pmatrix} - \begin{pmatrix} 0{,}20 & 0{,}20 & 0{,}40 \\ 0{,}08 & 0{,}08 & 0{,}16 \end{pmatrix} = \begin{pmatrix} -0{,}20 & 1{,}80 & -1{,}40 \\ -1{,}08 & 0{,}92 & 0{,}84 \end{pmatrix}\]

Est-ce que ça a aidé ? Relançons la propagation avant avec les nouveaux poids : \(z^{[1]} = (-1{,}20,\ 1{,}52)\), \(a^{[1]} = (0{,}23,\ 0{,}82)\), \(z^{[2]} = -0{,}42\), et

\[\hat{y} = \sigma(-0{,}42) \approx 0{,}40, \qquad L = -\ln(1 - 0{,}40) \approx 0{,}51\]

Un seul pas, et la prédiction de la classe 1 est passée de \(0{,}80\) à \(0{,}40\), la perte de \(1{,}61\) à \(0{,}51\). L'entraînement, c'est cette boucle, répétée sur les mini-lots jusqu'à ce que la perte se stabilise.

6.5 La disparition du gradient

La formule de rétropropagation cache un piège. À chaque couche traversée, l'erreur \(\delta^{[l]}\) est multipliée par la pente locale \(g'(z^{[l]})\), si bien que le gradient qui atteint la couche 1 contient un tel facteur par couche. Avec des activations sigmoïdes, ces facteurs sont petits par construction :

\[\boxed{ \sigma'(z) = \sigma(z)\left(1 - \sigma(z)\right) \le \tfrac{1}{4} }\]

Le résultat est la disparition du gradient : les couches proches de la sortie apprennent, celles proches de l'entrée ne reçoivent presque rien et bougent à peine. Les réseaux sigmoïdes profonds stagnent, et le remède n'est pas un meilleur optimiseur, c'est une meilleure activation (section 6.6).

Preuve : le gradient rétrécit géométriquement avec la profondeur

Étape 1 : la pente de la sigmoïde ne dépasse jamais \(1/4\). Dérivons \(\sigma(z) = (1 + e^{-z})^{-1}\) avec la règle de dérivation en chaîne :

\[\sigma'(z) = \frac{e^{-z}}{\left(1 + e^{-z}\right)^2} = \frac{1}{1 + e^{-z}} \cdot \frac{e^{-z}}{1 + e^{-z}} = \sigma(z)\left(1 - \sigma(z)\right)\]

Posons \(s = \sigma(z) \in (0, 1)\). Le produit \(s(1 - s)\) est une parabole tournée vers le bas, maximale en \(s = \tfrac{1}{2}\) où elle vaut \(\tfrac{1}{4}\). La borne tient donc, avec égalité seulement en \(z = 0\), et la saturation aggrave tout : dans l'exemple détaillé de la section 6.2.4, l'unité cachée 2 se trouve à \(\sigma(2) \approx 0{,}88\), où la pente est déjà tombée à \(0{,}88 \cdot 0{,}12 \approx 0{,}10\).

Étape 2 : la rétropropagation multiplie ces pentes. Prenons le réseau profond le plus simple, une chaîne de \(L\) couches à une unité chacune, où chaque quantité est un scalaire. En appliquant la règle de dérivation en chaîne de la sortie vers la couche 1, chaque couche traversée apporte le facteur \(\partial z^{[l]} / \partial z^{[l-1]} = w^{[l]}\, \sigma'(z^{[l-1]})\) :

\[\frac{\partial L}{\partial z^{[1]}} = \frac{\partial L}{\partial z^{[L]}} \prod_{l=2}^{L} w^{[l]}\, \sigma'(z^{[l-1]})\]

Avec des poids de taille typique \(|w^{[l]}| \le 1\), chaque facteur vaut au plus \(\tfrac{1}{4}\) en valeur absolue, donc

\[\boxed{ \left|\frac{\partial L}{\partial z^{[1]}}\right| \le \left(\tfrac{1}{4}\right)^{L-1} \left|\frac{\partial L}{\partial z^{[L]}}\right| }\]

Dix couches rétrécissent déjà le gradient d'environ \(10^{-6}\). Le cas matriciel complet est la récursion de la section 6.4, avec la même conclusion. \(\blacksquare\)

Des poids bien plus grands que \(1\) ne font qu'échanger le problème contre son image miroir, l'explosion du gradient. La leçon Initialisation et disparition du gradient du cours de Deep Learning en donne le traitement complet.

6.6 Les fonctions d'activation

Alors, quelle activation choisir pour \(g\) ? Les candidates, dans l'ordre où l'histoire les a essayées :

\[\boxed{ \sigma(z) = \frac{1}{1 + e^{-z}}, \qquad \tanh(z), \qquad \mathrm{ReLU}(z) = \max(0, z) }\]

La sigmoïde sature dans ses deux queues, exactement ce que la section 6.5 vient de punir, et ses sorties ne sont jamais négatives, donc les poids entrants d'une unité reçoivent des gradients de même signe et les mises à jour zigzaguent. La \(\tanh\), centrée en zéro, supprime ce biais mais sature encore. ReLU garde une pente d'exactement \(1\) sur tout son côté positif, les facteurs rétrécissants de la section 6.5 disparaissent donc, et elle ne coûte presque rien à calculer. C'est pourquoi elle est aujourd'hui l'activation cachée par défaut.

Fonctions d'activation

La tanh est centrée en zéro alors que la sigmoïde ne l'est pas, et ReLU reste linéaire pour les entrées positives.

ReLU a un angle mort : une unité dont l'entrée reste négative sort \(0\), a une pente de \(0\) et cesse d'apprendre, une unité morte. Des variantes comme Leaky ReLU, \(\max(0{,}01\, z, z)\), et ELU gardent une petite pente du côté négatif pour l'éviter. En pratique : commencer avec ReLU, essayer ses variantes si des unités meurent, et réserver la sigmoïde là où la section 6.3 en a besoin, à la sortie d'un classifieur binaire. La leçon Fonctions d'activation du cours de Deep Learning les compare toutes.

6.7 Les bonnes pratiques

Cinq habitudes font la différence entre un réseau qui s'entraîne et un réseau qui stagne.

Entraîner par mini-lots. Classification linéaire offrait deux extrêmes, le lot complet ou un seul exemple par pas. Les réseaux s'entraînent par mini-lots, un petit lot par pas : un gradient assez précis pour progresser, un pas assez bon marché pour en faire des milliers, et la propagation avant vectorisée de la section 6.2.3 traite tout le mini-lot en un produit matriciel par couche.

Initialiser avec soin. Des poids tous égaux feraient calculer la même chose à chaque unité d'une couche pour toujours, on démarre donc petit et aléatoire pour briser la symétrie. L'échelle compte aussi : trop petit et les activations rétrécissent vers zéro couche après couche, trop grand et elles saturent. Mettre la variance à l'échelle du nombre d'entrées de l'unité, Xavier pour tanh, He pour ReLU.

Centrer et normaliser les entrées. Standardiser chaque caractéristique (soustraire sa moyenne, diviser par son écart-type), pour qu'aucune ne domine les premiers produits scalaires et que le zigzag des entrées toutes positives de la section 6.6 disparaisse dès la première couche.

Dropout. Mettre à zéro au hasard une fraction des unités pendant l'entraînement pour qu'aucune ne puisse s'appuyer sur ses voisines, un régulariseur dans l'esprit de Concepts généraux. En prédiction, toutes les unités restent actives et les sorties sont mises à l'échelle par la probabilité de conservation, ce qui approche la moyenne des nombreux réseaux amincis (Régularisation et dropout).

Vérifier avant d'entraîner longtemps. Un classifieur à \(K\) classes fraîchement initialisé doit démarrer près de la perte \(\ln K\) (environ \(2{,}3\) pour \(K = 10\)). Un minuscule jeu d'entraînement doit être facile à surapprendre : si le réseau n'y arrive pas, le code est cassé. Surveiller les courbes d'entraînement et de validation. Et comme la rétropropagation est source d'erreurs, comparer son gradient analytique à une estimation numérique par différences finies :

\[\boxed{ \frac{\partial L}{\partial w} \approx \frac{L(w + \varepsilon) - L(w - \varepsilon)}{2\varepsilon} }\]

6.8 La descente de gradient améliorée

La descente de gradient brute prend le pas le plus pentu et rien de plus, et trois paysages la mettent en échec : les plateaux, où la pente est presque nulle et le progrès s'arrête, les points de selle (fréquents en haute dimension), où le gradient est exactement nul sans être un minimum, et les ravins, pentus dans une direction et doux dans l'autre, où le pas oscille entre les parois en rampant le long du fond.

Le momentum traite la mise à jour comme une vitesse avec frottement : les gradients s'accumulent, les directions persistantes prennent de la vitesse, les directions oscillantes s'annulent :

\[\boxed{ v \leftarrow \rho\, v + \nabla_W L, \qquad W \leftarrow W - \alpha\, v }\]

avec un frottement \(\rho\) typiquement autour de \(0{,}9\).

RMSProp donne à chaque paramètre son propre pas, en divisant par une moyenne glissante de l'amplitude du gradient, ce qui tempère les directions pentues et accélère les plates :

\[\boxed{ m \leftarrow \beta\, m + (1 - \beta) \left(\nabla_W L\right)^2, \qquad W \leftarrow W - \frac{\alpha}{\sqrt{m} + \varepsilon}\, \nabla_W L }\]

Adam combine les deux idées, une vitesse pour la direction et une échelle par paramètre pour le pas (la version complète corrige aussi un biais de démarrage dans \(v\) et \(m\)), et c'est l'optimiseur par défaut en pratique :

\[\boxed{ v \leftarrow \beta_1 v + (1 - \beta_1)\, \nabla_W L, \qquad m \leftarrow \beta_2 m + (1 - \beta_2) \left(\nabla_W L\right)^2, \qquad W \leftarrow W - \alpha\, \frac{v}{\sqrt{m} + \varepsilon} }\]

Deux habitudes complètent le tableau : faire décroître le taux d'apprentissage au fil de l'entraînement, et se rappeler que ces trois méthodes consomment toujours les gradients par mini-lots de la section 6.7, elles ne font que mieux les dépenser. La leçon Optimisation du cours de Deep Learning les dérive une à une et ajoute les calendriers de taux d'apprentissage.

Ce module est la porte d'entrée du cours de Deep Learning, qui développe pleinement les architectures, les optimiseurs, l'initialisation, la normalisation et la régularisation. Le module suivant revient aux modèles linéaires sous un nouvel angle, le classifieur à marge maximale.


Suivant : Machines à vecteurs de support · Vue d'ensemble du cours