We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
tuner use previous layer's output to adapt the next
<!-- STEP 1: Give the pull request a meaningful title. -->
### Which issue(s) does this Pull Request fix?
<!-- STEP 2: Replace the "000" with the issue ID this pull request resolves. -->
resolves #1312 

### Details of the Pull Request
<!-- STEP 3: Add details/comments on the pull request. -->

<!-- STEP 4: If the pull request is in progress, click the down green arrow to select "Create Draft Pull Request", and click the button. If the pull request is ready to be reviewed, click "Create Pull Request" button directly. -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `autokeras/engine/tuner.py`
Content:
```
1 # Copyright 2020 The AutoKeras Authors.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 import copy
16 import os
17 
18 import kerastuner
19 import tensorflow as tf
20 from kerastuner.engine import hypermodel as hm_module
21 from tensorflow.keras import callbacks as tf_callbacks
22 from tensorflow.keras.layers.experimental import preprocessing
23 from tensorflow.python.util import nest
24 
25 from autokeras.utils import utils
26 
27 
28 class AutoTuner(kerastuner.engine.tuner.Tuner):
29     """A Tuner class based on KerasTuner for AutoKeras.
30 
31     Different from KerasTuner's Tuner class. AutoTuner's not only tunes the
32     Hypermodel which can be directly built into a Keras model, but also the
33     preprocessors. Therefore, a HyperGraph stores the overall search space containing
34     both the Preprocessors and Hypermodel. For every trial, the HyperGraph build the
35     PreprocessGraph and KerasGraph with the provided HyperParameters.
36 
37     The AutoTuner uses EarlyStopping for acceleration during the search and fully
38     train the model with full epochs and with both training and validation data.
39     The fully trained model is the best model to be used by AutoModel.
40 
41     # Arguments
42         preprocessors: An instance or list of `Preprocessor` objects corresponding to
43             each AutoModel input, to preprocess a `tf.data.Dataset` before passing it
44             to the model. Defaults to None (no external preprocessing).
45         **kwargs: The args supported by KerasTuner.
46     """
47 
48     def __init__(self, oracle, hypermodel, preprocessors=None, **kwargs):
49         # Initialize before super() for reload to work.
50         self._finished = False
51         super().__init__(oracle, hypermodel, **kwargs)
52         self.preprocessors = nest.flatten(preprocessors)
53         # Save or load the HyperModel.
54         self.hypermodel.hypermodel.save(os.path.join(self.project_dir, "graph"))
55 
56     # Override the function to prevent building the model during initialization.
57     def _populate_initial_space(self):
58         pass
59 
60     def get_best_model(self):
61         model = self._build_best_model()
62         with hm_module.maybe_distribute(self.distribution_strategy):
63             model.load_weights(self.best_model_path)
64         return model
65 
66     def _on_train_begin(self, model, hp, x, *args, **kwargs):
67         """Adapt the preprocessing layers and tune the fit arguments."""
68         self.adapt(model, x)
69 
70     @staticmethod
71     def adapt(model, dataset):
72         """Adapt the preprocessing layers in the model."""
73         # Currently, only support using the original dataset to adapt all the
74         # preprocessing layers before the first non-preprocessing layer.
75         # TODO: Use PreprocessingStage for preprocessing layers adapt.
76         # TODO: Use Keras Tuner for preprocessing layers adapt.
77         x = dataset.map(lambda x, y: x)
78 
79         def get_output_layer(tensor):
80             tensor = nest.flatten(tensor)[0]
81             for layer in model.layers:
82                 if isinstance(layer, tf.keras.layers.InputLayer):
83                     continue
84                 input_node = nest.flatten(layer.input)[0]
85                 if input_node is tensor:
86                     return layer
87             return None
88 
89         for index, input_node in enumerate(nest.flatten(model.input)):
90             temp_x = x.map(lambda *args: nest.flatten(args)[index])
91             layer = get_output_layer(input_node)
92             while isinstance(layer, preprocessing.PreprocessingLayer):
93                 layer.adapt(temp_x)
94                 layer = get_output_layer(layer.output)
95         return model
96 
97     def search(
98         self, epochs=None, callbacks=None, fit_on_val_data=False, **fit_kwargs
99     ):
100         """Search for the best HyperParameters.
101 
102         If there is not early-stopping in the callbacks, the early-stopping callback
103         is injected to accelerate the search process. At the end of the search, the
104         best model will be fully trained with the specified number of epochs.
105 
106         # Arguments
107             callbacks: A list of callback functions. Defaults to None.
108             fit_on_val_data: Boolean. Use the training set and validation set for the
109                 final fit of the best model.
110         """
111         if self._finished:
112             return
113 
114         if callbacks is None:
115             callbacks = []
116 
117         # Insert early-stopping for adaptive number of epochs.
118         epochs_provided = True
119         if epochs is None:
120             epochs_provided = False
121             epochs = 1000
122             if not utils.contain_instance(callbacks, tf_callbacks.EarlyStopping):
123                 callbacks.append(tf_callbacks.EarlyStopping(patience=10))
124 
125         # Insert early-stopping for acceleration.
126         early_stopping_inserted = False
127         new_callbacks = self._deepcopy_callbacks(callbacks)
128         if not utils.contain_instance(callbacks, tf_callbacks.EarlyStopping):
129             early_stopping_inserted = True
130             new_callbacks.append(tf_callbacks.EarlyStopping(patience=10))
131 
132         # Populate initial search space.
133         hp = self.oracle.get_space()
134         self.hypermodel.build(hp)
135         self.oracle.update_space(hp)
136 
137         super().search(epochs=epochs, callbacks=new_callbacks, **fit_kwargs)
138 
139         # Train the best model use validation data.
140         # Train the best model with enought number of epochs.
141         if fit_on_val_data or early_stopping_inserted:
142             copied_fit_kwargs = copy.copy(fit_kwargs)
143 
144             # Remove early-stopping since no validation data.
145             # Remove early-stopping since it is inserted.
146             copied_fit_kwargs["callbacks"] = self._remove_early_stopping(callbacks)
147 
148             # Decide the number of epochs.
149             copied_fit_kwargs["epochs"] = epochs
150             if not epochs_provided:
151                 copied_fit_kwargs["epochs"] = self._get_best_trial_epochs()
152 
153             # Concatenate training and validation data.
154             if fit_on_val_data:
155                 copied_fit_kwargs["x"] = copied_fit_kwargs["x"].concatenate(
156                     fit_kwargs["validation_data"]
157                 )
158                 copied_fit_kwargs.pop("validation_data")
159 
160             model = self.final_fit(**copied_fit_kwargs)
161         else:
162             model = self.get_best_models()[0]
163 
164         model.save_weights(self.best_model_path)
165         self._finished = True
166 
167     def get_state(self):
168         state = super().get_state()
169         state.update({"finished": self._finished})
170         return state
171 
172     def set_state(self, state):
173         super().set_state(state)
174         self._finished = state.get("finished")
175 
176     @staticmethod
177     def _remove_early_stopping(callbacks):
178         return [
179             copy.deepcopy(callbacks)
180             for callback in callbacks
181             if not isinstance(callback, tf_callbacks.EarlyStopping)
182         ]
183 
184     def _get_best_trial_epochs(self):
185         best_trial = self.oracle.get_best_trials(1)[0]
186         return self.oracle.get_trial(best_trial.trial_id).best_step
187 
188     def _build_best_model(self):
189         best_trial = self.oracle.get_best_trials(1)[0]
190         best_hp = best_trial.hyperparameters
191         return self.hypermodel.build(best_hp)
192 
193     def final_fit(self, x=None, **fit_kwargs):
194         model = self._build_best_model()
195         self.adapt(model, x)
196         model.fit(x, **fit_kwargs)
197         return model
198 
199     @property
200     def best_model_path(self):
201         return os.path.join(self.project_dir, "best_model")
202 
203     @property
204     def objective(self):
205         return self.oracle.objective
206 
207     @property
208     def max_trials(self):
209         return self.oracle.max_trials
210
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/autokeras/engine/tuner.py b/autokeras/engine/tuner.py
--- a/autokeras/engine/tuner.py
+++ b/autokeras/engine/tuner.py
@@ -91,6 +91,7 @@
             layer = get_output_layer(input_node)
             while isinstance(layer, preprocessing.PreprocessingLayer):
                 layer.adapt(temp_x)
+                temp_x = temp_x.map(layer)
                 layer = get_output_layer(layer.output)
         return model

{"golden_diff": "diff --git a/autokeras/engine/tuner.py b/autokeras/engine/tuner.py\n--- a/autokeras/engine/tuner.py\n+++ b/autokeras/engine/tuner.py\n@@ -91,6 +91,7 @@\n             layer = get_output_layer(input_node)\n             while isinstance(layer, preprocessing.PreprocessingLayer):\n                 layer.adapt(temp_x)\n+                temp_x = temp_x.map(layer)\n                 layer = get_output_layer(layer.output)\n         return model\n", "issue": "tuner use previous layer's output to adapt the next\n<!-- STEP 1: Give the pull request a meaningful title. -->\r\n### Which issue(s) does this Pull Request fix?\r\n<!-- STEP 2: Replace the \"000\" with the issue ID this pull request resolves. -->\r\nresolves #1312 \r\n\r\n### Details of the Pull Request\r\n<!-- STEP 3: Add details/comments on the pull request. -->\r\n\r\n<!-- STEP 4: If the pull request is in progress, click the down green arrow to select \"Create Draft Pull Request\", and click the button. If the pull request is ready to be reviewed, click \"Create Pull Request\" button directly. -->\r\n\n", "before_files": [{"content": "# Copyright 2020 The AutoKeras Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport copy\nimport os\n\nimport kerastuner\nimport tensorflow as tf\nfrom kerastuner.engine import hypermodel as hm_module\nfrom tensorflow.keras import callbacks as tf_callbacks\nfrom tensorflow.keras.layers.experimental import preprocessing\nfrom tensorflow.python.util import nest\n\nfrom autokeras.utils import utils\n\n\nclass AutoTuner(kerastuner.engine.tuner.Tuner):\n    \"\"\"A Tuner class based on KerasTuner for AutoKeras.\n\n    Different from KerasTuner's Tuner class. AutoTuner's not only tunes the\n    Hypermodel which can be directly built into a Keras model, but also the\n    preprocessors. Therefore, a HyperGraph stores the overall search space containing\n    both the Preprocessors and Hypermodel. For every trial, the HyperGraph build the\n    PreprocessGraph and KerasGraph with the provided HyperParameters.\n\n    The AutoTuner uses EarlyStopping for acceleration during the search and fully\n    train the model with full epochs and with both training and validation data.\n    The fully trained model is the best model to be used by AutoModel.\n\n    # Arguments\n        preprocessors: An instance or list of `Preprocessor` objects corresponding to\n            each AutoModel input, to preprocess a `tf.data.Dataset` before passing it\n            to the model. Defaults to None (no external preprocessing).\n        **kwargs: The args supported by KerasTuner.\n    \"\"\"\n\n    def __init__(self, oracle, hypermodel, preprocessors=None, **kwargs):\n        # Initialize before super() for reload to work.\n        self._finished = False\n        super().__init__(oracle, hypermodel, **kwargs)\n        self.preprocessors = nest.flatten(preprocessors)\n        # Save or load the HyperModel.\n        self.hypermodel.hypermodel.save(os.path.join(self.project_dir, \"graph\"))\n\n    # Override the function to prevent building the model during initialization.\n    def _populate_initial_space(self):\n        pass\n\n    def get_best_model(self):\n        model = self._build_best_model()\n        with hm_module.maybe_distribute(self.distribution_strategy):\n            model.load_weights(self.best_model_path)\n        return model\n\n    def _on_train_begin(self, model, hp, x, *args, **kwargs):\n        \"\"\"Adapt the preprocessing layers and tune the fit arguments.\"\"\"\n        self.adapt(model, x)\n\n    @staticmethod\n    def adapt(model, dataset):\n        \"\"\"Adapt the preprocessing layers in the model.\"\"\"\n        # Currently, only support using the original dataset to adapt all the\n        # preprocessing layers before the first non-preprocessing layer.\n        # TODO: Use PreprocessingStage for preprocessing layers adapt.\n        # TODO: Use Keras Tuner for preprocessing layers adapt.\n        x = dataset.map(lambda x, y: x)\n\n        def get_output_layer(tensor):\n            tensor = nest.flatten(tensor)[0]\n            for layer in model.layers:\n                if isinstance(layer, tf.keras.layers.InputLayer):\n                    continue\n                input_node = nest.flatten(layer.input)[0]\n                if input_node is tensor:\n                    return layer\n            return None\n\n        for index, input_node in enumerate(nest.flatten(model.input)):\n            temp_x = x.map(lambda *args: nest.flatten(args)[index])\n            layer = get_output_layer(input_node)\n            while isinstance(layer, preprocessing.PreprocessingLayer):\n                layer.adapt(temp_x)\n                layer = get_output_layer(layer.output)\n        return model\n\n    def search(\n        self, epochs=None, callbacks=None, fit_on_val_data=False, **fit_kwargs\n    ):\n        \"\"\"Search for the best HyperParameters.\n\n        If there is not early-stopping in the callbacks, the early-stopping callback\n        is injected to accelerate the search process. At the end of the search, the\n        best model will be fully trained with the specified number of epochs.\n\n        # Arguments\n            callbacks: A list of callback functions. Defaults to None.\n            fit_on_val_data: Boolean. Use the training set and validation set for the\n                final fit of the best model.\n        \"\"\"\n        if self._finished:\n            return\n\n        if callbacks is None:\n            callbacks = []\n\n        # Insert early-stopping for adaptive number of epochs.\n        epochs_provided = True\n        if epochs is None:\n            epochs_provided = False\n            epochs = 1000\n            if not utils.contain_instance(callbacks, tf_callbacks.EarlyStopping):\n                callbacks.append(tf_callbacks.EarlyStopping(patience=10))\n\n        # Insert early-stopping for acceleration.\n        early_stopping_inserted = False\n        new_callbacks = self._deepcopy_callbacks(callbacks)\n        if not utils.contain_instance(callbacks, tf_callbacks.EarlyStopping):\n            early_stopping_inserted = True\n            new_callbacks.append(tf_callbacks.EarlyStopping(patience=10))\n\n        # Populate initial search space.\n        hp = self.oracle.get_space()\n        self.hypermodel.build(hp)\n        self.oracle.update_space(hp)\n\n        super().search(epochs=epochs, callbacks=new_callbacks, **fit_kwargs)\n\n        # Train the best model use validation data.\n        # Train the best model with enought number of epochs.\n        if fit_on_val_data or early_stopping_inserted:\n            copied_fit_kwargs = copy.copy(fit_kwargs)\n\n            # Remove early-stopping since no validation data.\n            # Remove early-stopping since it is inserted.\n            copied_fit_kwargs[\"callbacks\"] = self._remove_early_stopping(callbacks)\n\n            # Decide the number of epochs.\n            copied_fit_kwargs[\"epochs\"] = epochs\n            if not epochs_provided:\n                copied_fit_kwargs[\"epochs\"] = self._get_best_trial_epochs()\n\n            # Concatenate training and validation data.\n            if fit_on_val_data:\n                copied_fit_kwargs[\"x\"] = copied_fit_kwargs[\"x\"].concatenate(\n                    fit_kwargs[\"validation_data\"]\n                )\n                copied_fit_kwargs.pop(\"validation_data\")\n\n            model = self.final_fit(**copied_fit_kwargs)\n        else:\n            model = self.get_best_models()[0]\n\n        model.save_weights(self.best_model_path)\n        self._finished = True\n\n    def get_state(self):\n        state = super().get_state()\n        state.update({\"finished\": self._finished})\n        return state\n\n    def set_state(self, state):\n        super().set_state(state)\n        self._finished = state.get(\"finished\")\n\n    @staticmethod\n    def _remove_early_stopping(callbacks):\n        return [\n            copy.deepcopy(callbacks)\n            for callback in callbacks\n            if not isinstance(callback, tf_callbacks.EarlyStopping)\n        ]\n\n    def _get_best_trial_epochs(self):\n        best_trial = self.oracle.get_best_trials(1)[0]\n        return self.oracle.get_trial(best_trial.trial_id).best_step\n\n    def _build_best_model(self):\n        best_trial = self.oracle.get_best_trials(1)[0]\n        best_hp = best_trial.hyperparameters\n        return self.hypermodel.build(best_hp)\n\n    def final_fit(self, x=None, **fit_kwargs):\n        model = self._build_best_model()\n        self.adapt(model, x)\n        model.fit(x, **fit_kwargs)\n        return model\n\n    @property\n    def best_model_path(self):\n        return os.path.join(self.project_dir, \"best_model\")\n\n    @property\n    def objective(self):\n        return self.oracle.objective\n\n    @property\n    def max_trials(self):\n        return self.oracle.max_trials\n", "path": "autokeras/engine/tuner.py"}], "after_files": [{"content": "# Copyright 2020 The AutoKeras Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport copy\nimport os\n\nimport kerastuner\nimport tensorflow as tf\nfrom kerastuner.engine import hypermodel as hm_module\nfrom tensorflow.keras import callbacks as tf_callbacks\nfrom tensorflow.keras.layers.experimental import preprocessing\nfrom tensorflow.python.util import nest\n\nfrom autokeras.utils import utils\n\n\nclass AutoTuner(kerastuner.engine.tuner.Tuner):\n    \"\"\"A Tuner class based on KerasTuner for AutoKeras.\n\n    Different from KerasTuner's Tuner class. AutoTuner's not only tunes the\n    Hypermodel which can be directly built into a Keras model, but also the\n    preprocessors. Therefore, a HyperGraph stores the overall search space containing\n    both the Preprocessors and Hypermodel. For every trial, the HyperGraph build the\n    PreprocessGraph and KerasGraph with the provided HyperParameters.\n\n    The AutoTuner uses EarlyStopping for acceleration during the search and fully\n    train the model with full epochs and with both training and validation data.\n    The fully trained model is the best model to be used by AutoModel.\n\n    # Arguments\n        preprocessors: An instance or list of `Preprocessor` objects corresponding to\n            each AutoModel input, to preprocess a `tf.data.Dataset` before passing it\n            to the model. Defaults to None (no external preprocessing).\n        **kwargs: The args supported by KerasTuner.\n    \"\"\"\n\n    def __init__(self, oracle, hypermodel, preprocessors=None, **kwargs):\n        # Initialize before super() for reload to work.\n        self._finished = False\n        super().__init__(oracle, hypermodel, **kwargs)\n        self.preprocessors = nest.flatten(preprocessors)\n        # Save or load the HyperModel.\n        self.hypermodel.hypermodel.save(os.path.join(self.project_dir, \"graph\"))\n\n    # Override the function to prevent building the model during initialization.\n    def _populate_initial_space(self):\n        pass\n\n    def get_best_model(self):\n        model = self._build_best_model()\n        with hm_module.maybe_distribute(self.distribution_strategy):\n            model.load_weights(self.best_model_path)\n        return model\n\n    def _on_train_begin(self, model, hp, x, *args, **kwargs):\n        \"\"\"Adapt the preprocessing layers and tune the fit arguments.\"\"\"\n        self.adapt(model, x)\n\n    @staticmethod\n    def adapt(model, dataset):\n        \"\"\"Adapt the preprocessing layers in the model.\"\"\"\n        # Currently, only support using the original dataset to adapt all the\n        # preprocessing layers before the first non-preprocessing layer.\n        # TODO: Use PreprocessingStage for preprocessing layers adapt.\n        # TODO: Use Keras Tuner for preprocessing layers adapt.\n        x = dataset.map(lambda x, y: x)\n\n        def get_output_layer(tensor):\n            tensor = nest.flatten(tensor)[0]\n            for layer in model.layers:\n                if isinstance(layer, tf.keras.layers.InputLayer):\n                    continue\n                input_node = nest.flatten(layer.input)[0]\n                if input_node is tensor:\n                    return layer\n            return None\n\n        for index, input_node in enumerate(nest.flatten(model.input)):\n            temp_x = x.map(lambda *args: nest.flatten(args)[index])\n            layer = get_output_layer(input_node)\n            while isinstance(layer, preprocessing.PreprocessingLayer):\n                layer.adapt(temp_x)\n                temp_x = temp_x.map(layer)\n                layer = get_output_layer(layer.output)\n        return model\n\n    def search(\n        self, epochs=None, callbacks=None, fit_on_val_data=False, **fit_kwargs\n    ):\n        \"\"\"Search for the best HyperParameters.\n\n        If there is not early-stopping in the callbacks, the early-stopping callback\n        is injected to accelerate the search process. At the end of the search, the\n        best model will be fully trained with the specified number of epochs.\n\n        # Arguments\n            callbacks: A list of callback functions. Defaults to None.\n            fit_on_val_data: Boolean. Use the training set and validation set for the\n                final fit of the best model.\n        \"\"\"\n        if self._finished:\n            return\n\n        if callbacks is None:\n            callbacks = []\n\n        # Insert early-stopping for adaptive number of epochs.\n        epochs_provided = True\n        if epochs is None:\n            epochs_provided = False\n            epochs = 1000\n            if not utils.contain_instance(callbacks, tf_callbacks.EarlyStopping):\n                callbacks.append(tf_callbacks.EarlyStopping(patience=10))\n\n        # Insert early-stopping for acceleration.\n        early_stopping_inserted = False\n        new_callbacks = self._deepcopy_callbacks(callbacks)\n        if not utils.contain_instance(callbacks, tf_callbacks.EarlyStopping):\n            early_stopping_inserted = True\n            new_callbacks.append(tf_callbacks.EarlyStopping(patience=10))\n\n        # Populate initial search space.\n        hp = self.oracle.get_space()\n        self.hypermodel.build(hp)\n        self.oracle.update_space(hp)\n\n        super().search(epochs=epochs, callbacks=new_callbacks, **fit_kwargs)\n\n        # Train the best model use validation data.\n        # Train the best model with enought number of epochs.\n        if fit_on_val_data or early_stopping_inserted:\n            copied_fit_kwargs = copy.copy(fit_kwargs)\n\n            # Remove early-stopping since no validation data.\n            # Remove early-stopping since it is inserted.\n            copied_fit_kwargs[\"callbacks\"] = self._remove_early_stopping(callbacks)\n\n            # Decide the number of epochs.\n            copied_fit_kwargs[\"epochs\"] = epochs\n            if not epochs_provided:\n                copied_fit_kwargs[\"epochs\"] = self._get_best_trial_epochs()\n\n            # Concatenate training and validation data.\n            if fit_on_val_data:\n                copied_fit_kwargs[\"x\"] = copied_fit_kwargs[\"x\"].concatenate(\n                    fit_kwargs[\"validation_data\"]\n                )\n                copied_fit_kwargs.pop(\"validation_data\")\n\n            model = self.final_fit(**copied_fit_kwargs)\n        else:\n            model = self.get_best_models()[0]\n\n        model.save_weights(self.best_model_path)\n        self._finished = True\n\n    def get_state(self):\n        state = super().get_state()\n        state.update({\"finished\": self._finished})\n        return state\n\n    def set_state(self, state):\n        super().set_state(state)\n        self._finished = state.get(\"finished\")\n\n    @staticmethod\n    def _remove_early_stopping(callbacks):\n        return [\n            copy.deepcopy(callbacks)\n            for callback in callbacks\n            if not isinstance(callback, tf_callbacks.EarlyStopping)\n        ]\n\n    def _get_best_trial_epochs(self):\n        best_trial = self.oracle.get_best_trials(1)[0]\n        return self.oracle.get_trial(best_trial.trial_id).best_step\n\n    def _build_best_model(self):\n        best_trial = self.oracle.get_best_trials(1)[0]\n        best_hp = best_trial.hyperparameters\n        return self.hypermodel.build(best_hp)\n\n    def final_fit(self, x=None, **fit_kwargs):\n        model = self._build_best_model()\n        self.adapt(model, x)\n        model.fit(x, **fit_kwargs)\n        return model\n\n    @property\n    def best_model_path(self):\n        return os.path.join(self.project_dir, \"best_model\")\n\n    @property\n    def objective(self):\n        return self.oracle.objective\n\n    @property\n    def max_trials(self):\n        return self.oracle.max_trials\n", "path": "autokeras/engine/tuner.py"}]}