Dans ce chapitre, nous allons comprendre les limitations d’un neurone formel, et comment les lever en mettant les neurones en réseau. Ensuite nous allons voir comment utiliser un réseau en couches.
Limitation du neurone formel
Nous avons vu comment on peut utiliser un modèle avec un simple neurone et l'appliquer à une tâche de classification.
Cependant, un seul neurone ne permet pas de répondre à des problèmes complexes.
Mettez plusieurs neurones en réseau
Pour résoudre des problèmes complexes, les neurones biologiques communiquent aussi entre eux via les synapses, et forment un réseau. Nous pouvons associer les neurones formels de la même manière, en affectant la sortie d'un neurone à une ou plusieurs entrées d'autres neurones.
Voici une topologie quelconque de réseaux. Chaque nœud rouge représente un neurone.
On utilise le plus souvent des réseaux particuliers organisés en couches :
L'influx d'information va toujours des couches d'entrées aux couches de sorties. Ces réseaux peuvent être appris par descente de gradient. Ils sont adaptés aux données de tailles fixes, comme des images. Ils portent le nom de perceptron multicouche (PMC), Feed-Forward ou Multi Layer Perceptron (MLP) en anglais.
Son apprentissage n'est pas aisé. Nous nous concentrerons d'abord sur les réseaux multicouches. Les réseaux récurrents feront l'objet d'une partie propre dans ce SPOC.
Organisation en une couche
Construisons tout d'abord un réseau à une seule couche.
Ici, nous avons mis 2 neurones en parallèle. Les sorties de chaque neurone sont concaténées pour former un vecteur . Les entrées sont toujours un vecteur . Le calcul de la sortie se fait par les équations :
\begin{eqnarray*}
S_j &=& \sum_i W_{ji} \vx_i\\
\vy_j &=& f(S_j)
\end{eqnarray*}
où représente la pondération entre l'entrée et la sortie . On a remplacé le biais à l'aide d'une fausse entrée qui reste constante à la valeur 1. Ainsi, correspond au biais du neurone . forme une matrice contenant les paramètres de la couche.
Comment apprendre un réseau à une seule couche ?
On applique une descente de gradient avec comme déplacement :
\begin{eqnarray*}
\frac{\partial L}{\partial \vw_{ji}}&=&\frac{\partial L}{\partial \vy_j}\frac{\partial \vy_j}{\partial S_j}\frac{\partial S_j}{\partial \vw_{ji}}\\
\frac{\partial L}{\partial \vw_{ji}}&=& \frac{\partial L}{\partial \vy_j} f' (S_j) \vx_i\\
\end{eqnarray*}
Organisation en plusieurs couches
Tout d'abord, nous reprenons l'organisation précédente ; seulement, nous remplaçons l'entrée par une entrée quelconque , et la sortie par une sortie quelconque . Dans la figure suivante, représente le numéro de la couche sur laquelle on se trouve :
Comment allons-nous faire pour construire un réseau multicouche ?
Prenons un exemple : nous allons construire un réseau à deux couches, contenant 3 neurones sur la première couche et 2 neurones sur la deuxième. On connecte la sortie de la première couche à l'entrée de la deuxième couche :
$$I^{(2)} \leftarrow O^{(1)} $$
En outre, pour la première couche, on aura l'entrée égale aux caractéristiques . Et pour la dernière couche, la sortie représente l'estimation de la cible :
$$I^{(1)} \leftarrow \vx $$
$$\hat{\vy} \leftarrow O^{(2)} $$
Voici le réseau final :
Les équations en phase de décision pour une couche restent les mêmes. L'entrée est simplement remplacée par la sortie de la couche précédente. Et la sortie de la couche est reliée à l'entrée de la couche suivante. Formellement, cela s'écrit ainsi :
\begin{eqnarray*}
S_j^{(l)} &=& \sum_i W_{ji}^{(l)} I_i^{(l)}\\
O_j^{(l)} &=& f^{(l)}(S_j^{(l)}) \rightarrow I^{(l+1)}
\end{eqnarray*}
où est le numéro de couche.
Rétropropagation du gradient
Pour l'apprentissage, c'est un peu plus compliqué.
Pour cela, nous allons commencer par calculer le gradient des paramètres de la dernière couche, puis propager le gradient vers les entrées de la dernière couche (ce qui correspond au gradient de la sortie de la couche précédente). Ainsi, on peut calculer le gradient des paramètres de l'avant-dernière couche, puis le gradient de son entrée. Et ainsi de suite, couche à couche, de la dernière à la première. C'est ce qu'on appelle la rétropropagation du gradient.
Regardons ce qui se passe plus en détail sur une couche . On suppose que l'on connaît le gradient de la perte par rapport à la sortie de la couche .
Les gradients de la perte par rapport aux paramètres de la couche sont alors donnés par :
\begin{eqnarray*}
\frac{\partial L}{\partial \vw_{ji}^{(l)}}&=&\frac{\partial L}{\partial O_j^{(l)}}\frac{\partial O_j^{(l)}}{\partial S_j^{(l)}}\frac{\partial S_j^{(l)}}{\partial \vw_{ji}^{(l)}}\\
\frac{\partial L}{\partial \vw_{ji}^{(l)}}&=& \frac{\partial L}{\partial O_j^{(l)}} f'^{(l)} (S_j^{(l)}) I_i^{(l)}\\
\end{eqnarray*}
On calcule ensuite les gradients de la perte par rapport aux entrées de la couche :
\begin{eqnarray*}
\frac{\partial L}{\partial I_i^{(l)}} &=&\sum_j \frac{\partial L}{\partial O_j^{(l)}} \frac{\partial O_j^{(l)}}{\partial I_i^{(l)}}\\
\frac{\partial L}{\partial I_i^{(l)}} &=&\sum_j \frac{\partial L}{\partial O_j^{(l)}} \frac{\partial O_j^{(l)}}{\partial S_j^{(l)}} \frac{\partial S_j^{(l)}}{\partial I_i^{(l)}}\\
\frac{\partial L}{\partial I_i^{(l)}} &=&\sum_j \frac{\partial L}{\partial O_j^{(l)}} f'^{(l)} (S_j^{(l)}) \vw_{ji}
\end{eqnarray*}
On voit que l'on somme plusieurs termes. En effet, il faut prendre en compte tous les chemins entre l'entrée et toutes les sorties possibles.
C'est une étape de l'algorithme de rétropropagation du gradient, que l'on répète jusqu'aux entrées du réseau. La récursion se passe ainsi :
on commence par calculer le gradient des sorties de la dernière couche :
$$\frac{\partial L}{\partial O_j^{(last)}} \leftarrow \frac{\partial L}{\partial \hat{\vy}_j}$$on itère le calcul des gradients sur les couches, en partant de la fin. Le gradient de l'entrée de la couche $(l)$ étant utilisé comme gradient de la sortie de la couche précédente :
$$\frac{\partial L}{\partial O_j^{(l-1)}} \leftarrow \frac{\partial L}{\partial I_i^{(l)}}$$
Illustration sur un jeu de données non linéairement séparable
Maintenant, on peut résoudre un problème non linéairement séparable :
Nous avons construit un réseau contenant 3 neurones sur une première couche, et 2 neurones sur une seconde couche (comme dans l'exemple de la précédente section). Grâce à l'apport du multicouche, on peut maintenant séparer ces exemples en deux groupes :
Voici l'évolution de la fonction de décision au cours de l'apprentissage :
Cliquez ici pour visualiser l'animation de l'apprentissage du PMC sur l'exemple XOR.
Allez plus loin :
Article sur les réseaux de neurones artificiels.
Friedman, J., Hastie, T., & Tibshirani, R. (2001). The elements of statistical learning (Vol. 1, No. 10). New York, NY, USA: Springer series in statistics.
En résumé
Dans ce chapitre, nous avons vu qu'un neurone isolé ne peut pas résoudre de problème non-linéairement séparable. Il faut pour cela regrouper plusieurs neurones entre eux dans un réseau de neurones artificiels. Nous avons différents types de réseaux possibles, et nous nous sommes attardés sur les réseaux de neurones en couches dits perceptrons multicouches. Ce type de réseau s'apprend par un algorithme particulier, la rétropropagation du gradient.