Skip to content

Commit cf175ea

Browse files
authored
CI: Unpin tf-nightly and stay on Keras 2 (#6684)
`tf-nightly` was pinned at #6655 due to Keras 3 release. `Keras 2 <> Keras incompatibilities` (keras-team/keras#18467) are impacting the Graph plugin and Hparams plugin, since the two plugins are not being actively developed and updating the code to be Keras 3 compatible is non-trivial, enforce using Keras 2 for the time being. Note that `tf-nightly` is not compatible with `tf-keras` and needs to be used with `tf-keras-nightly` instead. Googlers, see b/309503942 for more context. Tested internally: cl/582334596 #oncall
1 parent 7439f46 commit cf175ea

File tree

6 files changed

+107
-70
lines changed

6 files changed

+107
-70
lines changed

.github/workflows/ci.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ env:
3030
BUILDTOOLS_VERSION: '3.0.0'
3131
BUILDIFIER_SHA256SUM: 'e92a6793c7134c5431c58fbc34700664f101e5c9b1c1fcd93b97978e8b7f88db'
3232
BUILDOZER_SHA256SUM: '3d58a0b6972e4535718cdd6c12778170ea7382de7c75bc3728f5719437ffb84d'
33-
TENSORFLOW_VERSION: 'tf-nightly==2.16.0.dev20231018'
33+
TENSORFLOW_VERSION: 'tf-nightly'
34+
TF_KERAS_VERSION: 'tf-keras-nightly' # Keras 2
3435

3536
jobs:
3637
build:
@@ -78,6 +79,12 @@ jobs:
7879
python -m pip install -U pip
7980
pip install "${TENSORFLOW_VERSION}"
8081
if: matrix.tf_version_id != 'notf'
82+
# Replace the `tf-keras` with `tf-keras-nightly` in the requirements.txt
83+
# to avoid incompatibilities when using alongside `tf-nightly`.
84+
# TODO: Remove this after migrating to Keras 3.
85+
- name: 'Make user to use tf-keras-nightly with tf-nightly'
86+
run: |
87+
sed -i "s/^tf-keras.*/${TF_KERAS_VERSION}/g" ./tensorboard/pip_package/requirements.txt
8188
- name: 'Install Python dependencies'
8289
run: |
8390
python -m pip install -U pip

tensorboard/pip_package/requirements.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ setuptools >= 41.0.0 # Note: provides pkg_resources as well as setuptools
3434
# requirement, and likely this will not disrupt existing users of the package.
3535
six > 1.9
3636
tensorboard-data-server >= 0.7.0, < 0.8.0
37-
werkzeug >= 1.0.1
37+
# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467.
38+
# TODO: Remove this after migrating to Keras 3.
39+
tf-keras >= 2.15.0
40+
werkzeug >= 1.0.1

tensorboard/plugins/graph/graphs_plugin_v2_test.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
from tensorboard.compat.proto import graph_pb2
2525
from tensorboard.plugins.graph import graphs_plugin_test
2626

27+
# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467.
28+
version_fn = getattr(tf.keras, "version", None)
29+
if version_fn and version_fn().startswith("3."):
30+
import tf_keras as keras # Keras 2
31+
else:
32+
keras = tf.keras # Keras 2
33+
2734

2835
class GraphsPluginV2Test(
2936
graphs_plugin_test.GraphsPluginBaseTest, tf.test.TestCase
@@ -34,10 +41,10 @@ def generate_run(
3441
x, y = np.ones((10, 10)), np.ones((10, 1))
3542
val_x, val_y = np.ones((4, 10)), np.ones((4, 1))
3643

37-
model = tf.keras.Sequential(
44+
model = keras.Sequential(
3845
[
39-
tf.keras.layers.Dense(10, activation="relu"),
40-
tf.keras.layers.Dense(1, activation="sigmoid"),
46+
keras.layers.Dense(10, activation="relu"),
47+
keras.layers.Dense(1, activation="sigmoid"),
4148
]
4249
)
4350
model.compile("rmsprop", "binary_crossentropy")
@@ -49,7 +56,7 @@ def generate_run(
4956
batch_size=2,
5057
epochs=1,
5158
callbacks=[
52-
tf.compat.v2.keras.callbacks.TensorBoard(
59+
keras.callbacks.TensorBoard(
5360
log_dir=os.path.join(logdir, run_name),
5461
write_graph=include_graph,
5562
)

tensorboard/plugins/graph/keras_util_test.py

+66-59
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121

2222
from tensorboard.plugins.graph import keras_util
2323

24+
# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467.
25+
version_fn = getattr(tf.keras, "version", None)
26+
if version_fn and version_fn().startswith("3."):
27+
import tf_keras as keras # Keras 2
28+
else:
29+
keras = tf.keras # Keras 2
30+
2431

2532
class KerasUtilTest(tf.test.TestCase):
2633
def assertGraphDefToModel(self, expected_proto, model):
@@ -112,12 +119,12 @@ def DISABLED_test_keras_model_to_graph_def_sequential_model(self):
112119
}
113120
}
114121
"""
115-
model = tf.keras.models.Sequential(
122+
model = keras.models.Sequential(
116123
[
117-
tf.keras.layers.Dense(32, input_shape=(784,)),
118-
tf.keras.layers.Activation("relu", name="my_relu"),
119-
tf.keras.layers.Dense(10),
120-
tf.keras.layers.Activation("softmax"),
124+
keras.layers.Dense(32, input_shape=(784,)),
125+
keras.layers.Activation("relu", name="my_relu"),
126+
keras.layers.Dense(10),
127+
keras.layers.Activation("softmax"),
121128
]
122129
)
123130
self.assertGraphDefToModel(expected_proto, model)
@@ -188,12 +195,12 @@ def test_keras_model_to_graph_def_functional_model(self):
188195
}
189196
}
190197
"""
191-
inputs = tf.keras.layers.Input(shape=(784,), name="functional_input")
192-
d0 = tf.keras.layers.Dense(64, activation="relu")
193-
d1 = tf.keras.layers.Dense(64, activation="relu")
194-
d2 = tf.keras.layers.Dense(64, activation="relu")
198+
inputs = keras.layers.Input(shape=(784,), name="functional_input")
199+
d0 = keras.layers.Dense(64, activation="relu")
200+
d1 = keras.layers.Dense(64, activation="relu")
201+
d2 = keras.layers.Dense(64, activation="relu")
195202

196-
model = tf.keras.models.Model(
203+
model = keras.models.Model(
197204
inputs=inputs, outputs=d2(d1(d0(inputs))), name="model"
198205
)
199206
self.assertGraphDefToModel(expected_proto, model)
@@ -265,12 +272,12 @@ def test_keras_model_to_graph_def_functional_model_with_cycle(self):
265272
}
266273
}
267274
"""
268-
inputs = tf.keras.layers.Input(shape=(784,), name="cycle_input")
269-
d0 = tf.keras.layers.Dense(64, activation="relu")
270-
d1 = tf.keras.layers.Dense(64, activation="relu")
271-
d2 = tf.keras.layers.Dense(64, activation="relu")
275+
inputs = keras.layers.Input(shape=(784,), name="cycle_input")
276+
d0 = keras.layers.Dense(64, activation="relu")
277+
d1 = keras.layers.Dense(64, activation="relu")
278+
d2 = keras.layers.Dense(64, activation="relu")
272279

273-
model = tf.keras.models.Model(
280+
model = keras.models.Model(
274281
inputs=inputs, outputs=d1(d2(d1(d0(inputs)))), name="model"
275282
)
276283
self.assertGraphDefToModel(expected_proto, model)
@@ -309,10 +316,10 @@ def test_keras_model_to_graph_def_lstm_model(self):
309316
}
310317
}
311318
"""
312-
inputs = tf.keras.layers.Input(shape=(None, 5), name="lstm_input")
313-
encoder = tf.keras.layers.SimpleRNN(256)
319+
inputs = keras.layers.Input(shape=(None, 5), name="lstm_input")
320+
encoder = keras.layers.SimpleRNN(256)
314321

315-
model = tf.keras.models.Model(
322+
model = keras.models.Model(
316323
inputs=inputs, outputs=encoder(inputs), name="model"
317324
)
318325
self.assertGraphDefToModel(expected_proto, model)
@@ -447,25 +454,25 @@ def DISABLED_test_keras_model_to_graph_def_nested_sequential_model(self):
447454
}
448455
}
449456
"""
450-
sub_sub_model = tf.keras.models.Sequential(
457+
sub_sub_model = keras.models.Sequential(
451458
[
452-
tf.keras.layers.Dense(32, input_shape=(784,)),
453-
tf.keras.layers.Activation("relu"),
459+
keras.layers.Dense(32, input_shape=(784,)),
460+
keras.layers.Activation("relu"),
454461
]
455462
)
456463

457-
sub_model = tf.keras.models.Sequential(
464+
sub_model = keras.models.Sequential(
458465
[
459466
sub_sub_model,
460-
tf.keras.layers.Activation("relu", name="my_relu"),
467+
keras.layers.Activation("relu", name="my_relu"),
461468
]
462469
)
463470

464-
model = tf.keras.models.Sequential(
471+
model = keras.models.Sequential(
465472
[
466473
sub_model,
467-
tf.keras.layers.Dense(10),
468-
tf.keras.layers.Activation("softmax"),
474+
keras.layers.Dense(10),
475+
keras.layers.Activation("softmax"),
469476
]
470477
)
471478

@@ -601,27 +608,27 @@ def test_keras_model_to_graph_def_functional_multi_inputs(self):
601608
}
602609
}
603610
"""
604-
main_input = tf.keras.layers.Input(
611+
main_input = keras.layers.Input(
605612
shape=(100,), dtype="int32", name="main_input"
606613
)
607-
x = tf.keras.layers.Embedding(
614+
x = keras.layers.Embedding(
608615
output_dim=512, input_dim=10000, input_length=100
609616
)(main_input)
610-
rnn_out = tf.keras.layers.SimpleRNN(32)(x)
617+
rnn_out = keras.layers.SimpleRNN(32)(x)
611618

612-
auxiliary_output = tf.keras.layers.Dense(
619+
auxiliary_output = keras.layers.Dense(
613620
1, activation="sigmoid", name="aux_output"
614621
)(rnn_out)
615-
auxiliary_input = tf.keras.layers.Input(shape=(5,), name="aux_input")
622+
auxiliary_input = keras.layers.Input(shape=(5,), name="aux_input")
616623

617-
x = tf.keras.layers.concatenate([rnn_out, auxiliary_input])
618-
x = tf.keras.layers.Dense(64, activation="relu")(x)
624+
x = keras.layers.concatenate([rnn_out, auxiliary_input])
625+
x = keras.layers.Dense(64, activation="relu")(x)
619626

620-
main_output = tf.keras.layers.Dense(
627+
main_output = keras.layers.Dense(
621628
1, activation="sigmoid", name="main_output"
622629
)(x)
623630

624-
model = tf.keras.models.Model(
631+
model = keras.models.Model(
625632
inputs=[main_input, auxiliary_input],
626633
outputs=[main_output, auxiliary_output],
627634
name="model",
@@ -757,22 +764,22 @@ def test_keras_model_to_graph_def_functional_model_as_layer(self):
757764
}
758765
}
759766
"""
760-
inputs1 = tf.keras.layers.Input(shape=(784,), name="sub_func_input_1")
761-
inputs2 = tf.keras.layers.Input(shape=(784,), name="sub_func_input_2")
762-
d0 = tf.keras.layers.Dense(64, activation="relu")
763-
d1 = tf.keras.layers.Dense(64, activation="relu")
764-
d2 = tf.keras.layers.Dense(64, activation="relu")
767+
inputs1 = keras.layers.Input(shape=(784,), name="sub_func_input_1")
768+
inputs2 = keras.layers.Input(shape=(784,), name="sub_func_input_2")
769+
d0 = keras.layers.Dense(64, activation="relu")
770+
d1 = keras.layers.Dense(64, activation="relu")
771+
d2 = keras.layers.Dense(64, activation="relu")
765772

766-
sub_model = tf.keras.models.Model(
773+
sub_model = keras.models.Model(
767774
inputs=[inputs2, inputs1],
768775
outputs=[d0(inputs1), d1(inputs2)],
769776
name="model",
770777
)
771778

772779
main_outputs = d2(
773-
tf.keras.layers.concatenate(sub_model([inputs2, inputs1]))
780+
keras.layers.concatenate(sub_model([inputs2, inputs1]))
774781
)
775-
model = tf.keras.models.Model(
782+
model = keras.models.Model(
776783
inputs=[inputs2, inputs1],
777784
outputs=main_outputs,
778785
name="model_1",
@@ -864,16 +871,16 @@ def DISABLED_test_keras_model_to_graph_def_functional_sequential_model(
864871
}
865872
}
866873
"""
867-
inputs = tf.keras.layers.Input(shape=(784,), name="func_seq_input")
868-
sub_model = tf.keras.models.Sequential(
874+
inputs = keras.layers.Input(shape=(784,), name="func_seq_input")
875+
sub_model = keras.models.Sequential(
869876
[
870-
tf.keras.layers.Dense(32, input_shape=(784,)),
871-
tf.keras.layers.Activation("relu", name="my_relu"),
877+
keras.layers.Dense(32, input_shape=(784,)),
878+
keras.layers.Activation("relu", name="my_relu"),
872879
]
873880
)
874-
dense = tf.keras.layers.Dense(64, activation="relu")
881+
dense = keras.layers.Dense(64, activation="relu")
875882

876-
model = tf.keras.models.Model(
883+
model = keras.models.Model(
877884
inputs=inputs, outputs=dense(sub_model(inputs))
878885
)
879886

@@ -962,15 +969,15 @@ def DISABLED_test_keras_model_to_graph_def_sequential_functional_model(
962969
}
963970
}
964971
"""
965-
inputs = tf.keras.layers.Input(shape=(784,), name="func_seq_input")
966-
dense = tf.keras.layers.Dense(64, activation="relu")
972+
inputs = keras.layers.Input(shape=(784,), name="func_seq_input")
973+
dense = keras.layers.Dense(64, activation="relu")
967974

968-
sub_model = tf.keras.models.Model(inputs=inputs, outputs=dense(inputs))
969-
model = tf.keras.models.Sequential(
975+
sub_model = keras.models.Model(inputs=inputs, outputs=dense(inputs))
976+
model = keras.models.Sequential(
970977
[
971978
sub_model,
972-
tf.keras.layers.Dense(32, input_shape=(784,)),
973-
tf.keras.layers.Activation("relu", name="my_relu"),
979+
keras.layers.Dense(32, input_shape=(784,)),
980+
keras.layers.Activation("relu", name="my_relu"),
974981
]
975982
)
976983

@@ -1029,16 +1036,16 @@ def test_keras_model_to_graph_def_functional_multiple_inbound_nodes_from_same_no
10291036
}
10301037
}
10311038
"""
1032-
inputs = tf.keras.Input(shape=(2,))
1039+
inputs = keras.Input(shape=(2,))
10331040
doubling_layer = _DoublingLayer()
1034-
reducing_layer = tf.keras.layers.Add()
1041+
reducing_layer = keras.layers.Add()
10351042
outputs = reducing_layer(doubling_layer(inputs))
1036-
model = tf.keras.Model(inputs=[inputs], outputs=outputs)
1043+
model = keras.Model(inputs=[inputs], outputs=outputs)
10371044

10381045
self.assertGraphDefToModel(expected_proto, model)
10391046

10401047

1041-
class _DoublingLayer(tf.keras.layers.Layer):
1048+
class _DoublingLayer(keras.layers.Layer):
10421049
def call(self, inputs):
10431050
return inputs, inputs
10441051

tensorboard/plugins/hparams/_keras.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@
2424
from tensorboard.plugins.hparams import summary
2525
from tensorboard.plugins.hparams import summary_v2
2626

27+
# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467.
28+
version_fn = getattr(tf.keras, "version", None)
29+
if version_fn and version_fn().startswith("3."):
30+
import tf_keras as keras # Keras 2
31+
else:
32+
keras = tf.keras # Keras 2
2733

28-
class Callback(tf.keras.callbacks.Callback):
34+
35+
class Callback(keras.callbacks.Callback):
2936
"""Callback for logging hyperparameters to TensorBoard.
3037
3138
NOTE: This callback only works in TensorFlow eager mode.
@@ -34,7 +41,7 @@ class Callback(tf.keras.callbacks.Callback):
3441
def __init__(self, writer, hparams, trial_id=None):
3542
"""Create a callback for logging hyperparameters to TensorBoard.
3643
37-
As with the standard `tf.keras.callbacks.TensorBoard` class, each
44+
As with the standard `keras.callbacks.TensorBoard` class, each
3845
callback object is valid for only one call to `model.fit`.
3946
4047
Args:

tensorboard/plugins/hparams/_keras_test.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
from tensorboard.plugins.hparams import plugin_data_pb2
2626
from tensorboard.plugins.hparams import summary_v2 as hp
2727

28+
# Stay on Keras 2 for now: https://github.com/keras-team/keras/issues/18467.
29+
version_fn = getattr(tf.keras, "version", None)
30+
if version_fn and version_fn().startswith("3."):
31+
import tf_keras as keras # Keras 2
32+
else:
33+
keras = tf.keras # Keras 2
2834

2935
tf.compat.v1.enable_eager_execution()
3036

@@ -40,12 +46,12 @@ def _initialize_model(self, writer):
4046
"optimizer": "adam",
4147
HP_DENSE_NEURONS: 8,
4248
}
43-
self.model = tf.keras.models.Sequential(
49+
self.model = keras.models.Sequential(
4450
[
45-
tf.keras.layers.Dense(
51+
keras.layers.Dense(
4652
self.hparams[HP_DENSE_NEURONS], input_shape=(1,)
4753
),
48-
tf.keras.layers.Dense(1, activation="sigmoid"),
54+
keras.layers.Dense(1, activation="sigmoid"),
4955
]
5056
)
5157
self.model.compile(loss="mse", optimizer=self.hparams["optimizer"])

0 commit comments

Comments
 (0)