From dfeaf4112bd7e18fac9bc8d79b95043b0c1e3081 Mon Sep 17 00:00:00 2001 From: Neel Kovelamudi <60985914+nkovela1@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:12:55 -0700 Subject: [PATCH 1/2] Fix legacy optimizer handling in `compile_from_config()`. --- keras/engine/training.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/keras/engine/training.py b/keras/engine/training.py index f8b2dbcfa2a..e6b0627ff63 100644 --- a/keras/engine/training.py +++ b/keras/engine/training.py @@ -3680,7 +3680,12 @@ def compile_from_config(self, config): return config = saving_lib.deserialize_keras_object(config) self.compile(**config) - if hasattr(self, "optimizer") and self.built: + if ( + hasattr(self, "optimizer") + # Exempt legacy optimizers. + and isinstance(self.optimizer, optimizer.Optimizer) + and self.built + ): # Create optimizer variables. self.optimizer.build(self.trainable_variables) From 4c87b8b67b9953484604c9e10fd8ca02fe81128e Mon Sep 17 00:00:00 2001 From: Neel Kovelamudi <60985914+nkovela1@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:15:34 -0700 Subject: [PATCH 2/2] Add associated test --- keras/optimizers/legacy/optimizer_v2_test.py | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/keras/optimizers/legacy/optimizer_v2_test.py b/keras/optimizers/legacy/optimizer_v2_test.py index 47ffec24453..2d6bbc14e1d 100644 --- a/keras/optimizers/legacy/optimizer_v2_test.py +++ b/keras/optimizers/legacy/optimizer_v2_test.py @@ -15,6 +15,7 @@ """Functional test for OptimizerV2.""" import collections +import os from copy import deepcopy import numpy as np @@ -568,6 +569,33 @@ def testOptimizerWithKerasModel(self): batch_size=5, ) + @test_combinations.generate(test_combinations.combine(mode=["eager"])) + def testOptimizerSaving(self): + np.random.seed(1331) + input_np = np.random.random((10, 3)) + output_np = np.random.random((10, 4)) + a = input_layer.Input(shape=(3,), name="input_a") + model = sequential.Sequential() + model.add(core.Dense(4, kernel_initializer="zeros", name="dense")) + model.add(regularization.Dropout(0.5, name="dropout")) + model(a) + optimizer = gradient_descent.SGD(learning_rate=0.1) + model.compile(optimizer, loss="mse", metrics=["mae"]) + + model.fit( + input_np, + output_np, + batch_size=10, + validation_data=(input_np, output_np), + epochs=2, + verbose=0, + ) + + temp_filepath = os.path.join(self.get_temp_dir(), "optv2_model.keras") + model.save(temp_filepath) + loaded_model = keras.models.load_model(temp_filepath) + self.assertAllClose(model(input_np), loaded_model(input_np), atol=1e-6) + @test_combinations.generate( test_combinations.combine(mode=["graph", "eager"]) )