Version 5, last updated by fsavard at April 05, 2011 10:43 UTC
MLPs profonds
But
Suite au commentaire d'un reviewer pour l'article pour JMLR, on veut mesurer la performance de MLP profonds (2 ou 3 couches cachées) entraînés de manière purement supervisée, avec déformations.
Le reviewer avait fait un test rapide avec 3 couches de 500 unités et des caractères NIST déformés et avait obtenu 1.08% sur des digits (plus probablement MNIST que NIST!), vs 1.4% pour notre meilleur SdA. À noter qu'il avait probablement entraîné sur les digits uniquement, ce qui peut faire une bonne différence.
Pour l'instant les tests avec MLP étaient shallow, donc n'avaient qu'une seule couche (tests effectués par Xavier Muller).
Plan des expériences
Plan du choix d'hyperparamètres selon datasets
- Je veux entraîner (de manière supervisée) sur différents datasets: NIST, NISTP, P07.
- Je vais calculer l'erreur de tous les modèles sur tous les datasets, pour faire simple.
- Je vais aussi calculer l'erreur sur des classes séparées: NIST digits, minuscules, majuscules.
- Il faudrait cependant essayer d'entraîner sur NIST digits uniquement, si on compte calculer l'erreur sur NIST digits, plutôt que de rouler uniquement des tests où on entraîne sur toutes les classes. (Sinon il se peut que de faire ça désavantage les MLPs.)
- Pour faire ça, comme on a pas de training set "NIST digits" séparé, je compte mettre un masque dans la fonction de coût, pour n'utiliser que les exemples qui sont des digits (ie. multiplier par 0 la loss pour les autres exemples). Ça va rendre les minibatches de taille variable, par contre.
- YOSHUA: il me semblerait VRAIMENT plus efficace de générer un training set avec juste les chiffres en filtrant le training set original!
- Je cherchais à éviter ça (car ça finit par prendre pas mal de place sur les disques), mais tant pis; j'ai écrit un script pour filtrer P07 et NISTP pour ne garder que les digits. Il fonctionne, mais je dois attendre un peu avant de le lancer, car pour l'instant P07 est en état zippé sur /data/lisa, pas lisatmp, etc. Donc encore un peu de job de bras avant de pouvoir lancer sur P07 et des versions à digits seulement.
- Comme le choix du dataset sur lequel calculer l'erreur influe sur à la fois le choix d'hyperparamètres (est-ce qu'on optimiser pour l'erreur en valid sur P07, NISTP, etc.), et influe aussi sur le early stopping (une erreur peut descendre plus vite que l'autre etc.), je compte utiliser une grille fixe d'hyperparamètres, un nombre fixe (assez grand) d'époques, calculer les séries d'erreur sur tous les datasets, et conserver le minimum atteint pour chacun pour fin de comparaison de modèles.
- Ensuite en regardant les minima atteint selon chaque dataset, on pourra sélectionner les meilleurs hyperparamètres selon les différentes tâches qui nous intéressent, pour obtenir le meilleur pour une tâche donnée.
Autres paramètres des modèles
- J'utiliserai des softmaxes en sortie, et des tanh comme nonlinéarité
- J'utiliserai des learning rates fixes, pour diminuer le nombre d'hyperparamètres
- J'utiliserai un nombre fixe d'unités cachées, le même que nos meilleurs modèles SdA (1000), pour ne pas avantager un ou l'autre inutilement.
- YOSHUA: NON, JUSTEMENT, la faiblesse des expériences passées, c'est qu'on avait gardé la taille fixe, ce qui pourrait avantager indûment un algo plutôt qu'un autre. Il faudrait donc garder la taille comme hyper-paramètre, i.e., trouver pour chaque algo une taille à peu près optimale (par rapport à l'erreur de valid).
- 2 ou 3 couches cachées
Hyperparamètres exacts
Voici les choix d'hyperparamètres qui seront passés à jobman pour qu'il fasse une grille:
'n_hidden={{200,500,1000,2000}}'
'n_hidden_layers={{2,3}}'
'train_on={{NIST,NISTP,P07}}'
'train_subset={{DIGITS_ONLY,ALL}}'
'learning_rate_log10={{-1.,-2.,-3.,-4.}}'
Paramètres ayant une seule valeur pour toutes les jobs:
rng_seed=1234
L1_reg=0.0
L2_reg=0.0
n_epochs=10 # <---- le plus important ici
minibatch_size=20
(et comme je disais: tanh comme nonlinéarité des couches cachées, softmax en sortie)
Résultats
Problèmes de jobs plantées
J'ai roulé ces expériences sur les GPU de condor entièrement, finalement. Sur 108 jobs, 37 n'ont pas terminé pour une raison ou une autre (j'en ai tué volontairement une dizaine, le reste je ne me l'explique pas parfaitement). Vu des contraintes de temps de calcul pour d'autres deadlines à venir, je ne les relancerai pas.
On a quand même assez de résultats pour avoir une idée des performances puisque ces jobs plantées étaient plus ou moins aléatoirement pigées dans le lot des 108, donc le reste constitue un bon sample des résultats complets.
Meilleures performances
Sélection de modèle par erreur de validation sur NIST
Si je sélectionne le meilleur modèle selon l'erreur de validation sur NIST, tous entraînements confondus, je favorise indûment les entraînements faits sur NIST entièrement, puisque leur ensemble d'entraînement a la même distribution que cet ensemble de validation. Hors cette distribution est assez différente de l'ensemble de test de NIST.
Globalement, les entraînements faits sur NISTP sont ceux qui donnent, de loin, les meilleures performances sur NIST test (pas le cas des modèles entraînés sur P07, qui sont moins bons).
Donc je triche "un peu" et je ne considère que les meilleurs résultats en validation pour les modèles entraînés sur NISTP.
Rappel: un entraînement de MLP profond sur NISTP revient environ, conceptuellement, aux méthodes d'entraînements avec déformations élastiques de Simard 2003.
Meilleures performances sur classification de NIST, toutes classes
Meilleur modèle entraîné sur NISTP:
- erreur de validation: 12.4%,
- erreur de test sur NIST:17.6% (légèrement moins bon que le meilleur SDA, ~=17.0%)
(obtenue par un modèle avec 3 couches de 2000 unités cachées, learning rate 0.001)
Meilleures performances sur classification de NIST, digits seulement
Meilleur modèle entraîné sur NISTP digits seulement:
- erreur de validation: 0.33%
-
erreur de test sur NIST digits: 1.71% (battu par le meilleur SDA: ~=1.2%)
- (ce qui me fait remarquer que le tableau de Sylvain "Résultats SDA" dit que la meilleure performance sur les digits est 1.2%, alors que dans l'article on disait 1.4%)
(obtenue par un modèle avec 3 couches de 1000 unités cachées, learning rate 0.01)
Meilleures performances sur classification de NISTP, toutes classes
Meilleur modèle entraîné sur NISTP:
- erreur de validation: 30.2%
- erreur de test sur NIST: 31.4% (battu par le meilleur SDA: ~=29.7%)
(obtenue par un modèle avec 3 couches de 2000 unités cachées, learning rate 0.01)