From 191d6a4e0218f15064618eaf15255dec8330df5f Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Tue, 14 Nov 2023 15:28:35 +0000 Subject: [PATCH 01/18] unpin tf-nightly --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 224e4dfde64..4670ed4f3f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ env: BUILDTOOLS_VERSION: '3.0.0' BUILDIFIER_SHA256SUM: 'e92a6793c7134c5431c58fbc34700664f101e5c9b1c1fcd93b97978e8b7f88db' BUILDOZER_SHA256SUM: '3d58a0b6972e4535718cdd6c12778170ea7382de7c75bc3728f5719437ffb84d' - TENSORFLOW_VERSION: 'tf-nightly==2.16.0.dev20231018' + TENSORFLOW_VERSION: 'tf-nightly' jobs: build: From 09e26549a57914f555be2af8f4dcabdc417b7fce Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Tue, 14 Nov 2023 16:37:11 +0000 Subject: [PATCH 02/18] Update Keras test, Model() no longer supports deeply nested input/output lists. --- tensorboard/plugins/hparams/_keras_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tensorboard/plugins/hparams/_keras_test.py b/tensorboard/plugins/hparams/_keras_test.py index 4ebaf21f91e..4df33e8ab8b 100644 --- a/tensorboard/plugins/hparams/_keras_test.py +++ b/tensorboard/plugins/hparams/_keras_test.py @@ -63,7 +63,7 @@ def mock_time(): initial_time = mock_time.time with mock.patch("time.time", mock_time): self._initialize_model(writer=self.logdir) - self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) + self.model.fit(x=[1], y=[2], callbacks=[self.callback]) final_time = mock_time.time files = os.listdir(self.logdir) @@ -136,7 +136,7 @@ def test_explicit_writer(self): filename_suffix=".magic", ) self._initialize_model(writer=writer) - self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) + self.model.fit(x=[1], y=[2], callbacks=[self.callback]) files = os.listdir(self.logdir) self.assertEqual(len(files), 1, files) @@ -152,15 +152,15 @@ def test_non_eager_failure(self): with self.assertRaisesRegex( RuntimeError, "only supported in TensorFlow eager mode" ): - self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) + self.model.fit(x=[1], y=[2], callbacks=[self.callback]) def test_reuse_failure(self): self._initialize_model(writer=self.logdir) - self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) + self.model.fit(x=[1], y=[2], callbacks=[self.callback]) with self.assertRaisesRegex( RuntimeError, "cannot be reused across training sessions" ): - self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) + self.model.fit(x=[1], y=[2], callbacks=[self.callback]) def test_invalid_writer(self): with self.assertRaisesRegex( From 37ad9102f832395e6b8e1a21779041144b43b90b Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Tue, 14 Nov 2023 17:02:42 +0000 Subject: [PATCH 03/18] `maybe_layers` will not be a nested list --- tensorboard/plugins/graph/keras_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tensorboard/plugins/graph/keras_util.py b/tensorboard/plugins/graph/keras_util.py index 987af754956..dfd8d9637a2 100644 --- a/tensorboard/plugins/graph/keras_util.py +++ b/tensorboard/plugins/graph/keras_util.py @@ -101,10 +101,10 @@ def _norm_to_list_of_layers(maybe_layers): """Normalizes to a list of layers. Args: - maybe_layers: A list of data[1] or a list of list of data. + maybe_layers: Data or a list of data. Returns: - List of list of data. + List of data. [1]: A Functional model has fields 'inbound_nodes' and 'output_layers' which can look like below: @@ -113,7 +113,7 @@ def _norm_to_list_of_layers(maybe_layers): The data inside the list seems to describe [name, size, index]. """ return ( - maybe_layers if isinstance(maybe_layers[0], (list,)) else [maybe_layers] + maybe_layers if isinstance(maybe_layers, list) else [maybe_layers] ) From 752a566f05ead7b2742438ed009384d553b572b8 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 13:55:28 +0000 Subject: [PATCH 04/18] Revert "`maybe_layers` will not be a nested list" This reverts commit e073813c55f4d21daf4bc1e385c4525951044435. --- tensorboard/plugins/graph/keras_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tensorboard/plugins/graph/keras_util.py b/tensorboard/plugins/graph/keras_util.py index dfd8d9637a2..987af754956 100644 --- a/tensorboard/plugins/graph/keras_util.py +++ b/tensorboard/plugins/graph/keras_util.py @@ -101,10 +101,10 @@ def _norm_to_list_of_layers(maybe_layers): """Normalizes to a list of layers. Args: - maybe_layers: Data or a list of data. + maybe_layers: A list of data[1] or a list of list of data. Returns: - List of data. + List of list of data. [1]: A Functional model has fields 'inbound_nodes' and 'output_layers' which can look like below: @@ -113,7 +113,7 @@ def _norm_to_list_of_layers(maybe_layers): The data inside the list seems to describe [name, size, index]. """ return ( - maybe_layers if isinstance(maybe_layers, list) else [maybe_layers] + maybe_layers if isinstance(maybe_layers[0], (list,)) else [maybe_layers] ) From 5e56b9b246208e23b01bab9b3a506f61bdb21250 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 13:55:56 +0000 Subject: [PATCH 05/18] Revert "Update Keras test, Model() no longer supports deeply nested input/output lists." This reverts commit 8187aeab7e595f11279fc352fd6c9781e9b11830. --- tensorboard/plugins/hparams/_keras_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tensorboard/plugins/hparams/_keras_test.py b/tensorboard/plugins/hparams/_keras_test.py index 4df33e8ab8b..4ebaf21f91e 100644 --- a/tensorboard/plugins/hparams/_keras_test.py +++ b/tensorboard/plugins/hparams/_keras_test.py @@ -63,7 +63,7 @@ def mock_time(): initial_time = mock_time.time with mock.patch("time.time", mock_time): self._initialize_model(writer=self.logdir) - self.model.fit(x=[1], y=[2], callbacks=[self.callback]) + self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) final_time = mock_time.time files = os.listdir(self.logdir) @@ -136,7 +136,7 @@ def test_explicit_writer(self): filename_suffix=".magic", ) self._initialize_model(writer=writer) - self.model.fit(x=[1], y=[2], callbacks=[self.callback]) + self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) files = os.listdir(self.logdir) self.assertEqual(len(files), 1, files) @@ -152,15 +152,15 @@ def test_non_eager_failure(self): with self.assertRaisesRegex( RuntimeError, "only supported in TensorFlow eager mode" ): - self.model.fit(x=[1], y=[2], callbacks=[self.callback]) + self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) def test_reuse_failure(self): self._initialize_model(writer=self.logdir) - self.model.fit(x=[1], y=[2], callbacks=[self.callback]) + self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) with self.assertRaisesRegex( RuntimeError, "cannot be reused across training sessions" ): - self.model.fit(x=[1], y=[2], callbacks=[self.callback]) + self.model.fit(x=[(1,)], y=[(2,)], callbacks=[self.callback]) def test_invalid_writer(self): with self.assertRaisesRegex( From 9e4fd172bcd33dc0cbe8b193f36c55aa32e603dd Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 20:15:56 +0000 Subject: [PATCH 06/18] stay on Keras 2 for the time being --- tensorboard/plugins/graph/graphs_plugin.py | 8 +++++++- tensorboard/plugins/graph/keras_util_test.py | 7 +++++++ tensorboard/plugins/hparams/_keras_test.py | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tensorboard/plugins/graph/graphs_plugin.py b/tensorboard/plugins/graph/graphs_plugin.py index b361e7732a6..db3253132ee 100644 --- a/tensorboard/plugins/graph/graphs_plugin.py +++ b/tensorboard/plugins/graph/graphs_plugin.py @@ -14,7 +14,6 @@ # ============================================================================== """The TensorBoard Graphs plugin.""" - import json from werkzeug import wrappers @@ -31,6 +30,13 @@ from tensorboard.plugins.graph import metadata from tensorboard.util import tb_logging +# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. +version_fn = getattr(tf.keras, "version", None) +if version_fn and version_fn().startswith("3."): + import tf_keras as keras # Keras 2 +else: + keras = tf.keras # Keras 2 + logger = tb_logging.get_logger() diff --git a/tensorboard/plugins/graph/keras_util_test.py b/tensorboard/plugins/graph/keras_util_test.py index bc66e0607c4..1139b6ab6bc 100644 --- a/tensorboard/plugins/graph/keras_util_test.py +++ b/tensorboard/plugins/graph/keras_util_test.py @@ -21,6 +21,13 @@ from tensorboard.plugins.graph import keras_util +# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. +version_fn = getattr(tf.keras, "version", None) +if version_fn and version_fn().startswith("3."): + import tf_keras as keras # Keras 2 +else: + keras = tf.keras # Keras 2 + class KerasUtilTest(tf.test.TestCase): def assertGraphDefToModel(self, expected_proto, model): diff --git a/tensorboard/plugins/hparams/_keras_test.py b/tensorboard/plugins/hparams/_keras_test.py index 4ebaf21f91e..2f0e114032b 100644 --- a/tensorboard/plugins/hparams/_keras_test.py +++ b/tensorboard/plugins/hparams/_keras_test.py @@ -25,6 +25,12 @@ from tensorboard.plugins.hparams import plugin_data_pb2 from tensorboard.plugins.hparams import summary_v2 as hp +# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. +version_fn = getattr(tf.keras, "version", None) +if version_fn and version_fn().startswith("3."): + import tf_keras as keras # Keras 2 +else: + keras = tf.keras # Keras 2 tf.compat.v1.enable_eager_execution() From 9fd869aefd7d425626f1fc756f9997a70d7b9c3c Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 20:22:23 +0000 Subject: [PATCH 07/18] oops, added the code to the wrong file, fixing --- tensorboard/plugins/graph/graphs_plugin.py | 7 ------- tensorboard/plugins/graph/graphs_plugin_v2_test.py | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tensorboard/plugins/graph/graphs_plugin.py b/tensorboard/plugins/graph/graphs_plugin.py index db3253132ee..4b803066525 100644 --- a/tensorboard/plugins/graph/graphs_plugin.py +++ b/tensorboard/plugins/graph/graphs_plugin.py @@ -30,13 +30,6 @@ from tensorboard.plugins.graph import metadata from tensorboard.util import tb_logging -# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. -version_fn = getattr(tf.keras, "version", None) -if version_fn and version_fn().startswith("3."): - import tf_keras as keras # Keras 2 -else: - keras = tf.keras # Keras 2 - logger = tb_logging.get_logger() diff --git a/tensorboard/plugins/graph/graphs_plugin_v2_test.py b/tensorboard/plugins/graph/graphs_plugin_v2_test.py index 8fdb02a1afd..d6bf3602172 100644 --- a/tensorboard/plugins/graph/graphs_plugin_v2_test.py +++ b/tensorboard/plugins/graph/graphs_plugin_v2_test.py @@ -24,6 +24,13 @@ from tensorboard.compat.proto import graph_pb2 from tensorboard.plugins.graph import graphs_plugin_test +# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. +version_fn = getattr(tf.keras, "version", None) +if version_fn and version_fn().startswith("3."): + import tf_keras as keras # Keras 2 +else: + keras = tf.keras # Keras 2 + class GraphsPluginV2Test( graphs_plugin_test.GraphsPluginBaseTest, tf.test.TestCase From 01541f85fc1879826133fcf0a6b48a42834f2fec Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 20:49:27 +0000 Subject: [PATCH 08/18] install tf-keras --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4670ed4f3f8..e62090b4235 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,6 +78,11 @@ jobs: python -m pip install -U pip pip install "${TENSORFLOW_VERSION}" if: matrix.tf_version_id != 'notf' + # TODO: Remove this after migrating to Keras 3. + - name: 'Install tf-keras (Keras 2)' + run: | + python -m pip install -U pip + pip install tf-keras - name: 'Install Python dependencies' run: | python -m pip install -U pip From 50781d6df07d37a2abf532b2fb557e83c8217889 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 20:52:10 +0000 Subject: [PATCH 09/18] rm white space --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e62090b4235..55f6e7fd9dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,7 @@ jobs: python -m pip install -U pip pip install "${TENSORFLOW_VERSION}" if: matrix.tf_version_id != 'notf' - # TODO: Remove this after migrating to Keras 3. + # TODO: Remove this after migrating to Keras 3. - name: 'Install tf-keras (Keras 2)' run: | python -m pip install -U pip From 32f879d70de7d413beaf70fa961ea5441c9af629 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 21:15:47 +0000 Subject: [PATCH 10/18] update relevant test code to use Keras 2 --- .../plugins/graph/graphs_plugin_v2_test.py | 6 +- tensorboard/plugins/graph/keras_util_test.py | 118 +++++++++--------- tensorboard/plugins/hparams/_keras_test.py | 6 +- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/tensorboard/plugins/graph/graphs_plugin_v2_test.py b/tensorboard/plugins/graph/graphs_plugin_v2_test.py index d6bf3602172..e2e62f68966 100644 --- a/tensorboard/plugins/graph/graphs_plugin_v2_test.py +++ b/tensorboard/plugins/graph/graphs_plugin_v2_test.py @@ -41,10 +41,10 @@ def generate_run( x, y = np.ones((10, 10)), np.ones((10, 1)) val_x, val_y = np.ones((4, 10)), np.ones((4, 1)) - model = tf.keras.Sequential( + model = keras.Sequential( [ - tf.keras.layers.Dense(10, activation="relu"), - tf.keras.layers.Dense(1, activation="sigmoid"), + keras.layers.Dense(10, activation="relu"), + keras.layers.Dense(1, activation="sigmoid"), ] ) model.compile("rmsprop", "binary_crossentropy") diff --git a/tensorboard/plugins/graph/keras_util_test.py b/tensorboard/plugins/graph/keras_util_test.py index 1139b6ab6bc..4dae5ae1ae7 100644 --- a/tensorboard/plugins/graph/keras_util_test.py +++ b/tensorboard/plugins/graph/keras_util_test.py @@ -119,12 +119,12 @@ def DISABLED_test_keras_model_to_graph_def_sequential_model(self): } } """ - model = tf.keras.models.Sequential( + model = keras.models.Sequential( [ - tf.keras.layers.Dense(32, input_shape=(784,)), - tf.keras.layers.Activation("relu", name="my_relu"), - tf.keras.layers.Dense(10), - tf.keras.layers.Activation("softmax"), + keras.layers.Dense(32, input_shape=(784,)), + keras.layers.Activation("relu", name="my_relu"), + keras.layers.Dense(10), + keras.layers.Activation("softmax"), ] ) self.assertGraphDefToModel(expected_proto, model) @@ -195,12 +195,12 @@ def test_keras_model_to_graph_def_functional_model(self): } } """ - inputs = tf.keras.layers.Input(shape=(784,), name="functional_input") - d0 = tf.keras.layers.Dense(64, activation="relu") - d1 = tf.keras.layers.Dense(64, activation="relu") - d2 = tf.keras.layers.Dense(64, activation="relu") + inputs = keras.layers.Input(shape=(784,), name="functional_input") + d0 = keras.layers.Dense(64, activation="relu") + d1 = keras.layers.Dense(64, activation="relu") + d2 = keras.layers.Dense(64, activation="relu") - model = tf.keras.models.Model( + model = keras.models.Model( inputs=inputs, outputs=d2(d1(d0(inputs))), name="model" ) self.assertGraphDefToModel(expected_proto, model) @@ -272,12 +272,12 @@ def test_keras_model_to_graph_def_functional_model_with_cycle(self): } } """ - inputs = tf.keras.layers.Input(shape=(784,), name="cycle_input") - d0 = tf.keras.layers.Dense(64, activation="relu") - d1 = tf.keras.layers.Dense(64, activation="relu") - d2 = tf.keras.layers.Dense(64, activation="relu") + inputs = keras.layers.Input(shape=(784,), name="cycle_input") + d0 = keras.layers.Dense(64, activation="relu") + d1 = keras.layers.Dense(64, activation="relu") + d2 = keras.layers.Dense(64, activation="relu") - model = tf.keras.models.Model( + model = keras.models.Model( inputs=inputs, outputs=d1(d2(d1(d0(inputs)))), name="model" ) self.assertGraphDefToModel(expected_proto, model) @@ -316,10 +316,10 @@ def test_keras_model_to_graph_def_lstm_model(self): } } """ - inputs = tf.keras.layers.Input(shape=(None, 5), name="lstm_input") - encoder = tf.keras.layers.SimpleRNN(256) + inputs = keras.layers.Input(shape=(None, 5), name="lstm_input") + encoder = keras.layers.SimpleRNN(256) - model = tf.keras.models.Model( + model = keras.models.Model( inputs=inputs, outputs=encoder(inputs), name="model" ) self.assertGraphDefToModel(expected_proto, model) @@ -454,25 +454,25 @@ def DISABLED_test_keras_model_to_graph_def_nested_sequential_model(self): } } """ - sub_sub_model = tf.keras.models.Sequential( + sub_sub_model = keras.models.Sequential( [ - tf.keras.layers.Dense(32, input_shape=(784,)), - tf.keras.layers.Activation("relu"), + keras.layers.Dense(32, input_shape=(784,)), + keras.layers.Activation("relu"), ] ) - sub_model = tf.keras.models.Sequential( + sub_model = keras.models.Sequential( [ sub_sub_model, - tf.keras.layers.Activation("relu", name="my_relu"), + keras.layers.Activation("relu", name="my_relu"), ] ) - model = tf.keras.models.Sequential( + model = keras.models.Sequential( [ sub_model, - tf.keras.layers.Dense(10), - tf.keras.layers.Activation("softmax"), + keras.layers.Dense(10), + keras.layers.Activation("softmax"), ] ) @@ -608,27 +608,27 @@ def test_keras_model_to_graph_def_functional_multi_inputs(self): } } """ - main_input = tf.keras.layers.Input( + main_input = keras.layers.Input( shape=(100,), dtype="int32", name="main_input" ) - x = tf.keras.layers.Embedding( + x = keras.layers.Embedding( output_dim=512, input_dim=10000, input_length=100 )(main_input) - rnn_out = tf.keras.layers.SimpleRNN(32)(x) + rnn_out = keras.layers.SimpleRNN(32)(x) - auxiliary_output = tf.keras.layers.Dense( + auxiliary_output = keras.layers.Dense( 1, activation="sigmoid", name="aux_output" )(rnn_out) - auxiliary_input = tf.keras.layers.Input(shape=(5,), name="aux_input") + auxiliary_input = keras.layers.Input(shape=(5,), name="aux_input") - x = tf.keras.layers.concatenate([rnn_out, auxiliary_input]) - x = tf.keras.layers.Dense(64, activation="relu")(x) + x = keras.layers.concatenate([rnn_out, auxiliary_input]) + x = keras.layers.Dense(64, activation="relu")(x) - main_output = tf.keras.layers.Dense( + main_output = keras.layers.Dense( 1, activation="sigmoid", name="main_output" )(x) - model = tf.keras.models.Model( + model = keras.models.Model( inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output], name="model", @@ -764,22 +764,22 @@ def test_keras_model_to_graph_def_functional_model_as_layer(self): } } """ - inputs1 = tf.keras.layers.Input(shape=(784,), name="sub_func_input_1") - inputs2 = tf.keras.layers.Input(shape=(784,), name="sub_func_input_2") - d0 = tf.keras.layers.Dense(64, activation="relu") - d1 = tf.keras.layers.Dense(64, activation="relu") - d2 = tf.keras.layers.Dense(64, activation="relu") + inputs1 = keras.layers.Input(shape=(784,), name="sub_func_input_1") + inputs2 = keras.layers.Input(shape=(784,), name="sub_func_input_2") + d0 = keras.layers.Dense(64, activation="relu") + d1 = keras.layers.Dense(64, activation="relu") + d2 = keras.layers.Dense(64, activation="relu") - sub_model = tf.keras.models.Model( + sub_model = keras.models.Model( inputs=[inputs2, inputs1], outputs=[d0(inputs1), d1(inputs2)], name="model", ) main_outputs = d2( - tf.keras.layers.concatenate(sub_model([inputs2, inputs1])) + keras.layers.concatenate(sub_model([inputs2, inputs1])) ) - model = tf.keras.models.Model( + model = keras.models.Model( inputs=[inputs2, inputs1], outputs=main_outputs, name="model_1", @@ -871,16 +871,16 @@ def DISABLED_test_keras_model_to_graph_def_functional_sequential_model( } } """ - inputs = tf.keras.layers.Input(shape=(784,), name="func_seq_input") - sub_model = tf.keras.models.Sequential( + inputs = keras.layers.Input(shape=(784,), name="func_seq_input") + sub_model = keras.models.Sequential( [ - tf.keras.layers.Dense(32, input_shape=(784,)), - tf.keras.layers.Activation("relu", name="my_relu"), + keras.layers.Dense(32, input_shape=(784,)), + keras.layers.Activation("relu", name="my_relu"), ] ) - dense = tf.keras.layers.Dense(64, activation="relu") + dense = keras.layers.Dense(64, activation="relu") - model = tf.keras.models.Model( + model = keras.models.Model( inputs=inputs, outputs=dense(sub_model(inputs)) ) @@ -969,15 +969,15 @@ def DISABLED_test_keras_model_to_graph_def_sequential_functional_model( } } """ - inputs = tf.keras.layers.Input(shape=(784,), name="func_seq_input") - dense = tf.keras.layers.Dense(64, activation="relu") + inputs = keras.layers.Input(shape=(784,), name="func_seq_input") + dense = keras.layers.Dense(64, activation="relu") - sub_model = tf.keras.models.Model(inputs=inputs, outputs=dense(inputs)) - model = tf.keras.models.Sequential( + sub_model = keras.models.Model(inputs=inputs, outputs=dense(inputs)) + model = keras.models.Sequential( [ sub_model, - tf.keras.layers.Dense(32, input_shape=(784,)), - tf.keras.layers.Activation("relu", name="my_relu"), + keras.layers.Dense(32, input_shape=(784,)), + keras.layers.Activation("relu", name="my_relu"), ] ) @@ -1036,16 +1036,16 @@ def test_keras_model_to_graph_def_functional_multiple_inbound_nodes_from_same_no } } """ - inputs = tf.keras.Input(shape=(2,)) + inputs = keras.Input(shape=(2,)) doubling_layer = _DoublingLayer() - reducing_layer = tf.keras.layers.Add() + reducing_layer = keras.layers.Add() outputs = reducing_layer(doubling_layer(inputs)) - model = tf.keras.Model(inputs=[inputs], outputs=outputs) + model = keras.Model(inputs=[inputs], outputs=outputs) self.assertGraphDefToModel(expected_proto, model) -class _DoublingLayer(tf.keras.layers.Layer): +class _DoublingLayer(keras.layers.Layer): def call(self, inputs): return inputs, inputs diff --git a/tensorboard/plugins/hparams/_keras_test.py b/tensorboard/plugins/hparams/_keras_test.py index 2f0e114032b..42cbe30c966 100644 --- a/tensorboard/plugins/hparams/_keras_test.py +++ b/tensorboard/plugins/hparams/_keras_test.py @@ -46,12 +46,12 @@ def _initialize_model(self, writer): "optimizer": "adam", HP_DENSE_NEURONS: 8, } - self.model = tf.keras.models.Sequential( + self.model = keras.models.Sequential( [ - tf.keras.layers.Dense( + keras.layers.Dense( self.hparams[HP_DENSE_NEURONS], input_shape=(1,) ), - tf.keras.layers.Dense(1, activation="sigmoid"), + keras.layers.Dense(1, activation="sigmoid"), ] ) self.model.compile(loss="mse", optimizer=self.hparams["optimizer"]) From 3730c28465844a70a7b53a2a5a5f6b738a306f8b Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 21:18:39 +0000 Subject: [PATCH 11/18] rm accidentally added newline --- tensorboard/plugins/graph/graphs_plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tensorboard/plugins/graph/graphs_plugin.py b/tensorboard/plugins/graph/graphs_plugin.py index 4b803066525..b361e7732a6 100644 --- a/tensorboard/plugins/graph/graphs_plugin.py +++ b/tensorboard/plugins/graph/graphs_plugin.py @@ -14,6 +14,7 @@ # ============================================================================== """The TensorBoard Graphs plugin.""" + import json from werkzeug import wrappers From df4ae08a24605f1608185e5ef7ffaa677ba0cc45 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 21:21:35 +0000 Subject: [PATCH 12/18] use tf-keras-nightly --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55f6e7fd9dc..48e997bc948 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ env: BUILDIFIER_SHA256SUM: 'e92a6793c7134c5431c58fbc34700664f101e5c9b1c1fcd93b97978e8b7f88db' BUILDOZER_SHA256SUM: '3d58a0b6972e4535718cdd6c12778170ea7382de7c75bc3728f5719437ffb84d' TENSORFLOW_VERSION: 'tf-nightly' + TF_KERAS_VERSION: 'tf-keras-nightly' # Keras 2 jobs: build: @@ -79,10 +80,10 @@ jobs: pip install "${TENSORFLOW_VERSION}" if: matrix.tf_version_id != 'notf' # TODO: Remove this after migrating to Keras 3. - - name: 'Install tf-keras (Keras 2)' + - name: 'Install TF-Keras (Keras 2)' run: | python -m pip install -U pip - pip install tf-keras + pip install "${TF_KERAS_VERSION}" - name: 'Install Python dependencies' run: | python -m pip install -U pip From c33e46a2e12e9567b98adb3b71f959009700e37d Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Wed, 15 Nov 2023 22:16:36 +0000 Subject: [PATCH 13/18] fix --- tensorboard/plugins/graph/graphs_plugin_v2_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tensorboard/plugins/graph/graphs_plugin_v2_test.py b/tensorboard/plugins/graph/graphs_plugin_v2_test.py index e2e62f68966..baf0c1645d2 100644 --- a/tensorboard/plugins/graph/graphs_plugin_v2_test.py +++ b/tensorboard/plugins/graph/graphs_plugin_v2_test.py @@ -56,7 +56,7 @@ def generate_run( batch_size=2, epochs=1, callbacks=[ - tf.compat.v2.keras.callbacks.TensorBoard( + keras.callbacks.TensorBoard( log_dir=os.path.join(logdir, run_name), write_graph=include_graph, ) From 3def2eb9105e1e0b68c15c2f30f3215e4da64c76 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Thu, 16 Nov 2023 00:18:58 +0000 Subject: [PATCH 14/18] use keras 2 --- tensorboard/plugins/hparams/_keras.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tensorboard/plugins/hparams/_keras.py b/tensorboard/plugins/hparams/_keras.py index dc57c09301a..004704dca29 100644 --- a/tensorboard/plugins/hparams/_keras.py +++ b/tensorboard/plugins/hparams/_keras.py @@ -24,8 +24,15 @@ from tensorboard.plugins.hparams import summary from tensorboard.plugins.hparams import summary_v2 +# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. +version_fn = getattr(tf.keras, "version", None) +if version_fn and version_fn().startswith("3."): + import tf_keras as keras # Keras 2 +else: + keras = tf.keras # Keras 2 -class Callback(tf.keras.callbacks.Callback): + +class Callback(keras.callbacks.Callback): """Callback for logging hyperparameters to TensorBoard. NOTE: This callback only works in TensorFlow eager mode. @@ -34,7 +41,7 @@ class Callback(tf.keras.callbacks.Callback): def __init__(self, writer, hparams, trial_id=None): """Create a callback for logging hyperparameters to TensorBoard. - As with the standard `tf.keras.callbacks.TensorBoard` class, each + As with the standard `keras.callbacks.TensorBoard` class, each callback object is valid for only one call to `model.fit`. Args: From 76f3af30e215a7508f1fc6b282f2bb83d7a6ad18 Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Thu, 16 Nov 2023 18:15:59 +0000 Subject: [PATCH 15/18] add tf-keras as an requirement for Hparams plugin --- tensorboard/pip_package/requirements.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tensorboard/pip_package/requirements.txt b/tensorboard/pip_package/requirements.txt index 4f6a36ef44f..c5923ec0040 100644 --- a/tensorboard/pip_package/requirements.txt +++ b/tensorboard/pip_package/requirements.txt @@ -35,3 +35,6 @@ setuptools >= 41.0.0 # Note: provides pkg_resources as well as setuptools six > 1.9 tensorboard-data-server >= 0.7.0, < 0.8.0 werkzeug >= 1.0.1 +# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. +# TODO: Remove this after migrating to Keras 3. +tf-keras >= 2.15.0 From 8c35eb3fcd5e4c7e6cf62c9cc2469051c20c541c Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Thu, 16 Nov 2023 18:38:28 +0000 Subject: [PATCH 16/18] keep the alphabetical order --- tensorboard/pip_package/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tensorboard/pip_package/requirements.txt b/tensorboard/pip_package/requirements.txt index c5923ec0040..61884f35924 100644 --- a/tensorboard/pip_package/requirements.txt +++ b/tensorboard/pip_package/requirements.txt @@ -34,7 +34,7 @@ setuptools >= 41.0.0 # Note: provides pkg_resources as well as setuptools # requirement, and likely this will not disrupt existing users of the package. six > 1.9 tensorboard-data-server >= 0.7.0, < 0.8.0 -werkzeug >= 1.0.1 # Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467. # TODO: Remove this after migrating to Keras 3. tf-keras >= 2.15.0 +werkzeug >= 1.0.1 \ No newline at end of file From 6604db45e9cedd99228a14466faa2b0dd95ebf9d Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Thu, 16 Nov 2023 19:15:51 +0000 Subject: [PATCH 17/18] use tf-keras-nightly when using tf-nightly --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48e997bc948..44f2d0b7175 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,11 +79,12 @@ jobs: python -m pip install -U pip pip install "${TENSORFLOW_VERSION}" if: matrix.tf_version_id != 'notf' + # Replace the `tf-keras` with `tf-keras-nightly` in the requirements.txt + # to avoid incompatibilities when using alongside `tf-nightly`. # TODO: Remove this after migrating to Keras 3. - - name: 'Install TF-Keras (Keras 2)' + - name: 'Make user to use tf-keras-nightly with tf-nightly' run: | - python -m pip install -U pip - pip install "${TF_KERAS_VERSION}" + sed -i "s/tf-keras/${TF_KERAS_VERSION}/g" ./tensorboard/pip_package/requirements.txt - name: 'Install Python dependencies' run: | python -m pip install -U pip From 62a5cf864616c58e297a3dd16e1951caf2cace4b Mon Sep 17 00:00:00 2001 From: Yating Jing Date: Thu, 16 Nov 2023 19:20:30 +0000 Subject: [PATCH 18/18] match and replace the whole line --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44f2d0b7175..9f9aa0b7f3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: # TODO: Remove this after migrating to Keras 3. - name: 'Make user to use tf-keras-nightly with tf-nightly' run: | - sed -i "s/tf-keras/${TF_KERAS_VERSION}/g" ./tensorboard/pip_package/requirements.txt + sed -i "s/^tf-keras.*/${TF_KERAS_VERSION}/g" ./tensorboard/pip_package/requirements.txt - name: 'Install Python dependencies' run: | python -m pip install -U pip