Add Keras utility for making user programs deterministic.
diff --git a/keras/api/golden/v2/tensorflow.keras.utils.pbtxt b/keras/api/golden/v2/tensorflow.keras.utils.pbtxt
index 4796cb3fbe0..ad46dc1c3b5 100644
--- a/keras/api/golden/v2/tensorflow.keras.utils.pbtxt
+++ b/keras/api/golden/v2/tensorflow.keras.utils.pbtxt
@@ -100,6 +100,10 @@ tf_module {
     name: "serialize_keras_object"
     argspec: "args=[\'instance\'], varargs=None, keywords=None, defaults=None"
   }
+  member_method {
+    name: "set_random_seed"
+    argspec: "args=[\'seed\'], varargs=None, keywords=None, defaults=None"
+  }
   member_method {
     name: "text_dataset_from_directory"
     argspec: "args=[\'directory\', \'labels\', \'label_mode\', \'class_names\', \'batch_size\', \'max_length\', \'shuffle\', \'seed\', \'validation_split\', \'subset\', \'follow_links\'], varargs=None, keywords=None, defaults=[\'inferred\', \'int\', \'None\', \'32\', \'None\', \'True\', \'None\', \'None\', \'None\', \'False\'], "
diff --git a/keras/utils/tf_utils.py b/keras/utils/tf_utils.py
index f3fc6ebb952..4c681756874 100644
--- a/keras/utils/tf_utils.py
+++ b/keras/utils/tf_utils.py
@@ -18,6 +18,7 @@
 
 import collections
 import copy
+import random
 import numpy as np
 from tensorflow.python.framework import ops
 from keras import backend
@@ -27,6 +28,38 @@
 from tensorflow.python.util.tf_export import keras_export
 
 
+@keras_export('keras.utils.set_random_seed', v1=[])
+def set_random_seed(seed):
+  """Sets all random seeds for the program (Python, NumPy, and TensorFlow).
+
+  You can use this utility to make almost any Keras program fully deterministic.
+  Some limitations apply in cases where network communications are involved
+  (e.g. parameter server distribution), which creates additional sources of
+  randomness, or when certain non-deterministic cuDNN ops are involved.
+
+  Calling this utility is equivalent to the following:
+
+  ```python
+  import random
+  import numpy as np
+  import tensorflow as tf
+  random.seed(seed)
+  np.random.seed(seed)
+  tf.random.set_seed(seed)
+  ```
+
+  Arguments:
+    seed: Integer, the random seed to use.
+  """
+  if not isinstance(seed, int):
+    raise ValueError(
+        'Expected `seed` argument to be an integer. '
+        f'Received: seed={seed} (of type {type(seed)})')
+  random.seed(seed)
+  np.random.seed(seed)
+  tf.random.set_seed(seed)
+
+
 def is_tensor_or_tensor_list(v):
   v = tf.nest.flatten(v)
   if v and isinstance(v[0], tf.Tensor):
diff --git a/keras/utils/tf_utils_test.py b/keras/utils/tf_utils_test.py
index 945fdaba54d..dd35adddd20 100644
--- a/keras/utils/tf_utils_test.py
+++ b/keras/utils/tf_utils_test.py
@@ -17,7 +17,7 @@
 import tensorflow.compat.v2 as tf
 
 from absl.testing import parameterized
-
+import numpy as np
 import keras
 from keras import combinations
 from keras.utils import tf_utils
@@ -228,5 +228,26 @@ def test_is_extension_type_return_false_for_list(self):
     tensor = [1., 2., 3.]
     self.assertFalse(tf_utils.is_extension_type(tensor))
 
+
+class TestRandomSeedSetting(tf.test.TestCase):
+
+  def test_seeds(self):
+    def get_model_output():
+      model = keras.Sequential([
+          keras.layers.Dense(10),
+          keras.layers.Dropout(0.5),
+          keras.layers.Dense(10),
+      ])
+      x = np.random.random((32, 10)).astype('float32')
+      ds = tf.data.Dataset.from_tensor_slices(x).shuffle(32).batch(16)
+      return model.predict(ds)
+
+    tf_utils.set_random_seed(42)
+    y1 = get_model_output()
+    tf_utils.set_random_seed(42)
+    y2 = get_model_output()
+    self.assertAllClose(y1, y2, atol=1e-6)
+
+
 if __name__ == '__main__':
   tf.test.main()

Add Keras utility for making user programs deterministic.
