-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Search near init params and some mini fixes #985
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0a54c5b
Various mini fixes
nicl-nno 0012b27
WIP add trials
YamLyubov 497bccb
WIP add trials fix setting of arguments
YamLyubov 92c1516
Add search near initial params, fix getting metric while tuning
YamLyubov a9c1364
Fix after rebase
YamLyubov 474b642
Add comments and clarifications
YamLyubov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
from functools import partial | ||
from typing import Tuple | ||
|
||
from hyperopt import fmin, space_eval | ||
from hyperopt import fmin, space_eval, hp, Trials | ||
|
||
from fedot.core.pipelines.pipeline import Pipeline | ||
from fedot.core.pipelines.tuning.search_space import convert_params | ||
from fedot.core.pipelines.tuning.search_space import convert_params, get_node_operation_parameter_label | ||
from fedot.core.pipelines.tuning.tuner_interface import HyperoptTuner | ||
|
||
|
||
|
@@ -18,21 +19,37 @@ def tune(self, pipeline: Pipeline, show_progress: bool = True) -> Pipeline: | |
:param pipeline: Pipeline which hyperparameters will be tuned | ||
:param show_progress: shows progress of tuning if true | ||
""" | ||
parameters_dict = self._get_parameters_for_tune(pipeline) | ||
|
||
# Check source metrics for data | ||
parameters_dict, init_parameters, is_init_params_full = self._get_parameters_for_tune(pipeline) | ||
self.init_check(pipeline) | ||
|
||
pipeline.replace_n_jobs_in_nodes(n_jobs=self.n_jobs) | ||
|
||
trials = Trials() | ||
|
||
# try searching using initial parameters (uses original search space with fixed initial parameters) | ||
try_initial_parameters = init_parameters and self.iterations > 1 | ||
|
||
if try_initial_parameters: | ||
trials, init_trials_num = self._search_near_initial_parameters(pipeline, init_parameters, | ||
is_init_params_full, trials, | ||
show_progress) | ||
|
||
best = fmin(partial(self._objective, pipeline=pipeline), | ||
parameters_dict, | ||
trials=trials, | ||
algo=self.algo, | ||
max_evals=self.iterations, | ||
show_progressbar=show_progress, | ||
early_stop_fn=self.early_stop_fn, | ||
timeout=self.max_seconds) | ||
|
||
# check if best point was obtained using search space with fixed initial parameters | ||
if try_initial_parameters: | ||
is_best_trial_with_init_params = trials.best_trial.get('tid') in range(init_trials_num) | ||
# replace search space | ||
parameters_dict = init_parameters if is_best_trial_with_init_params else parameters_dict | ||
|
||
best = space_eval(space=parameters_dict, hp_assignment=best) | ||
|
||
tuned_pipeline = self.set_arg_pipeline(pipeline=pipeline, | ||
|
@@ -43,14 +60,34 @@ def tune(self, pipeline: Pipeline, show_progress: bool = True) -> Pipeline: | |
|
||
return final_pipeline | ||
|
||
def _get_parameters_for_tune(self, pipeline: Pipeline) -> dict: | ||
def _search_near_initial_parameters(self, pipeline: Pipeline, initial_parameters: dict, | ||
is_init_parameters_full: bool, trials: Trials, | ||
show_progress: bool = True): | ||
if self.iterations >= 10 and not is_init_parameters_full: | ||
init_trials_num = min(int(self.iterations * 0.1), 10) | ||
else: | ||
init_trials_num = 1 | ||
|
||
# fmin updates trials with evaluation points tried out during the call | ||
fmin(partial(self._objective, pipeline=pipeline), | ||
initial_parameters, | ||
trials=trials, | ||
algo=self.algo, | ||
max_evals=init_trials_num, | ||
show_progressbar=show_progress, | ||
early_stop_fn=self.early_stop_fn, | ||
timeout=self.max_seconds) | ||
Comment on lines
+72
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А это так и задумано что fmin ничего не возвращает? Если да, то стоит пояснить. |
||
return trials, init_trials_num | ||
|
||
def _get_parameters_for_tune(self, pipeline: Pipeline) -> Tuple[dict, dict, bool]: | ||
""" | ||
Function for defining the search space | ||
|
||
:return parameters_dict: dictionary with operation names and parameters | ||
""" | ||
|
||
parameters_dict = {} | ||
initial_parameters = {} | ||
for node_id, node in enumerate(pipeline.nodes): | ||
operation_name = node.operation.operation_type | ||
|
||
|
@@ -59,9 +96,28 @@ def _get_parameters_for_tune(self, pipeline: Pipeline) -> dict: | |
node_params = self.search_space.get_node_params(node_id=node_id, | ||
operation_name=operation_name) | ||
|
||
parameters_dict.update({node_id: node_params}) | ||
|
||
return parameters_dict | ||
if node_params is not None: | ||
parameters_dict.update(node_params) | ||
|
||
tunable_node_params = self.search_space.get_operation_parameter_range(operation_name) | ||
tunable_initial_params = {get_node_operation_parameter_label(node_id, operation_name, p): | ||
node.parameters[p] for p in node.parameters if p in tunable_node_params} | ||
if tunable_initial_params: | ||
initial_parameters.update(tunable_initial_params) | ||
|
||
# create search space with fixed initial parameters | ||
init_params_space = {} | ||
is_init_params_full = len(initial_parameters) == len(parameters_dict) | ||
if initial_parameters: | ||
for key in parameters_dict: | ||
if key in initial_parameters: | ||
value = initial_parameters[key] | ||
# fix possible value for initial parameter (the value will be chosen with probability=1) | ||
init_params_space[key] = hp.pchoice(key, [(1, value)]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вот тут с hp.pchoice не очень понятно. |
||
else: | ||
init_params_space[key] = parameters_dict[key] | ||
|
||
return parameters_dict, init_params_space, is_init_params_full | ||
|
||
def _objective(self, parameters_dict: dict, pipeline: Pipeline) \ | ||
-> float: | ||
|
@@ -76,7 +132,6 @@ def _objective(self, parameters_dict: dict, pipeline: Pipeline) \ | |
|
||
# Set hyperparameters for every node | ||
pipeline = self.set_arg_pipeline(pipeline=pipeline, parameters=parameters_dict) | ||
|
||
metric_value = self.get_metric_value(pipeline=pipeline) | ||
return metric_value | ||
|
||
|
@@ -92,7 +147,7 @@ def set_arg_pipeline(pipeline: Pipeline, parameters: dict) -> Pipeline: | |
|
||
# Set hyperparameters for every node | ||
for node_id, _ in enumerate(pipeline.nodes): | ||
node_params = parameters.get(node_id) | ||
node_params = {key: value for key, value in parameters.items() if key.startswith(str(node_id))} | ||
|
||
if node_params is not None: | ||
# Delete all prefix strings to get appropriate parameters names | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут нужен какой-то комментарий, поясняющий что происходит. А то потом сложно будет вспомнить, зачем это.