2017-10-19 3 views
4

Ich habe das Problem, dass ich meine Ergebnisse nicht mit Keras und ThensorFlow reproduzieren kann.Ergebnisse nicht reproduzierbar mit Keras und TensorFlow in Python

Es scheint so, als hätte es kürzlich einen Workaround für dieses Problem auf der Keras documentation site veröffentlicht, aber irgendwie funktioniert es nicht für mich.

Was mache ich falsch?

Ich benutze ein Jupyter Notebook auf einem MBP Retina (ohne Nvidia GPU).

# ** Workaround from Keras Documentation ** 

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

# The below is necessary in Python 3.2.3 onwards to 
# have reproducible behavior for certain hash-based operations. 
# See these references for further details: 
# https://docs.python.org/3.4/using/cmdline.html#envvar-PYTHONHASHSEED 
# https://github.com/fchollet/keras/issues/2280#issuecomment-306959926 

import os 
os.environ['PYTHONHASHSEED'] = '0' 

# The below is necessary for starting Numpy generated random numbers 
# in a well-defined initial state. 

np.random.seed(42) 

# The below is necessary for starting core Python generated random numbers 
# in a well-defined state. 

rn.seed(12345) 

# Force TensorFlow to use single thread. 
# Multiple threads are a potential source of 
# non-reproducible results. 
# For further details, see: https://stackoverflow.com/questions/42022950/which-seeds-have-to-be-set-where-to-realize-100-reproducibility-of-training-res 

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1) 

from keras import backend as K 

# The below tf.set_random_seed() will make random number generation 
# in the TensorFlow backend have a well-defined initial state. 
# For further details, see: https://www.tensorflow.org/api_docs/python/tf/set_random_seed 

tf.set_random_seed(1234) 

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf) 
K.set_session(sess) 


# ** Workaround end ** 

# ** Start of my code ** 


# LSTM and CNN for sequence classification in the IMDB dataset 
from keras.models import Sequential 
from keras.layers import Dense 
from keras.layers import LSTM 
from keras.layers.embeddings import Embedding 
from keras.preprocessing import sequence 
from sklearn import metrics 
# fix random seed for reproducibility 
#np.random.seed(7) 

# ... importing data and so on ... 

# create the model 
embedding_vecor_length = 32 
neurons = 91 
epochs = 1 
model = Sequential() 
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length)) 
model.add(LSTM(neurons)) 
model.add(Dense(1, activation='sigmoid')) 
model.compile(loss='mean_squared_logarithmic_error', optimizer='adam', metrics=['accuracy']) 
print(model.summary()) 
model.fit(X_train, y_train, epochs=epochs, batch_size=64) 
# Final evaluation of the model 
scores = model.evaluate(X_test, y_test, verbose=0) 
print("Accuracy: %.2f%%" % (scores[1]*100)) 

Python 3.6.3 | Anaconda benutzerdefiniert (x86_64) | (Standard, 6. Oktober 2017, 12:04:38) [GCC 4.2.1 Compatible Clang 4.0.1 (Tags/RELEASE_401/final)]

Die Problemumgehung ist bereits im Code enthalten (ohne Wirkung).

Mit jedem Trainingsteil bekomme ich unterschiedliche Ergebnisse.

Beim Zurücksetzen des Kernels des Jupyter Notebooks entspricht das erste Mal dem ersten Mal und das zweite Mal dem zweiten Mal.

So nach dem Zurücksetzen ich immer zum Beispiel 0,7782 im ersten Lauf bekommen, 0,7732 auf dem zweiten Lauf usw.

Aber Ergebnisse ohne Kernel-Reset sind immer unterschiedlich jedes Mal, wenn ich es laufen.

Ich wäre für jeden Vorschlag hilfreich!

+0

Können Sie 'np.random.get_state()' und 'rn.getstate()' zur Ausgabe hinzufügen? Verwenden Sie GPU oder CPU? Können Sie das Skript in 'Python' ausprobieren? – Maxim

Antwort

1

Ich hatte genau das gleiche Problem und schaffte es, es zu lösen, indem ich die Tensorflow-Sitzung jedes Mal schloss und neu startete, wenn ich das Modell ausführte. In Ihrem Fall sollte es so aussehen:

#START A NEW TF SESSION 
np.random.seed(0) 
tf.set_random_seed(0) 
sess = tf.Session(graph=tf.get_default_graph()) 
K.set_session(sess) 

embedding_vecor_length = 32 
neurons = 91 
epochs = 1 
model = Sequential() 
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length)) 
model.add(LSTM(neurons)) 
model.add(Dense(1, activation='sigmoid')) 
model.compile(loss='mean_squared_logarithmic_error', optimizer='adam', metrics=['accuracy']) 
print(model.summary()) 
model.fit(X_train, y_train, epochs=epochs, batch_size=64) 
# Final evaluation of the model 
scores = model.evaluate(X_test, y_test, verbose=0) 
print("Accuracy: %.2f%%" % (scores[1]*100)) 

#CLOSE TF SESSION 
K.clear_session() 

lief ich den folgenden Code und reproduzierbare Ergebnisse hatte mit GPU und tensorflow Backend:

print datetime.now() 
for i in range(10): 
    np.random.seed(0) 
    tf.set_random_seed(0) 
    sess = tf.Session(graph=tf.get_default_graph()) 
    K.set_session(sess) 

    n_classes = 3 
    n_epochs = 20 
    batch_size = 128 

    task = Input(shape = x.shape[1:]) 
    h = Dense(100, activation='relu', name='shared')(task) 
    h1= Dense(100, activation='relu', name='single1')(h) 
    output1 = Dense(n_classes, activation='softmax')(h1) 

    model = Model(task, output1) 
    model.compile(loss='categorical_crossentropy', optimizer='Adam') 
    model.fit(x_train, y_train_onehot, batch_size = batch_size, epochs=n_epochs, verbose=0) 
print(model.evaluate(x=x_test, y=y_test_onehot, batch_size=batch_size, verbose=0)) 
K.clear_session() 

Und erhalten diese Ausgabe:

2017-10-23 11:27:14.494482 
0.489712882132 
0.489712893813 
0.489712892765 
0.489712854426 
0.489712882132 
0.489712864011 
0.486303713004 
0.489712903398 
0.489712892765 
0.489712903398 

Was ich verstanden habe ist, dass, wenn Sie Ihre tf-Sitzung nicht schließen (Sie tun es, indem Sie in einem neuen Kernel laufen), Sie die selbe "seeded" -Verteilung abtasten.

+0

Scheint, als ob es noch einige Unterschiede in der Punktzahl gibt, obwohl es nah ist. Im Moment muss ich ein Ranking machen, abhängig von der Wahrscheinlichkeit, also sind auch kleine Unterschiede wichtig (deshalb habe ich zu diesem Zweck auf Theano Backend umgestellt). Aber danke! Ich werde versuchen, welche Ergebnisse ich bekomme. –

Verwandte Themen