Repository: keras-team/autokeras

Issue:
Final fit not replacing the model in training history
Hi,

if I run clf.final_fit(x_train, y_train, x_test, y_test, **retrain=True**)
then call
model = clf.load_searcher().**load_best_model()**.produce_keras_model()
Is this model the retrained model?

I traced the 0.2.18 ImageSupervised.final_fit() source code but I'm not sure it's true.
**load_best_model()** seems to return the original best model in searching phase.

Thank you.


Discussion:
This might be a bug. I will investigate it. @twprinston Thanks.
Faced a similar problem:

After training the model using `clf.fit()` function, calling `clf.final_fit()` does not make any difference. The best model remains the same and does not get updated. So:
```
clf = ak.ImageClassifier(verbose=True, resume=True, path='autokeras-run')	
clf.final_fit(x_train, y_train, x_dev, y_dev, retrain=True)
y_test_pred = clf.predict(x_test)
```
leads to exactly the same results as:
```
clf = ak.ImageClassifier(verbose=True, resume=True, path='autokeras-run')
y_test_pred = clf.predict(x_test)
```

Resolving patch:
diff --git a/autokeras/cnn_module.py b/autokeras/cnn_module.py
--- a/autokeras/cnn_module.py
+++ b/autokeras/cnn_module.py
@@ -80,6 +80,7 @@ def final_fit(self, train_data, test_data, trainer_args=None, retrain=False):
         if retrain:
             graph.weighted = False
         _, _1, graph = train((graph, train_data, test_data, trainer_args, None, self.metric, self.loss, self.verbose))
+        searcher.replace_model(graph, searcher.get_best_model_id())
 
     @property
     def best_model(self):
diff --git a/autokeras/search.py b/autokeras/search.py
--- a/autokeras/search.py
+++ b/autokeras/search.py
@@ -89,7 +89,7 @@ def __init__(self, n_output_node, input_shape, path, metric, loss, verbose,
         self.bo = BayesianOptimizer(self, t_min, metric, kernel_lambda, beta)
 
     def load_model_by_id(self, model_id):
-        return pickle_from_file(os.path.join(self.path, str(model_id) + '.h5'))
+        return pickle_from_file(os.path.join(self.path, str(model_id) + '.graph'))
 
     def load_best_model(self):
         return self.load_model_by_id(self.get_best_model_id())
@@ -106,13 +106,13 @@ def get_best_model_id(self):
         return min(self.history, key=lambda x: x['metric_value'])['model_id']
 
     def replace_model(self, graph, model_id):
-        pickle_to_file(graph, os.path.join(self.path, str(model_id) + '.h5'))
+        pickle_to_file(graph, os.path.join(self.path, str(model_id) + '.graph'))
 
     def add_model(self, metric_value, loss, graph, model_id):
         if self.verbose:
             print('\nSaving model.')
 
-        pickle_to_file(graph, os.path.join(self.path, str(model_id) + '.h5'))
+        pickle_to_file(graph, os.path.join(self.path, str(model_id) + '.graph'))
 
         # Update best_model text file
         ret = {'model_id': model_id, 'loss': loss, 'metric_value': metric_value}


Test patch:
diff --git a/tests/image/test_image_supervised.py b/tests/image/test_image_supervised.py
--- a/tests/image/test_image_supervised.py
+++ b/tests/image/test_image_supervised.py
@@ -218,7 +218,7 @@ def test_export_keras_model(_):
     score = clf.evaluate(train_x, train_y)
     assert score <= 1.0
 
-    model_file_name = os.path.join(path, 'test_keras_model.h5')
+    model_file_name = os.path.join(path, 'test_keras_model.graph')
     clf.export_keras_model(model_file_name)
     from keras.models import load_model
     model = load_model(model_file_name)
@@ -242,7 +242,7 @@ def test_export_keras_model(_):
     score = clf.evaluate(train_x, train_y)
     assert score >= 0.0
 
-    model_file_name = os.path.join(path, 'test_keras_model.h5')
+    model_file_name = os.path.join(path, 'test_keras_model.graph')
     clf.export_keras_model(model_file_name)
     from keras.models import load_model
     model = load_model(model_file_name)