0

I am trying to learn about LSTM cells. I have read a few articles and am now trying to write my own code using tensorflow.

I came across this code from this tutorial. So I copied the lstm.py file and the data file sp500.csv. The code below is what I written.

Everything works fine. Each time I run the model I get very different predictions. I understand that because this model is very basic (trying to predict stock prices using just the closing price) this is to be expected. Also I believe in the background tensorflow uses some randomisation process to initiate the variables.

I wanted though to run the model and get the same results each time. So I read that to do this I need to use set_random_seed.

I have added this to my code below but when I re-run my code I get very different predictions. How am I supposed to use set_random_seed and why is the parameter 1234?

from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, LSTM, Dropout, Activation
import lstm, time
import tensorflow as tf

def RunML():

    tf.set_random_seed(1234)

    X_train, y_train, X_test, y_test = lstm.load_data('sp500.csv', 50, True)

    model = Sequential()

    model.add(LSTM(50, 
               input_shape=(50, 1),
               return_sequences=True))
    model.add(Dropout(0.2))

    model.add(LSTM(
        100,
        return_sequences=False))
    model.add(Dropout(0.2))

    model.add(Dense(1))
    model.add(Activation('linear'))

    start = time.time()
    model.compile(loss='mse', optimizer='rmsprop')
    print ('compilation time : ', time.time() - start)

    #Step 3 Train the model
    model.fit(
        X_train,
        y_train,
        batch_size=512,
        nb_epoch=1,
        validation_split=0.05)

    predictions = lstm.predict_sequences_multiple(model, X_test, 50, 50)
    lstm.plot_results_multiple(predictions, y_test, 50)
mHelpMe
  • 6,336
  • 24
  • 75
  • 150

1 Answers1

1

If you set the random seed before building the graph, you will get reproducible results. For example, given a random input:

random_input = np.random.rand(2, 50, 1)

We can define one tf.keras.model:

tf.keras.backend.clear_session()
tf.set_random_seed(42)

model_1 = Sequential()

model_1.add(LSTM(50,  input_shape=(50, 1), return_sequences=True))
model_1.add(Dropout(0.2))

model_1.add(LSTM(100, return_sequences=False))
model_1.add(Dropout(0.2))

model_1.add(Dense(1))
model_1.add(Activation('linear'))

model_1.compile(loss='mse', optimizer='rmsprop')

random_predict_1 = model_1.predict(random_input)

Then another:

tf.keras.backend.clear_session()
tf.set_random_seed(42)

model_2 = Sequential()

model_2.add(LSTM(50,  input_shape=(50, 1), return_sequences=True))
model_2.add(Dropout(0.2))

model_2.add(LSTM(100, return_sequences=False))
model_2.add(Dropout(0.2))

model_2.add(Dense(1))
model_2.add(Activation('linear'))

model_2.compile(loss='mse', optimizer='rmsprop')

random_predict_2 = model_2.predict(random_input)

Now, if we perform inference on the random_input tensor, we will get the same results with both models because they had the same random seed to start.

np.testing.assert_array_equal(random_predict_1, random_predict_2)

To sum it up, no matter which random seed you use, if you set the random seed to the same number before building the graph with tf.set_random_seed(seed), you will get the same results.

gorjan
  • 5,405
  • 2
  • 20
  • 40
  • thanks for your answer. I added these two lines of code to tf.keras.backend.clear_session() tf.set_random_seed(42) underneath def RunML(): but I am still getting different results when running the model. I take it I'm missing something? – mHelpMe Aug 21 '19 at 20:49
  • 1
    By doing what I've done, you will be sure that the model weights are going to be initialized with the same values at the start (as I demonstrated in the code). If you want to identical results up to the Nth decimal (which I don't now why would you), follow [this post](https://stackoverflow.com/questions/32419510/how-to-get-reproducible-results-in-keras/52897216#52897216). – gorjan Aug 21 '19 at 21:00
  • ok thanks I will go through the post. I'm not after identical results up to the Nth decimal place, its just the predictions coming out of the model are sometimes positive then the next time negative... this is what I'm trying to sort out. In your examples is the training part missing? – mHelpMe Aug 21 '19 at 21:08
  • 1
    Yes it is. Usually, the common way of achieving (almost) identical results is to set the random seed at the start, so that all the model weights and tf/keras ops start from that seed. Because of that, I left out the part where I am training the model. I just set the random seed and randomly initialize the model weights. Because it is a controlled randomness (due to the same random seed), the results are identical. – gorjan Aug 21 '19 at 21:14