2016-03-29 9 views
33

Próbuję uruchomić sieć neuronową wiele razy z różnymi parametrami w celu skalibrowania parametrów sieci (prawdopodobieństwa rezygnacji, szybkość uczenia się e.d.). Jednak mam problem, że uruchomienie sieci zachowując parametry takie same wciąż daje mi inne rozwiązanie kiedy uruchomić sieć w pętli, co następuje:Jak uzyskać stabilne wyniki za pomocą TensorFlow, ustawienie losowego materiału siewnego

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() 

Używam następujący kod na początku moja funkcja train_network przed utworzeniem warstwy i funkcji błędu z mojej sieci:

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

próbowałem również dodanie tego kodu przed stworzeniem wykresu TensorFlow, ale wciąż otrzymuję różne rozwiązania w moim wyjściu z wynikami.

Używam programu AdamOptimizer i inicjuję wagi sieci, używając tf.truncated_normal. Dodatkowo używam np.random.permutation do mieszania przychodzących obrazów dla każdej epoki.

Odpowiedz

24

Ustawienie bieżącego losowego materiału siewnego TensorFlow wpływa tylko na bieżący domyślny wykres. Ponieważ tworzysz nowy wykres treningu i ustawiasz go jako domyślny (with g.as_default():), musisz ustawić losowe nasiono w zakresie tego bloku with.

Na przykład, pętla powinna wyglądać następująco:

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) 

pamiętać, że będzie korzystać z tego samego losowych dla każdej iteracji pętli zewnętrznej for. Jeśli chcesz użyć innego —, ale nadal deterministycznego nasienia — w każdej iteracji, możesz użyć tf.set_random_seed(i + 1).

+2

wierzę my set_random_seed (1) już w g.as_default (blokują), ponieważ jest to jeden z pierwszych Linią kod train_network. Niemniej próbowałem wprowadzenie kodu jak w przykładzie, ale ja wciąż się wyniki niestabilne: > dokładność \t etykiety \t błąd > 0,9805 \t nie run0 \t 2,96916 > 0,9807 \t zrobił run1 \t 2,96494 > 0.9804 \t zrobił RUN2 \t 2.95215 – Waanders

+0

Mam ten sam problem. 'tensorflow'' 0.12.1' ustawia losowe ziarno zgodnie z podanym kątem Widzę niewielkie różnice w wynikach prawdopodobieństwa od uruchomienia do uruchomienia. – Luke

+2

Przyczyna zależy od tego, jaka jest twoja funkcja, ale prawdopodobnie małe różnice w obliczeniach dokładności są spowodowane niedeterministyczną równoległą redukcją operacji, takich jak 'tf.reduce_sum()'. (Operacje te traktują zmiennoprzecinkowe dodawanie jako przemienne, gdy w rzeczywistości tak nie jest, a zmiany w porządku redukcji mogą prowadzić do niewielkich błędów w wyniku ...) – mrry

6

Zachowanie deterministyczne można uzyskać przez podanie poziomu podstawowego lub poziomu operacyjnego. Oboje pracowali dla mnie. Nasiona na poziomie wykresu można umieścić pod numerem tf.set_random_seed. Seed operacji poziomu może być umieszczony na przykład w zmiennej intializer na przykład:

myvar = tf.Variable(tf.truncated_normal(((10,10)), stddev=0.1, seed=0)) 
Powiązane problemy