TP - Apprentissage bayésien et chaîne de Markov cachée

Stéphane Derrode, École Centrale de Lyon


1. Introduction

L’objectif de ce TP est de programmer certains des algorithmes vus en cours sur le modèle des chaînes de Markov cachées (Hidden Markov Chain, HMC). Il s’agit d’appliquer la décision bayésienne (par le biais des critères MPM et MAP), après avoir appris automatiquement les paramètres du modèle HMC grâce à l’algorithme EM (Expectation-Maximization).

Téléchargez et décompressez le fichier zip disponible en suivant ce lien. Vous disposez ainsi de 4 fichiers Python (et 3 répertoires), formant le squelette du programme :

  • Func.py : contient tous les algorithmes pour la décision bayésienne et pour l’apprentissage EM. Certaines fonctions sont vides : à vous de les programmer selon les indications données ci-dessous.
  • SimulHMC.py : permet de simuler N observations et N labels d’une HMC dont les paramètres sont fixés au début du programme principal. Les trajectoires simulées ainsi sont stockées dans le sous-répertoire sources.
  • SupervisedHMCRestoration.py : permet la restauration optimale au sens de certains critères Bayésien lorsque les paramètres du modèle sont supposés connus.
  • UnsupervisedHMCRestoration.py : même objectif que ci-dessous, mais avec une phase d’apprentissage automatique des paramètres supplémentaire (algorithme EM).

2. Simulation d’une HMC

Fichier principal : SimulHMC.py

  • Vérifiez que vous comprenez bien les algorithmes servant à simuler les états de la chaîne de Markov et les observations correspondantes.
  • Exécutez le programme SimulHMC.py. Dans le répertoire results, vous pouvez observer des extraits graphiques des 2 signaux générés.
  • Ouvrez le fichier sources/XY.out avec un éditeur de texte et observez le format des données enregistrées. Ces données seront utilisées comme données d’entrée lors des 2 prochains programmes.

3. Restauration supervisée

Fichier principal : SupervisedHMCRestoration.py

  • Vérifiez que les paramètres définis dans le programme principal sont bien identiques à ceux utilisés pour la simulation (on est ici dans le cas de la restauration à paramètres connus). Et vérifiez que le programme lit bien le fichier que vous avez simulé par le programme précédent (i.e. sources/XY.out).
  • Programmez la méthode getBeta(…) du fichier func.py, grâce à l’algorithme backward présenté en cours. Cet algorithme est utilisé dans le cadre du critère MPM (vous n’avez pas à programmer la phase forward ; elle l’est pour vous !).
  • Programmez la méthode getMAPClassif(…) du fichier func.py qui implémente l’algorithme de Viterbi (citère MAP).
  • Lancez le programme et vérifiez que vous obtenez un résultat proche du suivant :
II= [0.5 0.5]
t= [[0.95 0.05]
 [0.05 0.95]]
Confusion matrix for MPM:
 [[523.   8.]
 [  8. 461.]]
Global error rate for MPM: 0.016
By class error rate for MPM: [0.01506591 0.01705757]
Confusion matrix for MAP:
 [[526.   5.]
 [  8. 461.]]
Global error rate for MAP: 0.013
By class error rate for MAP: [0.0094162  0.01705757]

4. Restauration non supervisée

Fichier principal : UnsupervisedHMCRestoration.py

Il s’agit ici d’apprendre automatiquement les paramètres du modèle à partir de l’algorithme EM décrit dans le support de cours (cf HMCModel.pdf), avant d’appliquer la décision Bayésienne (critère MPM).

  • Analysez le squelette de l’algorithme, qui est très similaire à celui du modèle de mélange.
  • Programmez la méthode UpdateParameters(…), appelée par la fonction EM_Iter(…) du fichier func.py.
  • Lancez le programme. Après 30 itérations, vous devriez observer un résultat comparable à
--->iteration= 0
Initial estimations:
  Confusion matrix for MPM =
 [[272. 294.]
 [  0. 434.]]
  Global Error rate for MPM:  0.294
  Class Error rate for MPM:  [0.51943463 0.        ]
--->iteration= 1
--->iteration= 2
--->iteration= 3
...
--->iteration= 28
--->iteration= 29
pathToSave= ./results/XY_t4
Final estimations:
  Confusion matrix for MPM =
 [[525.   6.]
 [  8. 461.]]
  Global Error rate for MPM:  0.014
  Class Error rate for MPM:  [0.01129944 0.01705757]
  • Observez et commentez les courbes de convergence sauvegardées dans le répertoire results.

5. Application à la segmentation d’une image

Nous allons chercher à segmenter une image carrée à niveaux de gris (typiquement 64x64 ou 128x128), en exploitant l’algorithme d’estimation des paramètres de la section précédente et le Parcours de Peano.

Le parcours de Peano (famille des courbes de Hilbert) permet de convertir une image (intrinsèquement 2D) en un vecteur 1D (de taille égale au nombre de pixels dans l’image), tout en conservant au mieux le voisinage des pixels (cf slides de cours). Il est ainsi possible d’appliquer les algorithmes précédents sur ce vecteur. Nous obtenons alors un vecteur segmenté (par MAP ou MPM, suite à l’estimation des paramètres par EM) qu’il convient de reconstruire sous le format d’une image par le biais du parcours de Peano inverse.

  • Sélectionnez une image sur Internet

    • à niveaux de gris. Il est toujours possible de convertir une image couleur par un logiciel tel que gimp ou par un logiciel en ligne. Le répertoire Peano/source contient une image de cible qui convient, mais il est préférable de travailler sur votre propre image.
    • carrée et de dimensions en puissance de 2 (typiquement 64x64 ou 128x128, pour réduire les temps d’exécution).
  • Observez les 2 programmes principaux dans le répertoire Peano, et exécutez-les sur votre image de manière à convertir l’image en un vecteur et, vice-versa, convertir le vecteur ainsi obtenu en une image. Vérifiez que l’image résultante de cette double transformation est bien identique à l’image originale.

  • Créez un nouveau programme principal (appelé pourquoi pas SI_Peano_HMC.py ?) dont l’objectif est de segmenter de manière non supervisée, l’image proposée en entrée. TIP Si vous souhaitez importez une fonction (par exemple la fonction Peano(...) définie dans PeanoImage.py), vous pouvez utiliser cette façon de faire :

import sys
sys.path.append('./Peano')
from PeanoImage import Peano