web-dev-qa-db-fra.com

Comment obtenir des résultats reproductibles en keras

J'obtiens des résultats différents (précision du test) chaque fois que j'exécute l'exemple imdb_lstm.py à partir du framework Keras ( https://github.com/fchollet/keras/blob/master/examples/imdb_lstm.py ) Le code contient np.random.seed(1337) en haut, avant toute importation de keras. Cela devrait l'empêcher de générer des numéros différents pour chaque exécution. Qu'est-ce que je rate? 

MISE À JOUR: Comment reproduire: 

  1. Installer Keras ( http://keras.io/
  2. Exécutez https://github.com/fchollet/keras/blob/master/examples/imdb_lstm.py plusieurs fois. Il formera le modèle et la précision du test de sortie.
    Résultat attendu: La précision du test est la même à chaque exécution.
    Résultat réel: La précision du test est différente à chaque analyse.

UPDATE2: Je l’utilise sous Windows 8.1 avec MinGW/msys, versions de module:
theano 0.7.0
numpy 1.8.1
scipy 0.14.0c1

UPDATE3: J'ai réduit le problème un peu. Si je lance l'exemple avec GPU (set theeano flag device = gpu0), j'obtiens une précision de test différente à chaque fois, mais si je l'exécute sur un processeur, tout fonctionne comme prévu. Ma carte graphique: NVIDIA GeForce GT 635)

47
Pavel Surmenok

Theano's documentation parle des difficultés liées à l'ensemencement des variables aléatoires et explique pourquoi elles ensemencent chaque instance de graphe avec son propre générateur de nombres aléatoires. 

Partage d'un générateur de nombre aléatoire entre différents {{{RandomOp}}} cas, il est difficile de produire le même flux indépendamment de d’autres opérations dans le graphe, et de garder {{{RandomOps}}} isolé . Par conséquent, chaque instance {{{{RandomOp}}} dans un graphique aura son propre propre générateur de nombres aléatoires. Ce générateur de nombres aléatoires est une entrée à la fonction. En utilisation typique, nous utiliserons les nouvelles fonctionnalités de entrées de fonction ({{{valeur}}}, {{{update}}}) à transmettre et à mettre à jour le rng pour chaque {{{RandomOp}}}. En passant les RNG en entrées, il est possible de utilisez les méthodes habituelles d’accès aux entrées de fonction pour accéder à chaque {{{{RandomOp}}} ’rng. Dans cette approche, il n'y a pas de préexistant mécanisme pour travailler avec l'état de nombre aléatoire combiné d'un tout graphique. Il est donc proposé de fournir les fonctionnalités manquantes (les trois dernières exigences.) Via des fonctions auxiliaires: {{{seed, getstate, setstate}}}.

Ils fournissent également des exemples sur la manière d’ensemencer tous les générateurs de nombres aléatoires. 

Vous pouvez également ensemencer toutes les variables aléatoires allouées par un RandomStreams par la méthode de départ de cet objet. Cette graine sera utilisé pour créer un générateur de nombre aléatoire temporaire, qui à son tour générer des graines pour chacune des variables aléatoires.

>>> srng.seed(902340)  # seeds rv_u and rv_n with different seeds each
13
PabTorre

J'ai finalement obtenu des résultats reproductibles avec mon code. C'est une combinaison de réponses que j'ai vues sur le web. La première chose est de faire ce que @alex dit:

  1. Set numpy.random.seed;
  2. Utilisez PYTHONHASHSEED=0 pour Python 3.

Ensuite, vous devez résoudre le problème signalé par @ user2805751 à propos de cuDNN en appelant votre code Keras avec le THEANO_FLAGS supplémentaire suivant:

  1. dnn.conv.algo_bwd_filter=deterministic,dnn.conv.algo_bwd_data=deterministic

Et enfin, vous devez patcher votre installation Theano selon ce commentaire , qui consiste essentiellement à:

  1. en remplaçant tous les appels vers l'opérateur *_dev20 par sa version standard dans theano/sandbox/cuda/opt.py.

