Dans ce TP, nous abordons les perceptrons multi-couches.
Attention : ceux-ci ne sont pas adaptés aux exemples que nous traitons dans ce cours concernant classification supervisée pour des données tabulaires. Néanmoins, il nous paraît indispensable qu'une présentation de ces méthodes soit effectuée dans le cadre du cours.
À l'issue de ce TP, vous m'envoyez par email un compte-rendu (format pdf) indiquant la réponse aux questions qui sont posées. Vous m'envoyez également un fichier python réalisant toutes les manipulations de ce TP : je dois pouvoir exécuter ce fichier en tapant python3 nom-de-votre-fichier.py et reproduire vos résultats. Cette exécution ne doit pas provoquer d'erreur de python. Remarque : un notebook ne convient pas.
On commence par importer la bibliothèque adéquate par : from sklearn.neural_network import MLPClassifier
.
On suppose que l'on a chargé des exemples et que l'on a centrée-réduit la valeur des attributs. On note comme d'habitude X_train
et Y_train
les exemples d'entraînement, X_test
et Y_test
les exemples de test.
PMC = MLPClassifier (hidden_layer_sizes = (5, 3), activation='tanh', solver = "lbfgs", random_state = graine)
.
solver = "lbfgs"
qui calcule les poids du réseau de manière bien plus efficace qu'une descente de gradient stochastique (mais n'est utilisable que si le nombre de paramètres à optimiser est assez petit).
Pour calculer les poids sur les données d'entraînement, on fait comme suit :
PMC. fit (X_train, Y_train)
Pour prédire la classe d'un ensemble de données, on fait comme suit :
PMC. predict (X_test)
Comme pour les autres méthodes, cela fournit un vecteur contenant la prédiction pour chacune des lignes de X_test
.
On peut ensuite calculer le taux de succès, une table de contingence, etc.
On peut aussi obtenir une estimation de la probabilité d'appartenir à chacune des classes avec PMC. predict_proba (X_test)
. Pour un problème ayant 2 classes, on obtient une matrice à 2 colonnes, chaque colonne indiquant la probabilité pour la donnée d'appartenir à l'une ou l'autre classe.
On peut obtenir les biais et les poids du PMC avec PMC.coefs_
et les biais par PMC.intercepts_
:
PMC.intercepts_
est une liste ayant autant d'éléments qu'il y a de couches, donc ici 3 (2 couches cachées et une couche de sortie). Le premier élément contient les biais de la première couche cachée (donc 5 valeurs), etc. jusqu'au dernier élément qui contient les biais de la couche de sortie (1 valeur).PMC.coefs_
est également une liste ayant autant d'éléments qu'il y a de couches. Cette fois-ci, chaque élément de la liste est une matrice contenant le poids reliant la couche précédente à la couche courante. Ainsi le premier élément de la liste est la matrice des poids reliant les entrées du PMC aux perceptrons de la première couche cachée ; le deuxième élément est la matrice des poids reliant la première couche cachée à la seconde ; le dernier élément fournit les poids entre les perceptrons de la deuxième couche cachée et la couche de sortie. Étant donnée l'architecture du PMC (4 entrées, puis 5 perceptrons puis 3 perceptrons puis une sortie), les matrices sont de taille 4x5, 5x3, 3x1.Malheureusement, ces poids ne nous disent rien de qualitatif sur la manière dont le PMC prédit la classe d'une donnée. Certes on peut faire le calcul à la main (c'est bien de le faire pour une donnée pour vérifier que l'on a bien compris comment la sortie du PMC est calculée), mais c'est tout : les réseaux de neurones sont des boîtes noires.
Comme toujours en science des données, on cherche le plus petit modèle qui obtient de bonnes performances.
Une règle générale est de créer le PMC le plus petit possible qui donne un bon taux de succès. Pour cela, il faut tester plusieurs architectures. Pour les exemples traités dans ce TP, il faut prendre une ou deux couches cachées de petites tailles (5 perceptrons par couche par exemple, ou 5 et 3 en diminuant le nombre de perceptrons par couche quand on s'approche de la couche de sortie).
Et bien sûr, le calcul des poids étant stochastique, il faut réaliser plusieurs entraînements différents et conserver le paramétrage qui donne le meilleur taux de succès (sur le jeu de test). « Plusieurs entraînements différtents » signifie effectuer des entraînements avec des graines différentes, mais aussi des partitionnements jeu d'entraînement/jeu de test différents.
Les iris sont un problème à 3 classes. On le transforme en un problème à deux classes et on applique un PMC.
Tout d'abord, prédire les setosa par rapport aux deux autres classes. C'est un problème facile. Chercher une petit PMC qui effectue cette prédiction parfaitement. Une couche cachée doit suffire.
On veut maintenant prédire les versicolor par rapport aux deux autres classes. À nouveau, chercher un petit PMC qui minimise l'erreur de test.
On peut aussi traiter directement les trois classes. Pour cela, il suffit que les étiquettes à prédire prennent 3 valeurs dans le jeu d'entraînement. Faites-le pour les iris.
Comparer les résultats obtenus avec un arbre de décision. Conclure.
Procéder de même pour prédire l'attribut region
tout d'abord, l'attribut area
ensuite.
Faites de même sur ce jeu de données.
Il est très facile et instructif de programmer l'algorithme de descente de gradient stochastique pour un seul perceptron. Je vous encourage à le faire en vous appuyant sur ce TP que je fais faire en L1. Ce TP contient beaucoup d'explications que vous connaissez déjà. Concentrez-vous sur l'algorithme, sa programmation et sa mise en œuvre sur les jeux de données habituels. Vous pouvez lire une explication détaillée concernant le perceptron dans le polycopié qui accompagne mon cours de L1. Pour le perceptron multi-couches, voir mon polycopié de fouille de données.