Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Support convert nested dict in TPE #1023

Merged
merged 16 commits into from
Apr 28, 2019
2 changes: 2 additions & 0 deletions docs/en_US/Builtin_Tuner.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ tuner:

> Builtin Tuner Name: **SMAC**

**Please note that SMAC doesn't support running on windows currently. The specific reason can be referred to this [github issue](https://github.com/automl/SMAC3/issues/483).**

**Installation**

SMAC need to be installed by following command before first use.
Expand Down
44 changes: 27 additions & 17 deletions src/sdk/pynni/nni/hyperopt_tuner/hyperopt_tuner.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,27 +139,36 @@ def json2vals(in_x, vals, out_y, name=ROOT):
for i, temp in enumerate(in_x):
json2vals(temp, vals[i], out_y, name + '[%d]' % i)

def params2tuner_params(in_x, parameter):
def convert2tuner_params(in_x, parameter, father_object=None, father_key=None):
"""
change parameters in NNI format to parameters in hyperopt format.
For example, NNI receive parameters like:
change parameters in NNI format to parameters in hyperopt format(This function also support nested dict.).
For example, receive parameters like:
{'dropout_rate': 0.8, 'conv_size': 3, 'hidden_size': 512}
Will change to format in hyperopt, like:
{'dropout_rate': 0.8, 'conv_size': {'_index': 1, '_value': 3}, 'hidden_size': {'_index': 1, '_value': 512}}
"""
tuner_params = dict()
for key in parameter.keys():
value = parameter[key]
_type = in_x[key][TYPE]
if _type == 'choice':
_idx = in_x[key][VALUE].index(value)
tuner_params[key] = {
INDEX: _idx,
VALUE: value
}
else:
tuner_params[key] = value
return tuner_params
if TYPE not in in_x:
# if at the top level
for key, value in parameter.items():
convert2tuner_params(in_x[key], value, parameter, key)
elif isinstance(in_x, dict):
value_type = in_x[TYPE]
value_format = in_x[VALUE]
if value_type == "choice":
choice_name = list(parameter.keys())[0] if isinstance(parameter, dict) else parameter
for pos, item in enumerate(value_format): # here value_format is a list
if isinstance(item, list): # this format is ["choice_key", format_dict]
choice_key = item[0]
choice_value_format = item[1]
if choice_key == choice_name:
convert2tuner_params(choice_value_format, parameter[choice_name], parameter, choice_name)
break
elif choice_name == item:
if isinstance(parameter, dict):
parameter[choice_name] = {INDEX: pos, VALUE: item}
else:
father_object[father_key] = {INDEX: pos, VALUE: item}
break
PurityFan marked this conversation as resolved.
Show resolved Hide resolved

def _split_index(params):
"""
Expand Down Expand Up @@ -399,6 +408,7 @@ def import_data(self, data):
continue
self.supplement_data_num += 1
_parameter_id = '_'.join(["ImportData", str(self.supplement_data_num)])
self.total_data[_parameter_id] = params2tuner_params(self.json, _params)
convert2tuner_params(in_x=self.json, parameter=_params)
self.total_data[_parameter_id] = _params
self.receive_trial_result(parameter_id=_parameter_id, parameters=_params, value=_value)
logger.info("Successfully import data to TPE/Anneal tuner.")