Path: blob/master/examples/keras_recipes/ipynb/reproducibility_recipes.ipynb
3508 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.