Cela devrait vous donner les mêmes résultats pour la même graine.

Notez qu'il peut y avoir un ralentissement. J'ai vu une augmentation de temps d'exécution d'environ 10%.

11
kepler

Vous pouvez trouver la réponse dans la documentation de Keras: https://keras.io/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development .

En bref, pour être absolument certain que vous obtiendrez des résultats reproductibles avec votre script python sur le processeur d'un ordinateur portable/portable, vous devrez procéder comme suit:

  1. Définir la variable d'environnement PYTHONHASHSEED à une valeur fixe
  2. Définir le générateur pseudo-aléatoire intégré python à une valeur fixe
  3. Définir le générateur pseudo-aléatoire numpy à une valeur fixe
  4. Définir le générateur pseudo-aléatoire tensorflow à une valeur fixe
  5. Configurer une nouvelle session globale tensorflow

Après le lien Keras en haut, le code source que j'utilise est le suivant:

# Seed value
# Apparently you may use different seed values at each stage
seed_value= 0

# 1. Set `PYTHONHASHSEED` environment variable at a fixed value
import os
os.environ['PYTHONHASHSEED']=str(seed_value)

# 2. Set `python` built-in pseudo-random generator at a fixed value
import random
random.seed(seed_value)

# 3. Set `numpy` pseudo-random generator at a fixed value
import numpy as np
np.random.seed(seed_value)

# 4. Set `tensorflow` pseudo-random generator at a fixed value
import tensorflow as tf
tf.set_random_seed(seed_value)

# 5. Configure a new global `tensorflow` session
from keras import backend as K
session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

Il est inutile de dire que vous n'avez pas besoin de spécifier les variables seed ou random_state aux fonctions numpy, scikit-learn ou tensorflow/keras que vous utilisez dans votre script python, car avec le code source ci-dessus, nous définissons globalement leurs générateurs pseudo-aléatoires à une valeur fixe.

7
Poete Maudit

J'aimerais ajouter quelque chose aux réponses précédentes. Si vous utilisez python 3 et que vous voulez obtenir des résultats reproductibles à chaque exécution, vous devez

  1. définir numpy.random.seed au début de votre code
  2. donnez PYTHONHASHSEED = 0 comme paramètre à l'interpréteur python
1
Alex

Je suis d'accord avec le commentaire précédent, mais des résultats reproductibles nécessitent parfois le même environnement (par exemple, packages installés, caractéristiques de la machine, etc.). Pour cela, je vous recommande de copier votre environnement à un autre endroit au cas où vous obtiendriez des résultats reproductibles. Essayez d'utiliser l'une des prochaines technologies:

  1. Docker . Si vous avez un système Linux, il est très facile de déplacer votre environnement ailleurs. Aussi, vous pouvez essayer d'utiliser DockerHub
  2. Classeur . Ceci est une plate-forme en nuage pour reproduire des expériences scientifiques.
  3. Everware . C'est encore une autre plate-forme en nuage pour la "science réutilisable". Voir le répertoire project sur Github.
0
Yelaman

J'ai formé et testé le type de réseaux de neurones Sequential() à l'aide de Keras. J'ai effectué une régression non linéaire sur des données de parole bruyantes. J'ai utilisé le code suivant pour générer une graine aléatoire: 

import numpy as np
seed = 7
np.random.seed(seed)

Je reçois exactement les mêmes résultats avec val_loss chaque fois que je m'entraîne et que je teste les mêmes données. 

0
tauseef_CuriousGuy

Cela fonctionne pour moi:

SEED = 123456
import os
import random as rn
import numpy as np
from tensorflow import set_random_seed

os.environ['PYTHONHASHSEED']=str(SEED)
np.random.seed(SEED)
set_random_seed(SEED)
rn.seed(SEED)
0
Victor Villacorta