Version 5, last updated by fsavard at April 19, 2010 13:05 UTC

Carnet pour stacked denoising autoencoders

Statut de l'expérience (2010/03/16)

  • Les résultats actuels, fusionnés à la main, sont disponibles dans le fichier fsavard_sda_results.csv.
  • J'ai 88 des 96 jobs de complétées pour les expériences à 2 et 3 couches cachées. Pour une raison que je dois déterminer, le reste des jobs ont planté. Les résultats ci-dessous concernent celles qui ont abouti. Si j'arrive à déterminer la cause du bug, je relancerai celles qui restent.
  • Je fais aussi actuellement un essai avec mes meilleurs hyperparamètres, mais avec 2000 unités cachées par couche. Je le fais en utilisant un GPU, sur une machine du lab.
  • J'ai aussi obtenu d'autres résultats préliminaires à partir de premières expériences qui sont mortes car la machine de lancement avait dû être rebootée. Les quelques résultats, concernant principalement le cas à une couche cachée que j'avais eus sont dans fsavard_sda1_resultsview.
    • Il manque quelques résultats à 800 unités cachées pour la première couche.
  • Update 2010/03/29: j'avais lancé quelques jobs pour vérifier l'effet d'un bruit plus grand, en prenant les meilleurs hyperparamètres et en variant le niveau de bruit. Au passage, j'ai essayé un LR de finetuning plus petit (0.005 au lieu de 0.01, le meilleur à date), pour voir l'effet. J'ai aussi fait un test avec 2000 unités cachées sur GPU. Résultats plus bas

Auteur

François Savard

Tâche

Cette expérience fait réference au ticket: #34.

Motivations pour cette expérience.

  • Déterminer quels hyperparamètres favorisent une bonne erreur de validation sur NIST, et éventuellement sur d'autres ensembles d'entraînement.
  • Obtient-on un gain en performance par rapport aux méthodes (encore plus) baseline comme le MLP?

Modèle avec lequel on a effectué l'expérience: Il s'agit d'autoencodeurs débruitant empilés. J'explore les hyperparamètres suivant, pour l'instant, où chaque hyperparamètre prend les valeurs dans l'array qui le suit, et on fait le produit croisé de toutes les valeurs possibles:

JOB_VALS = {'pretraining_lr': [0.1, 0.01],
        'pretraining_epochs_per_layer': [10,20],
        'hidden_layers_sizes': [300,800],
        'corruption_levels': [0.1,0.2,0.3],
        'minibatch_size': [20],
        'max_finetuning_epochs':[1000],
        'finetuning_lr':[0.1, 0.01],
        'num_hidden_layers':[2,3]}

Dans ces expériences on ne retrouve pas le cas "num_hidden_layers=1" car j'avais déjà les résultats dans ce cas-là par les premières expériences non terminées. Ces dernières tentaient d'explorer les hyperparamètres suivants:

JOB_VALS = {'pretraining_lr': [0.1, 0.01, 0.001],
        'pretraining_epochs_per_layer': [10,20],
        'hidden_layers_sizes': [300,800],
        'corruption_levels': [0.1,0.2],
        'minibatch_size': [20],
        'max_finetuning_epochs':[1000]}
FINETUNING_LR_VALS = [0.1, 0.01, 0.001]
NUM_HIDDEN_LAYERS_VALS = [1,2,3]

Ce qu'on teste: l'impact de ces hyperparamètres sur l'erreur de validation, de test.

Données utilisées:

  • Pour l'instant, NIST brut seulement (j'utilise directement les ensembles train et test. Pour la validation, je prends la longueur de l'ensemble de test et je recoupe ce nombre d'exemples de l'ensemble d'entraînement, idée que j'ai empruntée dans le code de Xavier Muller.

Résultats

Le meilleur résultat a une erreur de validation de 11.8% et de test de 22.9%. Il est obtenu avec hidden_layers_sizes=800, num_hidden_layers=3, corruption_levels=0.2, finetuning_lr=0.01, pretraining_lr=0.1.

J'ai un meilleur résultat pour l'erreur de test (21.9%), mais il ne correspond pas à la meilleure erreur de validation.

