Path: blob/master/examples/keras_recipes/ipynb/reproducibility_recipes.ipynb
5294 views
Reproducibility in Keras Models
Author: Frightera
Date created: 2023/05/05
Last modified: 2023/05/05
Description: Demonstration of random weight initialization and reproducibility in Keras models.
Introduction
This example demonstrates how to control randomness in Keras models. Sometimes you may want to reproduce the exact same results across runs, for experimentation purposes or to debug a problem.
Setup
Weight initialization in Keras
Most of the layers in Keras have kernel_initializer and bias_initializer parameters. These parameters allow you to specify the strategy used for initializing the weights of layer variables. The following built-in initializers are available as part of keras.initializers:
In a reproducible model, the weights of the model should be initialized with same values in subsequent runs. First, we'll check how initializers behave when they are called multiple times with same seed value.
Now, let's inspect how two different initializer objects behave when they are have the same seed value.
If the seed value is not set (or different seed values are used), two different objects will produce different results. Since the random seed is set at the beginning of the notebook, the results will be same in the sequential runs. This is related to the keras.utils.set_random_seed.
result_3 and result_4 will be different, but when you run the notebook again, result_3 will have identical values to the ones in the previous run. Same goes for result_4.
Reproducibility in model training process
If you want to reproduce the results of a model training process, you need to control the randomness sources during the training process. In order to show a realistic example, this section utilizes tf.data using parallel map and shuffle operations.
In order to start, let's create a simple function which returns the history object of the Keras model.
Remember we called tf.config.experimental.enable_op_determinism() at the beginning of the function. This makes the tf.data operations deterministic. However, making tf.data operations deterministic comes with a performance cost. If you want to learn more about it, please check this official guide.
Small summary what's going on here. Models have kernel_initializer and bias_initializer parameters. Since we set random seeds using keras.utils.set_random_seed in the beginning of the notebook, the initializers will produce same results in the sequential runs. Additionally, TensorFlow operations have now become deterministic. Frequently, you will be utilizing GPUs that have thousands of hardware threads which causes non-deterministic behavior to occur.
tf.data.Dataset objects have a shuffle method which shuffles the data. This method has a buffer_size parameter which controls the size of the buffer. If you set this value to len(train_images), the whole dataset will be shuffled. If the buffer size is equal to the length of the dataset, then the elements will be shuffled in a completely random order.
Main drawback of setting the buffer size to the length of the dataset is that filling the buffer can take a while depending on the size of the dataset.
Here is a small summary of what's going on here:
The
shuffle()method creates a buffer of the specified size.The elements of the dataset are randomly shuffled and placed into the buffer.
The elements of the buffer are then returned in a random order.
Since tf.config.experimental.enable_op_determinism() is enabled and we set random seeds using keras.utils.set_random_seed in the beginning of the notebook, the shuffle() method will produce same results in the sequential runs.
Train the model for the first time.
Let's save our results into a JSON file, and restart the kernel. After restarting the kernel, we should see the same results as the previous run, this includes metrics and loss values both on the training and test data.
Do not run the cell above in order not to overwrite the results. Execute the model training cell again and compare the results.
Compare the results one by one. You will see that they are equal.
Conclusion
In this tutorial, you learned how to control the randomness sources in Keras and TensorFlow. You also learned how to reproduce the results of a model training process.
If you want to initialize the model with the same weights everytime, you need to set kernel_initializer and bias_initializer parameters of the layers and provide a seed value to the initializer.
There still may be some inconsistencies due to numerical error accumulation such as using recurrent_dropout in RNN layers.
Reproducibility is subject to the environment. You'll get the same results if you run the notebook or the code on the same machine with the same environment.