Deep Learning 03 – Reconnaissance de caractères

Dans la première partie, nous avons vu ce qu’est un neurone.

Nous allons maintenant passer au niveau supérieur : le réseau de neurones.

Le principe du réseau de neurones est d’assembler entre-eux des neurones, pour leur faire apprendre des tâches plus complexes, que celles vues dans la première partie.

Les neurones vont être regroupés en couches, une couche réalisant une même tâche de façon à donner un niveau d’abstraction supplémentaire à la couche suivante.

De cette façon, pour reconnaître le chiffre 8, la couche la plus basse va repérer des morceaux de courbes et la couche supérieure estimer qu’un certain agencement de morceaux de courbes forme un 8 et non un 3.

L’utilisation de plusieurs couches (layer en anglais) est appelée apprentissage profond, le fameux Deep Learning.

Nous allons expérimenter l’apprentissage d’un réseau de neurones pour résoudre un problème classique dans le milieu du machine learning : la reconnaissance d’écriture.

Nous utiliserons le jeux de données MNIST, mis à disposition par le français Yann Le Cun, actuel directeur du laboratoire de recherche de Facebook à Paris. Grâce à ses travaux sur MNIST, les réseaux de neurones sont revenus sur le devant de la scène.

Préparation

Il faut au préalable installer Keras et Tensorflow. Pour cela, reportez-vous à la documentation, l’installation de TensorFlow pour utiliser un GPU est un peu plus compliquée, mais l’amélioration des performances en vaut largement la peine, comme nous le verrons plus bas.

Le source est disponible sur mon GitHub.
C’est une copie d’un exemple de Keras, avec pour différence, l’enregistrement du résultat de l’apprentissage par la ligne suivante :

model.save_weights(DATA_ROOT + 'mnist_cnn_final_weights.hdf5')

Modèle

Le modèle utilisé est un réseau de neurones convolutif (Covolutional Neural Network : CNN) pouvant être représenté comme ceci :

Source

ou encore :

Source

(Pour les observateurs attentifs : les couches dans le code sont les mêmes que sur les illustrations, mais avec des paramètres légèrement différents)

Il y a deux couches de convolution 2D, qui analysent donc l’image telle qu’un humain la voit. Puis sont mises à plat (1D) les informations dans un tableau de 128 valeurs, et une dernière couche de neurones aboutit à un tableau de 10 valeurs, représentant chaque chiffre possible.

Vous pouvez visualiser le fonctionnement interne grâce à cette page de Standford :

Entraînement

Exécutons le script :

python3 02_mnist_cnn_train.py

Vous verrez que le programme récupère directement le jeu de données par lui-même, la librairie Keras le gère automatiquement, du fait que c’est un exemple très courant.

Le temps d’exécution dépendra de votre machine et la différence n’est pas négligeable :

Aux environs d’une heure sur un portable « classique » contre moins d’une minute avec une carte graphique GTX 1080 ti !

Le gain de performance est vraiment élevé et l’usage d’un GPU indispensable. En effet, dans le cas présent, les données utilisées sont très petites, de même que le réseau de neurones.

Prédiction

La prédiction est la finalité du réseau de neurones : pouvoir lui présenter une image et récupérer ce qu’il « voit ».

Moins de codes source pour réaliser cette action sont disponibles, vous trouverez le mien sur Github.

Étonnamment, le code est plus long que celui d’entraînement !

En effet, d’une part, il faut toujours construire le réseau de neurones avant de lui charger les poids sauvegardés par le script précédent.

D’autre part, il faut convertir l’image au format attendu par le réseau de neurones : c’est à dire un tableau de 28×28 pixels avec une valeur entre 0 et 1 pour chaque pixel. Et non trois couches rouge, vert, bleu entre 0 et 255 comme dans les formats d’images classiques.

Et voilà, nous avons maintenant un réseau de neurones pouvant détecter des chiffres !

Une prochaine fois, nous verrons comment utiliser ces connaissances sur notre propre jeu de données et en améliorer les performances petit à petit.