TensorFlow 2.0 tf.random.set_seed not working since I am getting different results

Question:

I am using tf.random.set_seed to assure the reproducibility of my experiments but getting different results in terms of loss after training my model multiple times. I am monitoring the learning curve of each experiment using Tensorboard, but I am getting different values of loss and accuracy.

Asked By: Khalil Mlayhi

||

Answers:

Providing the solution here (Answer Section), even though it is present in the Comment Section, for the benefit of the community.

To reproduce same results, you can create function as below and pass seeds directly to the layers as mentioned Daniel in the comments.

def reset_random_seeds():
   os.environ['PYTHONHASHSEED']=str(2)
   tf.random.set_seed(2)
   np.random.seed(2)
   random.seed(2)

Please refer complete code in below, which reproduced same results

import os
####*IMPORANT*: Have to do this line *before* importing tensorflow
os.environ['PYTHONHASHSEED']=str(2)

import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers 
import random
import pandas as pd
import numpy as np

def reset_random_seeds():
   os.environ['PYTHONHASHSEED']=str(2)
   tf.random.set_seed(2)
   np.random.seed(2)
   random.seed(2)

#make some random data
reset_random_seeds()
NUM_ROWS = 1000
NUM_FEATURES = 10
random_data = np.random.normal(size=(NUM_ROWS, NUM_FEATURES))
df = pd.DataFrame(data=random_data, columns=['x_' + str(ii) for ii in range(NUM_FEATURES)])
y = df.sum(axis=1) + np.random.normal(size=(NUM_ROWS))

def run(x, y):
    reset_random_seeds()

    model = keras.Sequential([
            keras.layers.Dense(40, input_dim=df.shape[1], activation='relu'),
            keras.layers.Dense(20, activation='relu'),
            keras.layers.Dense(10, activation='relu'),
            keras.layers.Dense(1, activation='linear')
        ])
    NUM_EPOCHS = 100
    model.compile(optimizer='adam', loss='mean_squared_error')
    model.fit(x, y, epochs=NUM_EPOCHS, verbose=0)
    predictions = model.predict(x).flatten()
    loss = model.evaluate(x,  y) #This prints out the loss by side-effect

#With Tensorflow 2.0 this is now reproducible! 
run(df, y)
run(df, y)
run(df, y)

Output:

32/32 [==============================] - 0s 2ms/step - loss: 0.5633
32/32 [==============================] - 0s 2ms/step - loss: 0.5633
32/32 [==============================] - 0s 2ms/step - loss: 0.5633
Answered By: Tensorflow Warrior

for tensorflow 2, use tf.random.set_seed(seed) instead

Answered By: Hassan Shoayb

tf.keras.utils.set_random_seed may also need to be set (or, for instnace, keras.utils.set_random_seed, if you imported keras from tensorflow).

Docs: https://www.tensorflow.org/api_docs/python/tf/keras/utils/set_random_seed

Answered By: Thomas Winckelman