Cet article présente comment utiliser un réseau de neuronnes pré-entrainé pour résoudre un problème de classification d’images (tâche différente que celle pour laquelle le réseau a été préalablement entrainé). Dans notre cas, l’objectif est de classer des images satellites de toits en 4 catégories : orientation EST/OUEST, orientation NORD/SUD, toit plat, et catégorie “Autre”. Il est important de préciser une nouvelle fois que cette tâche de classification est différente de celle pour laquelle le réseau de neuronnes que nous allons utiliser a été entrainé.
Librairie MxNet
La librairie de réseau de neuronnes que nous utiliserons se nomme MxNET. Elle est disponible à la fois sous Linux et Windows, et possède (entre autre) un wrapper en Python et en R. Dans cet article le code a été exécuté sous Ubuntu avec le wrapper Python.
Installation de la librairie sous Ubuntu
Tout d’abord, exécutez les commandes suivantes :
Ensuite, clonez le dépot Github de MxNet grâce à la commande ci-après :
Puis pour compiler la librairie :
Si vous disposez d’un GPU assez récent et que vous avez déjà installé les librairies CUDA suffisantes, vous pouvez compiler la librairie avec la commande ci-dessous. Cela permettra à MxNet de tirer partie de votre GPU.
Enfin, pour installer le package Python :
En cas de problème lors de la phase d’installation, n’hésitez pas à consulter directement la documentation de MxNet.
Extracteur de features
Le réseau de neuronnes que nous allons utiliser se nomme Inception. Il a été entrainé sur le jeu de données Image Net et a une précision top-1 de 70% et top-5 de 89.9%.
Pour information, le jeu de données Image Net contient divers types d’images telles que des plantes, des animaux, des ustensiles etc… Sont but est de correctement prédire le type d’une image, ce qui est différent de notre tâche de classification. Toutefois, ce réseau a appris à extraire des caractéristiques des images afin de pouvoir les différencier les unes des autres. Il a appris, lors de sa phase d’apprentissage, à représenter les images sous une autre forme que le format brut dont on dispose. Cela est similaire à une approche plus traditionnelle qui consiste à utiliser les HOGs (Histogramme de gradient orienté) ou aux SIFT (Scale-Invariant feature transform) pour extraire des features d’une image puis de se servir de celles-ci pour entrainer un classifieur supervisé.
Pour chaque image nous allons donc extraire les caractéristiques générées par le réseau de neuronnes. Dans le cas du programme ci-après, nous avons les fichiers id_train.csv dans le répertoire courant (contient les ids et labels des images de la phase d’entrainement), ainsi qu’un dossier roof_images contenant l’ensemble des images.
Le code ci-dessous extrait les features des images qui nous serviront à entrainer notre classifeur supervisé. Celles-ci sont écrites dans le fichier features_train.csv.
Cette première phase nous a donc permis d’extraire un ensemble de caractéristique des images. Dans l’étape suivante nous utiliserons ces caractéristiques afin d’entrainer un classifieur supervisé. Nous explorerons plusieurs possibilités telles que kNN, random forest ainsi que la SVM.
Entrainement du classifieur supervisé
L’objectif désormais est d’entrainer un classifieur supervisé sur les caractéristiques que nous venons d’extraire dans l’étape précédente. Celui-ci aura pour rôle d’apprendre à classer correctement les images dans l’une des quatre catégories suivantes :
- Toit orienté Est/Ouest
- Toit orienté Nord/Sud
- Toit plat
- Autre
Notre programme permet de tester 3 algorithmes pour classer nos toits : kNN, random forest, SVM. Le programme ci-dessous est inspiré de celui que j’ai utilisé par la compétition Datascience Game. Grâce aux différents paramètres du début du programme on peut facilement changer le type de classifieur à utiliser (svm, kNN, random forest), le nombre de voisins dans le cas de l’algorithme kNN, ainsi que le nombre d’images à utiliser pour entrainer notre classifieur.
Le maximum de précision atteint en local est ~0.77 avec une svm utilisant un kernel rbf (radial basis function). Lors de l’évaluation sur Kaggle pour la compétition Datascience Game, le modèle a obtenu une précision de 0.73. Cela est globalement du au fait que notre jeu de données contient peu d’images de la catégorie “Autre” et que c’est une catégorie que nous avons du mal à prédire avec notre modèle.
Morale de l'histoire
Nous partions plutot négatif pour cette compétition car de nos jours on associe souvent classification d’images avec deep learning. Or, il est très long de faire du deep learning sans carte graphique et/ou un bon processeur. De plus, à l’origine nous n’avions pas de connaissances particulière en traitement de l’image.
Il faut savoir que la génération des features avec le réseau de neuronnes a pris une 15ene d’heures sur un pc portable avec un processeur intel Celeron(ça existe encore en 2016 …), un disque dur classique (pas de ssd), et seulement 4GO de ram. L’entrainement du classifieur supervisé par la suite est très rapide ~1min, et est donc négligeable fasse au temps d’extraction des features.
Il est donc encore possible de nos jours de survivre dans les compétitions Kaggle ou de machine learning en général, même avec un pc légèrement (voir totalement) dépassé.
Remerciements
Je tiens à remercier (par ordre alphabétique) : Fabien Gontier, Perrine Martin et Jacques Peeters avec qui j’ai réalisé cette compétition. Je laisse à Jacques Peeters (s’il le souhaite) le soin d’expliquer le modèle le plus compétent que nous avons réalisé car il en est à l’origine.