Commit a850be48 authored by Shufan Huang's avatar Shufan Huang Committed by chicm-ms
Browse files

Support convert nested dict in TPE (#1023)

parent 2ea753a6
...@@ -132,6 +132,8 @@ tuner: ...@@ -132,6 +132,8 @@ tuner:
> Builtin Tuner Name: **SMAC** > 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** **Installation**
SMAC need to be installed by following command before first use. SMAC need to be installed by following command before first use.
......
...@@ -145,7 +145,7 @@ def parse_init_json(data): ...@@ -145,7 +145,7 @@ def parse_init_json(data):
if value == 'Empty': if value == 'Empty':
params[key] = ['Empty'] params[key] = ['Empty']
else: else:
params[key] = [value[0], value[1]['_value'], value[1]['_value']] params[key] = [value[0], value[1], value[1]]
return params return params
......
{"layer2": "Empty", "layer8": ["Conv", {"_index": 0, "_value": 2}], "layer3": ["Avg_pool", {"_index": 2, "_value": 5}], "layer0": ["Max_pool", {"_index": 2, "_value": 5}], "layer1": ["Conv", {"_index": 0, "_value": 2}], "layer6": ["Max_pool", {"_index": 1, "_value": 3}], "layer7": ["Max_pool", {"_index": 2, "_value": 5}], "layer9": ["Conv", {"_index": 0, "_value": 2}], "layer4": ["Avg_pool", {"_index": 1, "_value": 3}], "layer5": ["Avg_pool", {"_index": 2, "_value": 5}]} {
"layer2": "Empty",
"layer8": ["Conv", 2],
"layer3": ["Avg_pool", 5],
"layer0": ["Max_pool", 5],
"layer1": ["Conv", 2],
"layer6": ["Max_pool", 3],
"layer7": ["Max_pool", 5],
"layer9": ["Conv", 2],
"layer4": ["Avg_pool", 3],
"layer5": ["Avg_pool", 5]
}
...@@ -139,40 +139,50 @@ def json2vals(in_x, vals, out_y, name=ROOT): ...@@ -139,40 +139,50 @@ def json2vals(in_x, vals, out_y, name=ROOT):
for i, temp in enumerate(in_x): for i, temp in enumerate(in_x):
json2vals(temp, vals[i], out_y, name + '[%d]' % i) json2vals(temp, vals[i], out_y, name + '[%d]' % i)
def params2tuner_params(in_x, parameter): def _add_index(in_x, parameter):
""" """
change parameters in NNI format to parameters in hyperopt format. change parameters in NNI format to parameters in hyperopt format(This function also support nested dict.).
For example, NNI receive parameters like: For example, receive parameters like:
{'dropout_rate': 0.8, 'conv_size': 3, 'hidden_size': 512} {'dropout_rate': 0.8, 'conv_size': 3, 'hidden_size': 512}
Will change to format in hyperopt, like: Will change to format in hyperopt, like:
{'dropout_rate': 0.8, 'conv_size': {'_index': 1, '_value': 3}, 'hidden_size': {'_index': 1, '_value': 512}} {'dropout_rate': 0.8, 'conv_size': {'_index': 1, '_value': 3}, 'hidden_size': {'_index': 1, '_value': 512}}
""" """
tuner_params = dict() if TYPE not in in_x: # if at the top level
for key in parameter.keys(): out_y = dict()
value = parameter[key] for key, value in parameter.items():
_type = in_x[key][TYPE] out_y[key] = _add_index(in_x[key], value)
if _type == 'choice': return out_y
_idx = in_x[key][VALUE].index(value) elif isinstance(in_x, dict):
tuner_params[key] = { value_type = in_x[TYPE]
INDEX: _idx, value_format = in_x[VALUE]
VALUE: value if value_type == "choice":
} choice_name = parameter[0] if isinstance(parameter, list) 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:
return {INDEX: pos, VALUE: [choice_name, _add_index(choice_value_format, parameter[1])]}
elif choice_name == item:
return {INDEX: pos, VALUE: item}
else: else:
tuner_params[key] = value return parameter
return tuner_params
def _split_index(params): def _split_index(params):
""" """
Delete index infromation from params Delete index infromation from params
""" """
result = {} if isinstance(params, list):
return [params[0], _split_index(params[1])]
elif isinstance(params, dict):
if INDEX in params.keys():
return _split_index(params[VALUE])
result = dict()
for key in params: for key in params:
if isinstance(params[key], dict): result[key] = _split_index(params[key])
value = params[key][VALUE]
else:
value = params[key]
result[key] = value
return result return result
else:
return params
class HyperoptTuner(Tuner): class HyperoptTuner(Tuner):
...@@ -399,6 +409,6 @@ class HyperoptTuner(Tuner): ...@@ -399,6 +409,6 @@ class HyperoptTuner(Tuner):
continue continue
self.supplement_data_num += 1 self.supplement_data_num += 1
_parameter_id = '_'.join(["ImportData", str(self.supplement_data_num)]) _parameter_id = '_'.join(["ImportData", str(self.supplement_data_num)])
self.total_data[_parameter_id] = params2tuner_params(self.json, _params) self.total_data[_parameter_id] = _add_index(in_x=self.json, parameter=_params)
self.receive_trial_result(parameter_id=_parameter_id, parameters=_params, value=_value) self.receive_trial_result(parameter_id=_parameter_id, parameters=_params, value=_value)
logger.info("Successfully import data to TPE/Anneal tuner.") logger.info("Successfully import data to TPE/Anneal tuner.")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment