Votre premier modèle Keras, avec apprentissage par transfert

1. Présentation

Dans cet atelier, vous allez apprendre à créer un classificateur Keras. Au lieu d'essayer de trouver la combinaison parfaite de couches de réseau de neurones pour reconnaître les fleurs, nous allons d'abord utiliser une technique appelée "apprentissage par transfert" pour adapter un modèle préentraîné puissant à notre ensemble de données.

Cet atelier inclut les explications théoriques nécessaires sur les réseaux de neurones et constitue un bon point de départ pour les développeurs qui souhaitent en savoir plus sur le deep learning.

Cet atelier est la deuxième partie de la série "Keras sur TPU". Vous pouvez les effectuer dans l'ordre suivant ou indépendamment.

ca8cc21f6838eccc.png

Points abordés

  • Pour créer votre propre classificateur d'images Keras avec une couche softmax et une perte d'entropie croisée
  • Pour tricher 😈, utilisez l'apprentissage par transfert au lieu de créer vos propres modèles.

Commentaires

Si vous remarquez quelque chose d'inhabituel dans cet atelier de programmation, veuillez nous en informer. Vous pouvez envoyer vos commentaires via les problèmes GitHub [lien vers les commentaires].

2. Démarrage rapide de Google Colaboratory

Cet atelier utilise Google Collaboratory et ne nécessite aucune configuration de votre part. Colaboratory est une plate-forme de notebooks en ligne à des fins pédagogiques. Il propose un entraînement sans frais sur CPU, GPU et TPU.

688858c21e3beff2.png

Vous pouvez ouvrir cet exemple de notebook et exécuter quelques cellules pour vous familiariser avec Colaboratory.

c3df49e90e5a654f.png Welcome to Colab.ipynb

Sélectionner un backend TPU

8832c6208c99687d.png

Dans le menu Colab, sélectionnez Exécution > Modifier le type d'exécution, puis sélectionnez TPU. Dans cet atelier de programmation, vous allez utiliser un puissant TPU (Tensor Processing Unit) pour l'entraînement accéléré par le matériel. La connexion au runtime se fait automatiquement lors de la première exécution. Vous pouvez également utiliser le bouton "Connect" (Se connecter) en haut à droite.

Exécution de notebooks

76d05caa8b4db6da.png

Exécutez les cellules une par une en cliquant sur une cellule et en utilisant Maj+ENTRÉE. Vous pouvez également exécuter l'intégralité du notebook avec Exécuter > Exécuter tout.

Sommaire

429f106990037ec4.png

Tous les notebooks contiennent une table des matières. Vous pouvez l'ouvrir à l'aide de la flèche noire sur la gauche.

Cellules masquées

edc3dba45d26f12a.png

Certaines cellules n'affichent que leur titre. Il s'agit d'une fonctionnalité de notebook spécifique à Colab. Vous pouvez double-cliquer dessus pour afficher le code qu'ils contiennent, mais ce n'est généralement pas très intéressant. Fonctions de support ou de visualisation, généralement. Vous devez toujours exécuter ces cellules pour que les fonctions à l'intérieur soient définies.

Authentification

cdd4b41413100543.png

Colab peut accéder à vos buckets Google Cloud Storage privés à condition que vous vous authentifiiez avec un compte autorisé. L'extrait de code ci-dessus déclenche un processus d'authentification.

3. [INFO] Principes de base du classificateur de réseau de neurones

En bref

Si vous connaissez déjà tous les termes en gras du paragraphe suivant, vous pouvez passer à l'exercice suivant. Si vous débutez dans le deep learning, bienvenue. Veuillez lire la suite.

Pour les modèles créés sous forme de séquence de couches, Keras propose l'API Sequential. Par exemple, un classificateur d'images utilisant trois couches denses peut être écrit dans Keras comme suit :

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

Réseau de neurones dense

Il s'agit du réseau de neurones le plus simple pour classer des images. Il est composé de "neurones" organisés en couches. La première couche traite les données d'entrée et transmet ses sorties à d'autres couches. Elle est appelée "dense" parce que chaque neurone est connecté à tous les neurones de la couche précédente.

c21bae6dade487bc.png

