Le transfer learning en pratique — étapes clés et exemples de code

Owain Biddulph
neoxia
Published in
5 min readNov 30, 2021

Pour reprendre la comparaison classique des réseaux de neurones artificiels avec le cerveau humain, le transfer learning peut alors être illustré par des transferts de compétences que nous faisons tous les jours. Apprendre un instrument de musique est généralement beaucoup plus simple quand on maîtrise déjà un ou plusieurs instruments. Ou encore, un joueur de tennis sera généralement bon à d’autres sports de raquette qui nécessitent une bonne coordination oeil-main.

C’est une technique puissante, très utile pour des tâches nécessitant une importante puissance de calcul pour l’apprentissage, telles des tâches de vision par ordinateur (computer vision), ou de traitement du langage (NLP).

Son objectif est de réduire le temps d’apprentissage et d’améliorer les performances d’un modèle de deep learning. Pour cela, un modèle pré-entraîné est utilisé comme socle sur lequel on pourra développer un modèle spécifique à une tâche donnée.

Le transfer learning va donc permettre de transférer des compétences acquises par un modèle sur une tâche donnée, vers une autre tâche proche.

Les 5 étapes clés du transfer learning

Les frameworks plus communément utilisés pour faire du deep learning (TensorFlow, PyTorch, Caffe etc.) permettent facilement de faire du transfer learning et je donnerai pour chaque étape des exemples de code utilisant TensorFlow 2.x.

1. Import du modèle et suppression des couches de sortie

La première étape consiste à importer le modèle pré-entraîné et de supprimer la couche de classification du modèle (on parle de “head” ou “top”). Cette couche est spécifique à la tâche sur laquelle le modèle a été entraîné à l’origine et n’est pas adaptée à notre nouvelle tâche.

Dans le code qui suit, la suppression du “head” se fait grâce à l’argument include_top=False. On indique aussi la taille des données avec l’argument input_shape et les paramètres pré-entraînés à utiliser avec l’argument weights. On utilise ici les paramètres d’un MobileNet entraîné sur la base d’images imagenet.

Quand on utilise un modèle pré-entraîné, il ne faut pas oublier d’utiliser le même preprocessing que lors de l’entraînement d’origine. Dans TensorFlow, une fonction de preprocessing est toujours fournie, d’où l’import de preprocess_input.

2. Figer les couches pré-entraînées

Cette étape est cruciale pour éviter de détruire le pré-entraînement. En effet, le pré-entraînement (ou l’entraînement de façon générale) consiste à déterminer de bons paramètres pour les couches entraînées (ou du moins, c’est le but). Or, un modèle de transfer learning consiste en :

  • une base pré-entraînée (une base convolutive dans cet exemple)
  • des couches de sortie non entraînées.

Lors des premières étapes d’entraînement d’un tel modèle, les couches de sorties étant généralement initiées avec des valeurs aléatoires, les gradients de la rétro-propagation sont élevés. Si les paramètres de la base ne sont pas figés, les gradients élevés les modifient alors énormément. On perd alors tout l’intérêt du pré-entraînement !

Pour éviter cela, il est donc nécessaire de figer ces paramètres.

3. Ajout des nouvelles couches de sorties

Une fois les couches du socle figées, on peut ajouter de nouvelles couches de sorties spécifiques à une tâche donnée, permettant notamment d’avoir le bon type de sortie (classification binaire, multiclasse etc.). Ces nouvelles couches seront ainsi entraînées sur les données relatives à la tâche en question (des images de pierre feuille ciseaux par exemple dans le cas d’utilisation plus loin).

Nous avons maintenant tout les éléments nécessaires pour créer notre modèle, voici donc le code complet en TensorFlow 2.x.

On remarquera l.20 l’argument training=False lors de l’instanciation du base_model. Ceci est crucial, permettant de garder les couches de batch normalization en mode inférence lors de l’étape de fine-tuning (étape 5).

4. Première phase d’apprentissage

La première phase d’apprentissage permet d’entraîner les couches de sorties puisque les couches du socle sont figées. Les couches du modèle pré-entraîné sont alors utilisées en mode inférence, leurs paramètres ne sont pas mis à jour et certaines couches ont un comportement différent. Par exemple, les couches de Dropout ne s’activent plus.

Petite astuce si on ne prévoit pas de faire d’augmentation de données, on peut passer une fois les images dans le socle et stocker le résultat. Ces sorties (ou features) pourront être utilisées pour entraîner les couches de sorties seules, évitant ainsi de calculer les sorties du socle à chaque epoch. Cependant, on utilise souvent le transfer learning dans des cas où l’on ne dispose pas de beaucoup de données, il est donc généralement bénéfique d’utiliser des techniques d’augmentation.

En TensorFlow, après avoir compilé le modèle, l’entraînement se fait avec la fonction model.fit().

5. Fine-tuning

Le fine-tuning est la dernière étape d’entraînement et permet de spécialiser les couches du socle à leur nouvelle tâche. On peut alors les défiger, et continuer l’entraînement du modèle avec un learning rate faible.

Attention ! Si le socle comporte des couches de batch normalization, il faut vérifier qu’elles restent dans un mode d’inférence pour ne pas changer les valeurs de moyenne et de variance utilisées lors des précédents entraînements. Ceci est mis en avant dans l’exemple de code de l’étape 3.

Exemple d’utilisation sur des images de “pierre feuille ciseaux”

Vous trouverez dans ce Colab un cas d’exemple complet utilisant une base MobileNet.

Le graphique suivant montre les deux phases d’entraînement. On peut voir un premier plateau atteint lors de la première phase, qui est ensuite dépassé lors de la phase de fine-tuning grâce à une spécialisation des dernières couches du réseau convolutif.

Cet exemple montre l’efficacité que peut avoir le transfer learning, que ce soit en terme de qualité du modèle ou en temps de conception et d’entraînement. Ce n’est pas une solution miracle qui marche systématiquement, mais une méthode facile à mettre en oeuvre qui vaut donc souvent le coup d’essayer !

--

--