Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/maxpumperla/hyperas
Browse files Browse the repository at this point in the history
  • Loading branch information
maxpumperla committed Jun 21, 2017
2 parents 631f1c6 + a0b943e commit b9d167b
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 16 deletions.
22 changes: 13 additions & 9 deletions hyperas/optim.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

import nbformat
import numpy as np
from hyperopt import fmin, space_eval
from hyperopt import fmin
from nbconvert import PythonExporter

from .ensemble import VotingModel
from .utils import (
remove_imports, remove_all_comments, extract_imports, temp_string,
write_temp_files, determine_indent, with_line_numbers)
write_temp_files, determine_indent, with_line_numbers, unpack_hyperopt_vals,
eval_hyperopt_space)

sys.path.append(".")

Expand Down Expand Up @@ -52,7 +53,7 @@ def minimize(model,
-------
If `return_space` is False: A pair consisting of the results dictionary of the best run and the corresponding
keras model.
If `return_space` is True: The pair of best result and correspondeing keras model, and the hyperopt search space
If `return_space` is True: The pair of best result and corresponding keras model, and the hyperopt search space
"""
best_run, space = base_minimizer(model=model,
data=data,
Expand All @@ -68,14 +69,15 @@ def minimize(model,
best_model = None
for trial in trials:
vals = trial.get('misc').get('vals')
for key in vals.keys():
vals[key] = vals[key][0]
if trial.get('misc').get('vals') == best_run and 'model' in trial.get('result').keys():
# unpack the values from lists without overwriting the mutable dict within 'trial'
unpacked_vals = unpack_hyperopt_vals(vals)
# identify the best_run (comes with unpacked values from the hyperopt function `base.Trials.argmin`)
if unpacked_vals == best_run and 'model' in trial.get('result').keys():
best_model = trial.get('result').get('model')

if eval_space is True:
# evaluate the search space
best_run = space_eval(space, best_run)
best_run = eval_hyperopt_space(space, best_run)

if return_space is True:
# return the space as well
Expand Down Expand Up @@ -114,7 +116,8 @@ def base_minimizer(model, data, functions, algo, max_evals, trials,
algo=algo,
max_evals=max_evals,
trials=trials,
rseed=rseed),
rseed=rseed,
return_argmin=True),
get_space()
)
except TypeError:
Expand All @@ -126,7 +129,8 @@ def base_minimizer(model, data, functions, algo, max_evals, trials,
algo=algo,
max_evals=max_evals,
trials=trials,
rstate=np.random.RandomState(rseed)),
rstate=np.random.RandomState(rseed),
return_argmin=True),
get_space()
)

Expand Down
44 changes: 38 additions & 6 deletions hyperas/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
import warnings
from operator import attrgetter

from hyperopt import space_eval


class ImportParser(ast.NodeVisitor):
def __init__(self):
self.lines = []
self.line_numbers = []


def visit_Import(self,node):
def visit_Import(self, node):
line = 'import {}'.format(self._import_names(node.names))
if (self._import_asnames(node.names)!=''):
line += ' as {}'.format(self._import_asnames(node.names) )
if (self._import_asnames(node.names) != ''):
line += ' as {}'.format(self._import_asnames(node.names))
self.line_numbers.append(node.lineno)
self.lines.append(line)

Expand All @@ -22,7 +23,7 @@ def visit_ImportFrom(self, node):
node.level * '.',
node.module or '',
self._import_names(node.names))
if (self._import_asnames(node.names)!=''):
if (self._import_asnames(node.names) != ''):
line += " as {}".format(self._import_asnames(node.names))
self.line_numbers.append(node.lineno)
self.lines.append(line)
Expand Down Expand Up @@ -91,7 +92,7 @@ def with_line_numbers(code):
Parameters
----------
str : string
code : string
any multiline text, such as as (fragments) of source code
Returns
Expand Down Expand Up @@ -149,3 +150,34 @@ def determine_indent(str):
indent, len(indent), new_indent, len(new_indent)))
indent = new_indent
return indent


def unpack_hyperopt_vals(vals):
"""
Unpack values from a hyperopt return dictionary where values are wrapped in a list.
:param vals: dict
:return: dict
copy of the dictionary with unpacked values
"""
assert isinstance(vals, dict), "Parameter must be given as dict."
ret = {}
for k, v in list(vals.items()):
try:
ret[k] = v[0]
except (TypeError, IndexError):
ret[k] = v
return ret


def eval_hyperopt_space(space, vals):
"""
Evaluate a set of parameter values within the hyperopt space.
Optionally unpacks the values, if they are wrapped in lists.
:param space: dict
the hyperopt space dictionary
:param vals: dict
the values from a hyperopt trial
:return: evaluated space
"""
unpacked_vals = unpack_hyperopt_vals(vals)
return space_eval(space, unpacked_vals)
74 changes: 73 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
from hyperopt import hp
from hyperas.utils import (
extract_imports, remove_imports, remove_all_comments, temp_string,
write_temp_files, with_line_numbers, determine_indent)
write_temp_files, with_line_numbers, determine_indent, unpack_hyperopt_vals,
eval_hyperopt_space)

TEST_SOURCE = """
from __future__ import print_function
Expand Down Expand Up @@ -100,3 +102,73 @@ def test_determine_indent():
assert determine_indent(code) == ' '
code = "def do_stuff(x):\n\tfoo"
assert determine_indent(code) == '\t'


def test_unpack_hyperopt_vals():
test_vals = {
'filters_conv_A': [0],
'filters_conv_B': [1],
'rate': [0.1553971698387464],
'units': [1],
'rate_1': [0.4114807190252343],
'lr': [2.0215692016654265e-05],
'momentum': [2],
'nesterov': [0]
}
result = {
'filters_conv_A': 0,
'filters_conv_B': 1,
'rate': 0.1553971698387464,
'units': 1,
'rate_1': 0.4114807190252343,
'lr': 2.0215692016654265e-05,
'momentum': 2,
'nesterov': 0
}
assert unpack_hyperopt_vals(test_vals) == result


def test_eval_hyperopt_space():
space = {
'filters_conv_A': hp.choice('filters_conv_A', [8, 16]),
'filters_conv_B': hp.choice('filters_conv_B', [16, 24]),
'rate': hp.uniform('rate', 0, 1),
'units': hp.choice('units', [96, 128, 192]),
'rate_1': hp.uniform('rate_1', 0, 1),
'lr': hp.uniform('lr', 1e-5, 1e-4),
'momentum': hp.choice('momentum', [0.5, 0.9, 0.999]),
'nesterov': hp.choice('nesterov', [True, False])
}
test_vals = {
'filters_conv_A': [0],
'filters_conv_B': [1],
'rate': [0.1553971698387464],
'units': [1],
'rate_1': [0.4114807190252343],
'lr': [2.0215692016654265e-05],
'momentum': [2],
'nesterov': [0]
}
test_vals_unpacked = {
'filters_conv_A': 0,
'filters_conv_B': 1,
'rate': 0.1553971698387464,
'units': 1,
'rate_1': 0.4114807190252343,
'lr': 2.0215692016654265e-05,
'momentum': 2,
'nesterov': 0
}
result = {
'filters_conv_A': 8,
'filters_conv_B': 24,
'rate': 0.1553971698387464,
'units': 128,
'rate_1': 0.4114807190252343,
'lr': 2.0215692016654265e-05,
'momentum': 0.999,
'nesterov': True
}

assert eval_hyperopt_space(space, test_vals) == result
assert eval_hyperopt_space(space, test_vals_unpacked) == result

0 comments on commit b9d167b

Please sign in to comment.