diff --git a/setup.cfg b/setup.cfg index 7e4cd949..c3e54762 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = deepmol -version = 1.1.14 +version = 1.1.15 description = DeepMol: a python-based machine and deep learning framework for drug discovery keywords = machine-learning, deep-learning, cheminformatics, drug-discovery author = DeepMol Team diff --git a/src/deepmol/__init__.py b/src/deepmol/__init__.py index ec790b8d..50a960c9 100644 --- a/src/deepmol/__init__.py +++ b/src/deepmol/__init__.py @@ -1,2 +1,2 @@ -__version__ = '1.1.14' +__version__ = '1.1.15' diff --git a/src/deepmol/models/sklearn_models.py b/src/deepmol/models/sklearn_models.py index 96bb28dd..0d0fdbfe 100644 --- a/src/deepmol/models/sklearn_models.py +++ b/src/deepmol/models/sklearn_models.py @@ -190,8 +190,8 @@ def save(self, folder_path: str = None): save_to_disk(self.model, model_path) - # change file path to keep the extension but add _params - parameters_file_path = model_path.split('.')[0] + '_params.' + model_path.split('.')[1] + base, ext = os.path.splitext(model_path) + parameters_file_path = f"{base}_params{ext}" save_to_disk(self.parameters_to_save, parameters_file_path) @classmethod @@ -213,7 +213,8 @@ def load(cls, folder_path: str, **kwargs) -> 'SklearnModel': model_path = cls.get_model_filename(folder_path) model = load_from_disk(model_path) # change file path to keep the extension but add _params - parameters_file_path = ".".join(model_path.split('.')[:-1]) + '_params.' + model_path.split('.')[-1] + base, ext = os.path.splitext(model_path) + parameters_file_path = f"{base}_params{ext}" params = load_from_disk(parameters_file_path) instance = cls(model=model, model_dir=model_path, **params) return instance diff --git a/tests/unit_tests/models/test_deepchem_model.py b/tests/unit_tests/models/test_deepchem_model.py index 34c8d273..109a8012 100644 --- a/tests/unit_tests/models/test_deepchem_model.py +++ b/tests/unit_tests/models/test_deepchem_model.py @@ -1,4 +1,5 @@ import os +import shutil from unittest import TestCase from unittest.mock import MagicMock @@ -109,6 +110,25 @@ def test_save(self): new_predictions = model_graph_loaded.predict(ds_test) self.assertTrue(np.array_equal(test_preds, new_predictions)) + def test_save_load_with_dots(self): + ds_train = self.multitask_dataset + ds_train.X = ConvMolFeaturizer().featurize([MolFromSmiles('CCC')] * 10) + ds_test = self.multitask_dataset_test + ds_test.X = ConvMolFeaturizer().featurize([MolFromSmiles('CCC')] * 10) + + model_graph = DeepChemModel(GraphConvModel, n_tasks=ds_train.n_tasks, mode='classification', epochs=3) + + model_graph.fit(ds_train) + test_preds = model_graph.predict(ds_test) + + model_graph.save("../test_model") + model_graph_loaded = DeepChemModel.load("../test_model") + self.assertEqual(model_graph.n_tasks, ds_train.n_tasks) + self.assertEqual(model_graph.epochs, 3) + new_predictions = model_graph_loaded.predict(ds_test) + self.assertTrue(np.array_equal(test_preds, new_predictions)) + shutil.rmtree("../test_model") + def test_cross_validate(self): ds_train = self.binary_dataset ds_train.X = ConvMolFeaturizer().featurize([MolFromSmiles('CCC')] * 100) diff --git a/tests/unit_tests/models/test_keras_model.py b/tests/unit_tests/models/test_keras_model.py index a54ae389..eaa647f6 100644 --- a/tests/unit_tests/models/test_keras_model.py +++ b/tests/unit_tests/models/test_keras_model.py @@ -96,6 +96,40 @@ def test_save_model(self): shutil.rmtree("test_model") + def test_save_model_with_dots(self): + model = KerasModel(model_builder=make_cnn_model, + epochs=2, input_dim=self.binary_dataset.X.shape[1]) + model.fit(self.binary_dataset) + + first_predictions = model.predict(self.binary_dataset_test) + + model.save("../test_model") + loaded_model = KerasModel.load("../test_model") + self.assertEqual(2, loaded_model.epochs) + self.assertEqual(50, loaded_model.parameters_to_save["input_dim"]) + loaded_model_predictions = loaded_model.predict(self.binary_dataset_test) + + assert np.array_equal(first_predictions, loaded_model_predictions) + + shutil.rmtree("../test_model") + + def test_load_models_with_dots(self): + model = KerasModel(model_builder=make_cnn_model, + epochs=2, input_dim=self.binary_dataset.X.shape[1]) + model.fit(self.binary_dataset) + + first_predictions = model.predict(self.binary_dataset_test) + + model.save("../test_model") + loaded_model = KerasModel.load("../test_model") + self.assertEqual(2, loaded_model.epochs) + self.assertEqual(50, loaded_model.parameters_to_save["input_dim"]) + loaded_model_predictions = loaded_model.predict(self.binary_dataset_test) + + assert np.array_equal(first_predictions, loaded_model_predictions) + + shutil.rmtree("../test_model") + def test_baseline_models(self): model_kwargs = {'input_dim': 50} keras_kwargs = {} diff --git a/tests/unit_tests/models/test_sklearn_models.py b/tests/unit_tests/models/test_sklearn_models.py index 942e0c82..843a65b8 100644 --- a/tests/unit_tests/models/test_sklearn_models.py +++ b/tests/unit_tests/models/test_sklearn_models.py @@ -150,11 +150,12 @@ def test_save_model(self): self.assertEqual("classification", model.mode) - with self.assertRaises(ValueError): - model.save("test_model.params.pkl") - - with self.assertRaises(ValueError): - model.save("test_model.params.joblib") + model.save("test_model.params.pkl") + self.assertTrue(os.path.exists("test_model.params.pkl")) + shutil.rmtree("test_model.params.pkl") + model.save("test_model.params.joblib") + self.assertTrue(os.path.exists("test_model.params.joblib")) + shutil.rmtree("test_model.params.joblib") rf = RandomForestClassifier() model = SklearnModel(model=rf, mode="classification", model_dir="test_model") @@ -164,6 +165,34 @@ def test_save_model(self): shutil.rmtree("test_model") + def test_save_model_with_dots(self): + rf = RandomForestClassifier() + model = SklearnModel(model=rf, mode="classification", model_dir="test_model") + model.fit(self.binary_dataset) + model.save("../test_model") + self.assertTrue(os.path.exists("../test_model")) + shutil.rmtree("../test_model") + + def test_load_models_with_dots(self): + rf = RandomForestClassifier() + model = SklearnModel(model=rf, mode="classification", model_dir="../test_model") + model.fit(self.binary_dataset) + model.save("../test_model") + self.assertTrue(os.path.exists("../test_model")) + + predictions_1 = model.predict(self.binary_dataset_test) + + new_model = SklearnModel.load("../test_model") + y_test = new_model.predict(self.binary_dataset_test) + self.assertEqual(len(y_test), len(self.binary_dataset_test.y)) + self.assertIsInstance(new_model, SklearnModel) + self.assertEqual("classification", new_model.mode) + + assert np.array_equal(predictions_1, y_test) + + shutil.rmtree("../test_model") + + def test_load_model(self): rf = RandomForestClassifier() model = SklearnModel(model=rf, mode="classification")