L'architecture typique d'un réseau de neurones convolutif
Maintenant que vous maîtrisez le fonctionnement des différents types de couches d'un réseau de neurones convolutif, nous allons apprendre à en construire un !
Un CNN est simplement un empilement de plusieurs couches de convolution, pooling, correction ReLU et fully-connected. Chaque image reçue en entrée va donc être filtrée, réduite et corrigée plusieurs fois, pour finalement former un vecteur. Dans le problème de classification, ce vecteur contient les probabilités d'appartenance aux classes.
Tous les réseaux de neurones convolutifs doivent commencer par une couche de convolution et finir par une couche fully-connected. Les couches intermédiaires peuvent s'empiler de différentes manières, à condition que la sortie d'une couche ait la même structure que l'entrée de la suivante. Par exemple, une couche fully-connected, qui renvoie toujours un vecteur, ne peut pas être placée avant une couche de pooling, puisque cette dernière doit recevoir une matrice 3D.
En général, un réseau de neurones empile plusieurs couches de convolution et de correction ReLU, ajoute ensuite une couche de pooling (facultative), et répète ce motif plusieurs fois ; puis, il empile des couches fully-connected.
Plus il y a de couches, plus le réseau de neurones est "profond" : on est en plein dans le Deep Learning !
Le paramétrage des couches
Un réseau de neurones convolutif se distingue d'un autre par la façon dont les couches sont empilées, mais également paramétrées.
Les couches de convolution et de pooling possèdent en effet des hyperparamètres, c'est-à-dire des paramètres dont vous devez préalablement définir la valeur.
La taille des feature maps en sortie des couches de convolution et de pooling dépend des hyperparamètres.
Chaque image (ou feature map) est de dimensions , où est sa largeur en pixels, sa hauteur en pixels et le nombre de canaux (1 pour une image en noir et blanc, 3 pour une image en couleurs).
La couche de convolution possède quatre hyperparamètres :
Le nombre de filtres
La taille des filtres : chaque filtre est de dimensions pixels.
Le pas avec lequel on fait glisser la fenêtre correspondant au filtre sur l'image. Par exemple, un pas de 1 signifie qu'on déplace la fenêtre d'un pixel à la fois
Le zero-padding : on ajoute à l'image en entrée de la couche un contour noir d'épaisseur pixels. Sans ce contour, les dimensions en sortie sont plus petites. Ainsi, plus on empile de couches de convolution avec , plus l'image en entrée du réseau rétrécit. On perd donc beaucoup d'informations rapidement, ce qui rend la tâche d'extraction de features difficile
Pour chaque image de taille en entrée, la couche de convolution renvoie une matrice de dimensions , où , et .
Choisir et permet ainsi d'obtenir des feature maps de même largeur et hauteur que celles reçues en entrée.
La couche de pooling présente seulement deux hyperparamètres :
La taille des cellules : l'image est découpée en cellules carrées de taille pixels
Le pas : les cellules sont séparées les unes des autres de pixels
Pour chaque image de taille en entrée, la couche de pooling renvoie une matrice de dimensions , où , et .
Tout comme l'empilement, le choix des hyperparamètres se fait selon un schéma classique :
Pour la couche de convolution, les filtres sont de petite taille et glissés sur l'image d'un pixel à la fois. La valeur du zero-padding est choisie de sorte que la largeur et la hauteur du volume en entrée ne soient pas modifiées en sortie. En général, on choisit alors ou
Pour la couche de pooling, et est un choix judicieux. Cela permet d'éliminer 75% des pixels en entrée. On peut également trouver et : dans ce cas, les cellules se chevauchent. Choisir des cellules de plus grande taille provoque une perte trop importante d'informations, et donne de moins bons résultats en pratique
Le Transfer Learning
Entraîner un réseau de neurones convolutif est très coûteux : plus les couches s'empilent, plus le nombre de convolutions et de paramètres à optimiser est élevé. L'ordinateur doit être en mesure de stocker plusieurs gigaoctets de données et de faire efficacement les calculs. C'est pourquoi les fabricants de matériel informatique multiplient les efforts pour fournir des processeurs graphiques (GPU) performants, capables d'entraîner rapidement un réseau de neurones profond en parallélisant les calculs.
Le Transfer Learning (ou apprentissage par transfert) permet de faire du Deep Learning sans avoir besoin d'y passer un mois de calculs. Le principe est d'utiliser les connaissances acquises par un réseau de neurones lors de la résolution d'un problème afin d'en résoudre un autre plus ou moins similaire. On réalise ainsi un transfert de connaissances, d'où le nom.
En plus d'accélérer l'entraînement du réseau, le Transfer Learning permet d'éviter le sur-apprentissage (overfitting). En effet, lorsque la collection d'images en entrée est petite, il est vivement déconseillé d'entraîner le réseau de neurones en partant de zéro (c'est-à-dire avec une initialisation aléatoire) : le nombre de paramètres à apprendre étant largement supérieur au nombre d'images, le risque d'overfitting est énorme !
Le Transfer Learning est une technique très utilisée en pratique et simple à mettre en œuvre. Elle nécessite d'avoir un réseau de neurones déjà entraîné, de préférence sur un problème proche de celui qu'on veut résoudre. De nos jours, nous pouvons facilement en récupérer un sur Internet, et notamment dans les bibliothèques de Deep Learning, comme Keras que nous allons utiliser dans le chapitre suivant.
Nous pouvons exploiter le réseau de neurones pré-entraîné de plusieurs façons, en fonction de la taille du jeu de données en entrée et de sa similarité avec celui utilisé lors du pré-entraînement.
Stratégie #1 : fine-tuning total
On remplace la dernière couche fully-connected du réseau pré-entraîné par un classifieur adapté au nouveau problème (SVM, régression logistique...) et initialisé de manière aléatoire. Toutes les couches sont ensuite entraînées sur les nouvelles images.
La stratégie #1 doit être utilisée lorsque la nouvelle collection d'images est grande : dans ce cas, on peut se permettre d'entraîner tout le réseau sans courir le risque d'overfitting. De plus, comme les paramètres de toutes les couches (sauf de la dernière) sont initialement ceux du réseau pré-entraîné, la phase d'apprentissage sera faite plus rapidement que si l'initialisation avait été aléatoire.
Stratégie #2 : extraction des features
Cette stratégie consiste à se servir des features du réseau pré-entraîné pour représenter les images du nouveau problème. Pour cela, on retire la dernière couche fully-connected et on fixe tous les autres paramètres. Ce réseau tronqué va ainsi calculer la représentation de chaque image en entrée à partir des features déjà apprises lors du pré-entraînement. On entraîne alors un classifieur, initialisé aléatoirement, sur ces représentations pour résoudre le nouveau problème.
La stratégie #2 doit être utilisée lorsque la nouvelle collection d'images est petite et similaire aux images de pré-entraînement. En effet, entraîner le réseau sur aussi peu d'images est dangereux puisque le risque d'overfitting est important. De plus, si les nouvelles images ressemblent aux anciennes, elles peuvent alors être représentées par les mêmes features.
Stratégie #3 : fine-tuning partiel
Il s'agit d'un mélange des stratégies #1 et #2 : on remplace à nouveau la dernière couche fully-connected par le nouveau classifieur initialisé aléatoirement, et on fixe les paramètres de certaines couches du réseau pré-entraîné. Ainsi, en plus du classifieur, on entraîne sur les nouvelles images les couches non-fixées, qui correspondent en général aux plus hautes du réseau.
On utilise cette stratégie lorsque la nouvelle collection d'images est petite mais très différente des images du pré-entraînement. D'une part, comme il y a peu d'images d'entraînement, la stratégie #1 qui consiste à entraîner tout le réseau n'est pas envisageable à cause du risque d'overfitting.
D'autre part, on élimine également la stratégie #2 puisque les nouvelles images ont très peu de points communs avec les anciennes : utiliser les features du réseau pré-entraîné pour les représenter n'est pas une bonne idée ! Mais souvenez-vous : les features des couches basses sont simples et génériques (donc peuvent se retrouver dans deux images très différentes), tandis que celles des couches hautes sont complexes et spécifiques au problème. Ainsi, la stratégie de fixer les couches basses et d'entraîner le classifieur et les couches hautes constitue un bon compromis.