J'écris un wrapper tensorflow.Keras pour effectuer des expériences ML.

J'ai besoin de mon framework pour pouvoir effectuer une expérience comme spécifié dans un fichier de configuration yaml et l'exécuter en parallèle dans un GPU.

Ensuite, j'ai besoin d'une garantie que si je recommençais l'expérience, j'obtiendrais sinon exactement les mêmes résultats quelque chose de raisonnablement proche.

Pour essayer de garantir cela, mon script de formation contient ces lignes au début, en suivant les directives du documentation officielle :

# Set up random seeds
random.seed(seed)
np.random.seed(seed)
tf.set_random_seed(seed)

Cela s'est avéré insuffisant.

J'ai exécuté la même configuration 4 fois et tracé les résultats:

enter image description here

Comme vous pouvez le voir, les résultats varient beaucoup entre les analyses.

Comment puis-je configurer une session de formation dans Keras pour m'assurer d'obtenir des résultats raisonnablement similaires lors de la formation sur un GPU? Est-ce seulement possible?

Le script de formation complet est disponible ici.

Certains de mes collègues utilisent juste du TF pur, et leurs résultats semblent beaucoup plus cohérents. Qui plus est, ils ne semblent pas semer le hasard, sauf pour s'assurer que la répartition du train et de la validation est toujours la même.

2
Jsevillamol 16 mars 2019 à 22:41

2 réponses

Meilleure réponse

Keras + Tensorflow.

Étape 1, désactivez le GPU.

import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ""

Étape 2, amorcez les bibliothèques qui sont incluses dans votre code, dites "tensorflow, numpy, random".

import tensorflow as tf
import numpy as np
import random as rn

sd = 1 # Here sd means seed.
np.random.seed(sd)
rn.seed(sd)
os.environ['PYTHONHASHSEED']=str(sd)

from keras import backend as K
config = tf.ConfigProto(intra_op_parallelism_threads=1,inter_op_parallelism_threads=1)
tf.set_random_seed(sd)
sess = tf.Session(graph=tf.get_default_graph(), config=config)
K.set_session(sess)

Assurez-vous que ces deux morceaux de code sont inclus au début de votre code, le résultat sera reproductible.

5
guorui 20 juil. 2019 à 01:26

Essayez d'ajouter des paramètres de graine aux initialiseurs de poids / biais. Juste pour ajouter plus de détails au commentaire d'Alexandre Ejbekov.

Tensorflow a deux niveaux de graphe et niveau d'opération aléatoires. Si vous utilisez plusieurs graphiques, vous devez spécifier la graine dans chacun d'eux. Vous pouvez remplacer le graine de niveau graphique par le niveau op, en définissant le paramètre de graine dans la fonction. Et vous pouvez faire en sorte que deux fonctions, même à partir de graphiques différents, affichent la même valeur si la même valeur de départ est définie. Considérez cet exemple:

g1 = tf.Graph()
with g1.as_default():
    tf.set_random_seed(1)
    a = tf.get_variable('a', shape=(1,), initializer=tf.keras.initializers.glorot_normal())
    b = tf.get_variable('b', shape=(1,), initializer=tf.keras.initializers.glorot_normal(seed=2))
with tf.Session(graph=g1) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(a)) 
    print(sess.run(b))
g2 = tf.Graph()
with g2.as_default():
    a1 = tf.get_variable('a1', shape=(1,), initializer=tf.keras.initializers.glorot_normal(seed=1))

with tf.Session(graph=g2) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(a1))

Dans cet exemple, la sortie de a est identique à a1, mais b est différente.

1
Sharky 16 mars 2019 à 20:58