Ce que je constate concernant l'influence des différents hyperparamètres:

  • Le nombre d'unités cachées est franchement le facteur déterminant. Strictement tous les résultats à 300 unités cachées sont moins bons que les résultats à 800 unités par couche.
  • Le deuxième facteur d'importance est le nombre de couches cachées. Les meilleurs résultats sont tous avec 2 ou 3 couches cachées.
  • J'avais déterminé par des expériences préliminaires (partiellement complétées, voir ci-haut) qu'un learning rate trop petit (0.001) pour le finetuning donnait de franchement piètres résultats. Tous mes résultats avec ce learning rate avec une erreur de validation supérieure à 18%, allant jusqu'à 28%, bien que ce soit pour une seule couche cachée). Voir la table fsavard_sda1_resultsview.
    • J'ai donc éliminé ce learning rate plus petit des expériences reprises.
    • Le learning rate de pretraining n'a pas ce même impact négatif. Pour sauver du temps de calcul, j'ai néanmoins coupé pretraining_lr=0.001 dans les expériences reprises.
  • Cependant, mes 20 meilleurs résultats ont tous un learning rate de finetuning de 0.01, ce qui ne peut être une coïncidence. Pour bien faire, il faudrait que je raffine cet hyperparamètre dans des expériences ultérieures.
  • Le learning rate de pretraining (0.1 ou 0.01) a un impact largement moindre, apparemment.
  • Le niveau de corruption (bruit) choisi ne semble pas avoir un gros impact: j'ai de très bons résultats avec 0.1, 0.2 ou 0.3.
  • Le nombre d'époque de préentraînement par couche (10 ou 20) ne semblait pas avoir un gros impact, à première vue.

29 mars: résultats avec plus d'unités cachées ou plus de bruit

  • À la suggestion de Dumitru, j'ai essayé avec un bruit de 40% ou 60%, en conservant les meilleurs hyperparamètres trouvés plus haut (variant le LR de finetuning quand même).
    • Avec 40%, j'obtiens de bons résultats, semblables à ceux obtenus avec 30 ou 20%.
    • Avec 60%, les résultats sont moins bons, autour de 13 ou 14% d'erreur de validation.
    • J'ai au passage essayé un LR de finetuning plus petit (0.005 au lieu de 0.01) avec 30% de bruit, et ça produit de moins bons résultats.
  • Comme demandé il y a quelques semaines, j'avais lancé un test sur GPU avec 2000 unités cachées (autrement mêmes hyperparamètres que meilleur cas). Le résultat est très semblable au meilleurs résultats à 800 h.u. en validation: 11.9% d'erreur de validation, 24% d'erreur de test. Donc pas d'amélioration notable ici. Il faudrait peut-être que j'essaie de faire varier le LR par contre, ou encore plus d'unités cachées.

Emplacement des résultats

  • dans la base de donnée ift6266h10_db
  • sur gershwin
  • dans les views fsavard_sda1_resultsview* et fsavard_sda4_view
  • j'ai un résumé des résultats, fusionnés, dans un fichier uploadé ici, fsavard_sda_results.csv


Details pour réproduire les résultats

Code utilisé pour la deuxième vague d'expériences:

  • versionift6266 | versionpylearn | versiontheano
    • e656edaedb48+  | a88c1746b068+  | 37a7c963271a

Code utilisé pour les premiers tests (jobs mortes sauf pour première couche cachée):

  • le code pour les scripts de l'expérience est dans la révision revision:3346fcd381
  • avec theano (changeset id: 532d912f9541)
  • jobman (changeset id: afa949c22a3e)
  • dbidispatch

Grappe de calcul utilisé: condor au lisa (--server --os=FC9)

Commandes utilisées pour lancer les jobs:

  • le code actuel est dans ift6266/deep/stacked_dae
  • mon schedule est un peu particulier, je le fais avec le module Python jobman. Voir mon fichier nist_sda.py
    • Pour les premières expériences, je testais plusieurs combinaisons d'hyperparamètres par job. Je mettais les résultats dans une table _results, et les jobs à rouler dans une table _jobs. C'est lié à la façon dont je réutilise plusieurs fois les paramètres obtenus à la fin du préentraînement.
    • Pour la deuxième vague d'expérience, c'était plus simple. Une seule table de résultats et jobs (fsavard_sda4).
  • dbidispatch --condor --server --repeat_jobs=5 jobman sql 'postgres://ift6266h10@gershwin/ift6266h10_db/fsavard_sda1_jobs' .
    • En fait y'aura 24 jobs à lancer.

Temps de calcul: 

  • Pour la deuxième vague de jobs, ça prend en moyenne 1.2 jour / job. Minimum autour de 5 heures. Maximum autour de 5.4 jours.