From 5a8f2ef447494e4e358d936b24ec909d3d219a7e Mon Sep 17 00:00:00 2001 From: morrisnein Date: Thu, 26 Oct 2023 03:17:13 +0300 Subject: [PATCH 1/2] adapt to https://github.com/aimclub/GOLEM/pull/228 --- fedot/api/api_utils/api_composer.py | 12 ++++++------ fedot/core/pipelines/tuning/tuner_builder.py | 7 ++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/fedot/api/api_utils/api_composer.py b/fedot/api/api_utils/api_composer.py index 7bb1f2dabf..2ea32d2075 100644 --- a/fedot/api/api_utils/api_composer.py +++ b/fedot/api/api_utils/api_composer.py @@ -5,6 +5,7 @@ from golem.core.log import default_log from golem.core.optimisers.opt_history_objects.opt_history import OptHistory from golem.core.tuning.simultaneous import SimultaneousTuner +from golem.core.tuning.tuner_interface import BaseTuner from fedot.api.api_utils.assumptions.assumptions_handler import AssumptionsHandler from fedot.api.api_utils.params import ApiParams @@ -72,11 +73,8 @@ def obtain_model(self, train_data: InputData) -> Tuple[Pipeline, Sequence[Pipeli fitted_assumption ) if with_tuning: - best_pipeline = self.tune_final_pipeline(train_data, best_pipeline) - if gp_composer.history: - adapter = self.params.graph_generation_params.adapter - gp_composer.history.tuning_result = adapter.adapt(best_pipeline) - # enforce memory cleaning + best_pipeline = self.tune_final_pipeline(train_data, best_pipeline, gp_composer.history) + gc.collect() self.log.message('Model generation finished') @@ -142,7 +140,8 @@ def compose_pipeline(self, train_data: InputData, initial_assumption: Sequence[P best_pipeline = best_pipelines[0] if isinstance(best_pipelines, Sequence) else best_pipelines return best_pipeline, best_pipeline_candidates, gp_composer - def tune_final_pipeline(self, train_data: InputData, pipeline_gp_composed: Pipeline) -> Pipeline: + def tune_final_pipeline(self, train_data: InputData, pipeline_gp_composed: Pipeline, + history: Optional[OptHistory]) -> Tuple[BaseTuner, Pipeline]: """ Launch tuning procedure for obtained pipeline by composer """ timeout_for_tuning = abs(self.timer.determine_resources_for_tuning()) / 60 tuner = (TunerBuilder(self.params.task) @@ -152,6 +151,7 @@ def tune_final_pipeline(self, train_data: InputData, pipeline_gp_composed: Pipel .with_timeout(datetime.timedelta(minutes=timeout_for_tuning)) .with_eval_time_constraint(self.params.composer_requirements.max_graph_fit_time) .with_requirements(self.params.composer_requirements) + .with_history(history) .build(train_data)) if self.timer.have_time_for_tuning(): diff --git a/fedot/core/pipelines/tuning/tuner_builder.py b/fedot/core/pipelines/tuning/tuner_builder.py index 698de90a95..1e3c34ec60 100644 --- a/fedot/core/pipelines/tuning/tuner_builder.py +++ b/fedot/core/pipelines/tuning/tuner_builder.py @@ -1,5 +1,5 @@ from datetime import timedelta -from typing import Type, Union, Iterable, Sequence +from typing import Iterable, Sequence, Type, Union from golem.core.tuning.optuna_tuner import OptunaTuner from golem.core.tuning.simultaneous import SimultaneousTuner @@ -33,6 +33,7 @@ def __init__(self, task: Task): self.eval_time_constraint = None self.additional_params = {} self.adapter = PipelineAdapter() + self.history = None def with_tuner(self, tuner: Type[BaseTuner]): self.tuner_class = tuner @@ -89,6 +90,10 @@ def with_adapter(self, adapter): self.adapter = adapter return self + def with_history(self, history): + self.history = history + return self + def with_additional_params(self, **parameters): self.additional_params.update(parameters) return self From 196d366f6dbbc6e98bb26491a5d85d77254815b9 Mon Sep 17 00:00:00 2001 From: morrisnein Date: Thu, 26 Oct 2023 03:17:50 +0300 Subject: [PATCH 2/2] rename history.individuals -> generations --- .../advanced/parallelization_comparison.py | 2 +- .../pipeline_and_history_visualization.py | 2 +- .../api_params/test_main_api_params.py | 8 ++++---- test/integration/composer/test_composer.py | 8 ++++---- test/integration/composer/test_history.py | 18 +++++++++--------- .../quality/test_quality_improvement.py | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/advanced/parallelization_comparison.py b/examples/advanced/parallelization_comparison.py index 2776213ef3..3ef4a4537e 100644 --- a/examples/advanced/parallelization_comparison.py +++ b/examples/advanced/parallelization_comparison.py @@ -14,7 +14,7 @@ def _count_pipelines(opt_history: Optional[OptHistory]) -> int: if opt_history is not None: - return reduce(operator.add, map(len, opt_history.individuals), 0) + return reduce(operator.add, map(len, opt_history.generations), 0) return 0 diff --git a/examples/simple/pipeline_and_history_visualization.py b/examples/simple/pipeline_and_history_visualization.py index 25675a5f9e..04557e570f 100644 --- a/examples/simple/pipeline_and_history_visualization.py +++ b/examples/simple/pipeline_and_history_visualization.py @@ -11,7 +11,7 @@ def run_pipeline_and_history_visualization(): """ The function runs visualization of the composing history and the best pipeline. """ # Gather pipeline and history. history = OptHistory.load(Path(fedot_project_root(), 'examples', 'data', 'histories', 'scoring_case_history.json')) - pipeline = PipelineAdapter().restore(history.individuals[-1][-1].graph) + pipeline = PipelineAdapter().restore(history.generations[-1][-1].graph) # Show visualizations. pipeline.show() history_visualizer = PipelineHistoryVisualizer(history) diff --git a/test/integration/api_params/test_main_api_params.py b/test/integration/api_params/test_main_api_params.py index f49fc4d2bd..fd96ead2e0 100644 --- a/test/integration/api_params/test_main_api_params.py +++ b/test/integration/api_params/test_main_api_params.py @@ -20,15 +20,15 @@ class TimeoutParams: TIMEOUT_CASES = [ TimeoutParams( test_input={'timeout': -1, 'num_of_generations': 1}, - test_answer=lambda hist: len(hist.individuals) == 1 + 2 # num of gens + initial and final gens + test_answer=lambda hist: len(hist.generations) == 1 + 2 # num of gens + initial and final gens ), TimeoutParams( test_input={'timeout': None, 'num_of_generations': 1}, - test_answer=lambda hist: len(hist.individuals) == 1 + 2 + test_answer=lambda hist: len(hist.generations) == 1 + 2 ), TimeoutParams( test_input={'timeout': 0.1, 'num_of_generations': 15}, - test_answer=lambda hist: len(hist.individuals) < 15 + 2 + test_answer=lambda hist: len(hist.generations) < 15 + 2 ), TimeoutParams( test_input={'timeout': -2, 'num_of_generations': 15}, @@ -36,7 +36,7 @@ class TimeoutParams: ), TimeoutParams( test_input={'timeout': -1, 'num_of_generations': 3}, - test_answer=lambda hist: len(hist.individuals) == 3 + 2 + test_answer=lambda hist: len(hist.generations) == 3 + 2 ) ] diff --git a/test/integration/composer/test_composer.py b/test/integration/composer/test_composer.py index a30d2a933b..3b1775c46e 100644 --- a/test/integration/composer/test_composer.py +++ b/test/integration/composer/test_composer.py @@ -153,10 +153,10 @@ def test_parameter_free_composer_build_pipeline_correct(data_fixture, request): roc_on_valid_gp_composed = roc_auc(y_true=dataset_to_validate.target, y_score=predicted_gp_composed.predict) - all_individuals = len(gp_composer.history.individuals) - population_len = sum([len(history) for history in gp_composer.history.individuals]) / all_individuals + all_individuals = len(gp_composer.history.generations) + population_len = sum([len(history) for history in gp_composer.history.generations]) / all_individuals - assert population_len != len(gp_composer.history.individuals[0]) + assert population_len != len(gp_composer.history.generations[0]) assert roc_on_valid_gp_composed > 0.6 @@ -226,7 +226,7 @@ def test_gp_composer_with_adaptive_depth(data_fixture, request): composer.compose_pipeline(data=dataset_to_compose) - generations = composer.history.individuals + generations = composer.history.generations current_depth = composer.optimizer.requirements.max_depth assert req.start_depth <= current_depth < max_depth, f"max depth couldn't have been reached in {num_gen}" assert all(ind.graph.depth < max_depth for ind in generations[-1]), "last generation is too deep" diff --git a/test/integration/composer/test_history.py b/test/integration/composer/test_history.py index 70807c14ad..53d4906b94 100644 --- a/test/integration/composer/test_history.py +++ b/test/integration/composer/test_history.py @@ -44,8 +44,8 @@ def lagged_ridge_rfr_pipeline(): def _test_individuals_in_history(history: OptHistory): uids = set() ids = set() - for ind in chain(*history.individuals): - # All individuals in `history.individuals` must have a native generation. + for ind in chain(*history.generations): + # All individuals in `history.generations` must have a native generation. assert ind.has_native_generation assert ind.fitness if ind.native_generation == 0: @@ -83,7 +83,7 @@ def test_newly_generated_history(n_jobs: int): history = auto_model.history assert history is not None - assert len(history.individuals) == num_of_gens + 2 # initial_assumptions + num_of_gens + final_choices + assert len(history.generations) == num_of_gens + 2 # initial_assumptions + num_of_gens + final_choices assert len(history.archive_history) == num_of_gens + 2 # initial_assumptions + num_of_gens + final_choices assert len(history.initial_assumptions) >= 2 assert len(history.final_choices) == 1 @@ -151,15 +151,15 @@ def test_history_backward_compatibility(): assert all_historical_fitness assert historical_fitness # Assert that all fitness properties are valid. - assert len(history.individuals) == len(historical_fitness) + assert len(history.generations) == len(historical_fitness) assert np.all(len(generation) == len(gen_fitness) - for generation, gen_fitness in zip(history.individuals, historical_fitness)) - assert np.all(np.equal([ind.fitness.value for ind in chain(*history.individuals)], all_historical_fitness)) + for generation, gen_fitness in zip(history.generations, historical_fitness)) + assert np.all(np.equal([ind.fitness.value for ind in chain(*history.generations)], all_historical_fitness)) # Assert that fitness, graph, parent_individuals, and objective are valid - assert all(isinstance(ind.fitness, SingleObjFitness) for ind in chain(*history.individuals)) - assert all(ind.graph.nodes for ind in chain(*history.individuals)) + assert all(isinstance(ind.fitness, SingleObjFitness) for ind in chain(*history.generations)) + assert all(ind.graph.nodes for ind in chain(*history.generations)) assert all(isinstance(parent_ind, Individual) - for ind in chain(*history.individuals) + for ind in chain(*history.generations) for parent_op in ind.operators_from_prev_generation for parent_ind in parent_op.parent_individuals) _test_individuals_in_history(history) diff --git a/test/integration/quality/test_quality_improvement.py b/test/integration/quality/test_quality_improvement.py index 6ea71cf4b0..0b981fe5aa 100644 --- a/test/integration/quality/test_quality_improvement.py +++ b/test/integration/quality/test_quality_improvement.py @@ -77,7 +77,7 @@ def test_multiobjective_improvement(): def check_improvement(history): - first_pop = history.individuals[1] + first_pop = history.generations[1] pareto_front = history.archive_history[-1] first_pop_metrics = get_mean_metrics(first_pop)