Vous pouvez fournir une image à un tel réseau en aplatissant les valeurs RVB de tous ses pixels en un long vecteur et en l'utilisant comme entrée. Ce n'est pas la meilleure technique pour la reconnaissance d'images, mais nous l'améliorerons plus tard.

Neurones, activations, RELU

Un "neurone" calcule une somme pondérée de toutes ses entrées, ajoute une valeur appelée "biais" et transmet le résultat via une "fonction d'activation". Les pondérations et le biais sont inconnus au départ. Ils seront initialisés de manière aléatoire et "appris" en entraînant le réseau de neurones sur de nombreuses données connues.

644f4213a4ee70e5.png

La fonction d'activation la plus populaire est appelée RELU (Rectified Linear Unit). Comme vous pouvez le voir sur le graphique ci-dessus, il s'agit d'une fonction très simple.

Activation Softmax

Le réseau ci-dessus se termine par une couche de cinq neurones, car nous classons les fleurs dans cinq catégories (rose, tulipe, pissenlit, marguerite et tournesol). Les neurones des couches intermédiaires sont activés à l'aide de la fonction d'activation ReLU classique. Cependant, dans la dernière couche, nous voulons calculer des nombres compris entre 0 et 1 représentant la probabilité que cette fleur soit une rose, une tulipe, etc. Pour ce faire, nous utiliserons une fonction d'activation appelée "softmax".

Pour appliquer softmax à un vecteur, il faut prendre l'exponentielle de chaque élément, puis normaliser le vecteur, généralement à l'aide de la norme L1 (somme des valeurs absolues) afin que les valeurs s'additionnent à 1 et puissent être interprétées comme des probabilités.

ef0d98c0952c262d.png d51252f75894479e.gif

Perte d'entropie croisée

Maintenant que notre réseau de neurones produit des prédictions à partir d'images d'entrée, nous devons mesurer leur qualité, c'est-à-dire la distance entre ce que le réseau nous dit et les réponses correctes, souvent appelées "libellés". N'oubliez pas que nous disposons de libellés corrects pour toutes les images de l'ensemble de données.

N'importe quelle distance conviendrait, mais pour les problèmes de classification, la "distance d'entropie croisée" est la plus efficace. Nous appellerons cela notre fonction d'erreur ou de "perte" :

7bdf8753d20617fb.png

Descente de gradient

"Entraîner" le réseau de neurones signifie en fait utiliser des images et des libellés d'entraînement pour ajuster les pondérations et les biais afin de minimiser la fonction de perte d'entropie croisée. Voici comment cela fonctionne.

L'entropie croisée est une fonction des pondérations, des biais, des pixels de l'image d'entraînement et de sa classe connue.

Si nous calculons les dérivées partielles de l'entropie croisée par rapport à tous les poids et à tous les biais, nous obtenons un "gradient", calculé pour une image, un libellé et une valeur actuelle de poids et de biais donnés. N'oubliez pas que nous pouvons avoir des millions de pondérations et de biais. Le calcul du gradient semble donc être une tâche considérable. Heureusement, TensorFlow le fait pour nous. La propriété mathématique d'un gradient est qu'il pointe vers le haut. Comme nous voulons aller là où l'entropie croisée est faible, nous allons dans la direction opposée. Nous mettons à jour les pondérations et les biais par une fraction du gradient. Nous répétons ensuite la même chose encore et encore en utilisant les lots suivants d'images et d'étiquettes d'entraînement, dans une boucle d'entraînement. Nous espérons que cela convergera vers un endroit où l'entropie croisée est minimale, bien que rien ne garantisse que ce minimum soit unique.

gradient descent2.png

Mini-batching et momentum

Vous pouvez calculer votre gradient sur une seule image d'exemple et mettre à jour immédiatement les pondérations et les biais. Toutefois, si vous le faites sur un lot de, par exemple, 128 images, vous obtiendrez un gradient qui représente mieux les contraintes imposées par différentes images d'exemple et qui est donc susceptible de converger plus rapidement vers la solution. La taille du mini-lot est un paramètre ajustable.

Cette technique, parfois appelée "descente de gradient stochastique", présente un autre avantage plus pragmatique : travailler avec des lots signifie également travailler avec des matrices plus grandes, qui sont généralement plus faciles à optimiser sur les GPU et les TPU.

