web-dev-qa-db-fra.com

Comment obtenir des résultats stables avec TensorFlow, définir une graine aléatoire

J'essaie d'exécuter plusieurs fois un réseau de neurones avec différents paramètres afin de calibrer les paramètres du réseau (probabilités d'abandon, taux d'apprentissage e.d.). Cependant, le problème qui se pose est que le fonctionnement du réseau tout en conservant les mêmes paramètres me donne une solution différente lorsque je lance le réseau en boucle comme suit:

filename = create_results_file()
for i in range(3):
  g = tf.Graph()
  with g.as_default():
    accuracy_result, average_error = network.train_network(
        parameters, inputHeight, inputWidth, inputChannels, outputClasses)
    f, w = get_csv_writer(filename)
    w.writerow([accuracy_result, "did run %d" % i, average_error])
    f.close()

J'utilise le code suivant au début de ma fonction train_network avant de configurer les couches et la fonction d'erreur de mon réseau:

np.random.seed(1)
tf.set_random_seed(1)

J'ai également essayé d'ajouter ce code avant la création du graphique TensorFlow, mais je continue à avoir des solutions différentes dans mes résultats.

J'utilise AdamOptimizer et j'initialise les poids réseau à l'aide de tf.truncated_normal. De plus, j'utilise np.random.permutation pour mélanger les images entrantes pour chaque époque.

52
Waanders

La définition de la graine aléatoire TensorFlow actuelle affecte uniquement le graphique actuel par défaut. Puisque vous créez un nouveau graphique pour votre entraînement et que vous le définissez par défaut (with g.as_default():), vous devez définir le germe aléatoire dans la portée de ce bloc with.

Par exemple, votre boucle devrait ressembler à ceci:

for i in range(3):
  g = tf.Graph()
  with g.as_default():
    tf.set_random_seed(1)
    accuracy_result, average_error = network.train_network(
        parameters, inputHeight, inputWidth, inputChannels, outputClasses)

Notez que cela utilisera la même graine aléatoire pour chaque itération de la boucle externe for. Si vous souhaitez utiliser une graine différente - mais toujours déterministe - dans chaque itération, vous pouvez utiliser tf.set_random_seed(i + 1).

41
mrry

Un comportement déterministe peut être obtenu en fournissant un germe au niveau graphique ou au niveau opération. Les deux travaillaient pour moi. Une graine au niveau graphique peut être placée avec tf.set_random_seed . Une graine au niveau de l'opération peut être placée, par exemple, dans un initialiseur variable, comme dans:

myvar = tf.Variable(tf.truncated_normal(((10,10)), stddev=0.1, seed=0))
13
ssegvic