We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
How use multiple gpu?
### Feature Description
I want to use a single machine with multiple gpu for training, but it seems to have no actual effect### Code Example

```python
with strategy.scope():
```

### Reason
Speed up the calculation of toxins

### Solution
<!---
Please tell us how to implement the feature,
if you have one in mind.
-->


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

{"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@@ -17,6 +17,7 @@\n \n import kerastuner\n import tensorflow as tf\n+from kerastuner.engine import hypermodel as hm_module\n from tensorflow.keras import callbacks as tf_callbacks\n from tensorflow.keras.layers.experimental import preprocessing\n from tensorflow.python.util import nest\n@@ -58,7 +59,8 @@\n \n     def get_best_model(self):\n         model = self._build_best_model()\n-        model.load_weights(self.best_model_path)\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", "issue": "How use multiple gpu?\n### Feature Description\r\nI want to use a single machine with multiple gpu for training, but it seems to have no actual effect### Code Example\r\n\r\n```python\r\nwith strategy.scope():\r\n```\r\n\r\n### Reason\r\nSpeed up the calculation of toxins\r\n\r\n### Solution\r\n<!---\r\nPlease tell us how to implement the feature,\r\nif you have one in mind.\r\n-->\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 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        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 len(best_trial.metrics.metrics[\"val_loss\"]._observations)\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                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 len(best_trial.metrics.metrics[\"val_loss\"]._observations)\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"}]}