La convergence peut toutefois rester un peu chaotique et peut même s'arrêter si le vecteur de gradient est entièrement nul. Cela signifie-t-il que nous avons trouvé un minimum ? Non. Un composant de dégradé peut être nul à un minimum ou à un maximum. Avec un vecteur de gradient comportant des millions d'éléments, si tous sont nuls, la probabilité que chaque zéro corresponde à un minimum et qu'aucun ne corresponde à un point maximal est assez faible. Dans un espace à plusieurs dimensions, les points de selle sont assez courants et nous ne voulons pas nous y arrêter.

52e824fe4716c4a0.png

Illustration : un point-selle. Le gradient est nul, mais il ne s'agit pas d'un minimum dans toutes les directions. (Attribution de l'image : Wikimedia : par Nicoguaro – Own work, CC BY 3.0)

La solution consiste à ajouter de l'élan à l'algorithme d'optimisation afin qu'il puisse dépasser les points-selles sans s'arrêter.

Glossaire

Lot ou mini-lot : l'entraînement est toujours effectué sur des lots de données et d'étiquettes d'entraînement. Cela permet à l'algorithme de converger. La dimension "batch" est généralement la première dimension des Tensors de données. Par exemple, un Tensor de forme [100, 192, 192, 3] contient 100 images de 192 x 192 pixels avec trois valeurs par pixel (RVB).

Perte d'entropie croisée : fonction de perte spéciale souvent utilisée dans les classificateurs.

Couche dense : couche de neurones où chaque neurone est connecté à tous les neurones de la couche précédente.

Caractéristiques : les entrées d'un réseau de neurones sont parfois appelées "caractéristiques". L'art de déterminer quelles parties d'un ensemble de données (ou combinaisons de parties) transmettre à un réseau de neurones pour obtenir de bonnes prédictions s'appelle l'ingénierie des caractéristiques.

Libellés : autre nom pour les "classes" ou les réponses correctes dans un problème de classification supervisée.

Taux d'apprentissage : fraction du gradient par laquelle les pondérations et les biais sont mis à jour à chaque itération de la boucle d'entraînement.

logits : les sorties d'une couche de neurones avant l'application de la fonction d'activation sont appelées "logits". Le terme provient de la "fonction logistique", également appelée "fonction sigmoïde", qui était la fonction d'activation la plus populaire. "Sorties de neurones avant la fonction logistique" a été raccourci en "logits".

loss : fonction d'erreur comparant les sorties du réseau de neurones aux bonnes réponses

Neurone : calcule la somme pondérée de ses entrées, ajoute un biais et transmet le résultat via une fonction d'activation.

Encodage one-hot : la classe 3 sur 5 est encodée sous forme de vecteur de cinq éléments, tous nuls sauf le troisième qui est égal à 1.

relu : unité de rectification linéaire. Fonction d'activation populaire pour les neurones.

sigmoid : autre fonction d'activation qui était populaire et qui est toujours utile dans des cas particuliers.

softmax : fonction d'activation spéciale qui agit sur un vecteur, augmente la différence entre le plus grand composant et tous les autres, et normalise également le vecteur pour que la somme soit égale à 1, afin qu'il puisse être interprété comme un vecteur de probabilités. Utilisé comme dernière étape dans les classificateurs.

Tenseur : un tenseur est semblable à une matrice, mais avec un nombre arbitraire de dimensions. Un Tensor unidimensionnel est un vecteur. Un Tensor à deux dimensions est une matrice. Vous pouvez ensuite avoir des Tensors avec 3, 4, 5 ou plus de dimensions.

4. Apprentissage par transfert

Pour un problème de classification d'images, les couches denses ne suffiront probablement pas. Nous devons en apprendre davantage sur les couches de convolution et les nombreuses façons de les organiser.

Mais nous pouvons aussi prendre un raccourci ! Des réseaux de neurones convolutifs entièrement entraînés sont disponibles au téléchargement. Il est possible de supprimer leur dernière couche, la tête de classification softmax, et de la remplacer par la vôtre. Tous les poids et biais entraînés restent tels quels. Vous n'avez qu'à réentraîner la couche softmax que vous ajoutez. Cette technique s'appelle l'apprentissage par transfert. Étonnamment, elle fonctionne tant que l'ensemble de données sur lequel le réseau de neurones est pré-entraîné est "suffisamment proche" du vôtre.

Pratique

Veuillez ouvrir le notebook suivant, exécuter les cellules (Shift+ENTRÉE) et suivre les instructions chaque fois que vous voyez le libellé "WORK REQUIRED" (ACTION REQUISE).

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

Informations supplémentaires

L'apprentissage par transfert vous permet de bénéficier à la fois des architectures avancées de réseaux de neurones convolutifs développées par les meilleurs chercheurs et du pré-entraînement sur un énorme ensemble de données d'images. Dans notre cas, nous allons effectuer un transfert d'apprentissage à partir d'un réseau entraîné sur ImageNet, une base de données d'images contenant de nombreuses plantes et scènes d'extérieur, ce qui est suffisamment proche des fleurs.

b8fc1efd2001f072.png

Illustration : utilisation d'un réseau de neurones convolutif complexe, déjà entraîné, comme boîte noire, en réentraînant uniquement la tête de classification. C'est ce qu'on appelle l'apprentissage par transfert. Nous verrons plus tard comment fonctionnent ces arrangements complexes de couches de convolution. Pour l'instant, c'est le problème de quelqu'un d'autre.

Apprentissage par transfert dans Keras

Dans Keras, vous pouvez instancier un modèle pré-entraîné à partir de la collection tf.keras.applications.*. MobileNet V2, par exemple, est une très bonne architecture convolutionnelle qui reste de taille raisonnable. En sélectionnant include_top=False, vous obtenez le modèle pré-entraîné sans sa dernière couche softmax, ce qui vous permet d'ajouter la vôtre :

pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False

model = tf.keras.Sequential([
    pretrained_model,
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(5, activation='softmax')
])

Notez également le paramètre pretrained_model.trainable = False. Il fige les pondérations et les biais du modèle pré-entraîné afin que vous n'entraîniez que votre couche softmax. Cela implique généralement un nombre relativement faible de pondérations et peut être effectué rapidement sans nécessiter un très grand ensemble de données. Toutefois, si vous disposez de nombreuses données, l'apprentissage par transfert peut fonctionner encore mieux avec pretrained_model.trainable = True. Les pondérations pré-entraînées fournissent ensuite d'excellentes valeurs initiales et peuvent toujours être ajustées par l'entraînement pour mieux s'adapter à votre problème.

Enfin, notez que la couche Flatten() est insérée avant votre couche softmax dense. Les couches denses fonctionnent sur des vecteurs de données plats, mais nous ne savons pas si c'est ce que renvoie le modèle préentraîné. C'est pourquoi nous devons l'aplatir. Dans le prochain chapitre, lorsque nous aborderons les architectures convolutionnelles, nous expliquerons le format de données renvoyé par les couches convolutionnelles.

Vous devriez obtenir une précision proche de 75 % avec cette approche.

Solution

Voici le notebook de solution. Vous pouvez l'utiliser si vous êtes bloqué.

c3df49e90e5a654f.png Keras Flowers transfer learning (solution).ipynb

Points abordés

  • 🤔 Écrire un classificateur dans Keras
  • 🤓 configuré avec une dernière couche softmax et une perte d'entropie croisée
  • 😈 Apprentissage par transfert
  • 🤔 Entraîner votre premier modèle
  • 🧐 Suivre sa perte et sa précision pendant l'entraînement

Veuillez prendre quelques instants pour passer en revue cette checklist.

5. Félicitations !

Vous pouvez maintenant créer un modèle Keras. Passez à l'atelier suivant pour découvrir comment assembler des couches de convolution.

Les TPU en pratique

Les TPU et les GPU sont disponibles sur Cloud AI Platform :

Enfin, vos commentaires nous intéressent. N'hésitez pas à nous contacter si vous remarquez quelque chose d'inhabituel dans cet atelier ou si vous pensez qu'il devrait être amélioré. Vous pouvez envoyer vos commentaires via les problèmes GitHub [lien vers les commentaires].

HR.png

Martin Görner ID small.jpg
Auteur : Martin Görner
Twitter : @martin_gorner

tensorflow logo.jpg
www.tensorflow.org