Skip to content

Instantly share code, notes, and snippets.

@lgeiger
Last active March 14, 2018 10:56
Show Gist options
  • Save lgeiger/57cb27bcb9fb14c12c88c3034ccabd62 to your computer and use it in GitHub Desktop.
Save lgeiger/57cb27bcb9fb14c12c88c3034ccabd62 to your computer and use it in GitHub Desktop.
Hyperlaw
[modules]
tasks
[core]
no_lock: True
log_level: WARNING
[worker]
keep_alive: True
ping_interval: 20
wait_interval: 20
max_reschedules: 0
#!/usr/bin/env bash
action() {
local base="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export PYTHONPATH="$base:$PYTHONPATH"
export LAW_HOME="$base/.law"
export LAW_CONFIG_FILE="$base/law.cfg"
export LUIGI_CONFIG_PATH="$base/luigi.cfg"
export LAW_DATA_PATH="$base/data"
source "$( law completion )"
}
action
import os
import law
import luigi
law.contrib.load('matplotlib')
class Task(law.Task):
def local_path(self, *path):
# LAW_DATA_PATH is defined in setup.sh
parts = [os.getenv("LAW_DATA_PATH"), self.__class__.__name__] + [str(part) for part in path]
return os.path.join(*parts)
def local_target(self, *path, **kwargs):
return law.LocalFileTarget(self.local_path(*path), **kwargs)
class Optimizer(Task, law.LocalWorkflow):
iterations = luigi.IntParameter(default=10, description='Number of iterations')
n_parallel = luigi.IntParameter(default=4, description='Number of parallel evaluations')
n_initial_points = luigi.IntParameter(default=10, description='Number of random sampled values before starting optimizations')
def create_branch_map(self):
return list(range(self.iterations))
def requires(self):
if self.branch == 0:
return None
return Optimizer.req(self, branch=self.branch - 1)
def output(self):
return self.local_target('optimizer_{}.pkl'.format(self.branch))
def run(self):
import skopt
optimizer = skopt.Optimizer(
dimensions=[skopt.space.Real(-5.0, 10.0), skopt.space.Real(0.0, 15.0)],
random_state=1, n_initial_points=self.n_initial_points
) if self.branch == 0 else self.input().load()
x = optimizer.ask(n_points=self.n_parallel) # x is a list of n_points points
output = yield Objective(x=x, iteration=self.branch)
y = [f.load()['y'] for f in output['collection'].targets.values()]
optimizer.tell(x, y)
print('minimum:', min(optimizer.yi))
with self.output().localize('w') as tmp:
tmp.dump(optimizer)
@luigi.util.inherits(Optimizer)
class OptimizerPlot(Task, law.LocalWorkflow):
plot_objective = luigi.BoolParameter(default=True, description='Plot objective. \
Can be expensive to evaluate for high dimensional input')
def create_branch_map(self):
return list(range(self.iterations))
def requires(self):
return Optimizer.req(self)
def output(self):
return law.SiblingFileCollection({
'objective_plot': self.local_target('objective_{}.pdf'.format(self.branch), optional=True),
'evaluations_plot': self.local_target('evaluations_{}.pdf'.format(self.branch)),
'convergence_plot': self.local_target('convergence_{}.pdf'.format(self.branch))
})
def run(self):
from skopt.plots import plot_objective, plot_evaluations, plot_convergence
import matplotlib.pyplot as plt
result = self.input().load().run(None, 0)
output = self.output()
output.dir.touch()
with output.targets['convergence_plot'].localize('w') as tmp:
plot_convergence(result)
tmp.dump(plt.gcf(), bbox_inches='tight')
plt.close()
with output.targets['evaluations_plot'].localize('w') as tmp:
plot_evaluations(result, bins=10)
tmp.dump(plt.gcf(), bbox_inches='tight')
plt.close()
if self.plot_objective and (self.branch + 1) * self.n_parallel >= self.n_initial_points:
plot_objective(result)
with output.targets['objective_plot'].localize('w') as tmp:
tmp.dump(plt.gcf(), bbox_inches='tight')
plt.close()
class Objective(Task, law.LocalWorkflow):
x = luigi.ListParameter()
iteration = luigi.IntParameter()
def create_branch_map(self):
return {i: x for i, x in enumerate(self.x)}
def output(self):
return self.local_target('x_{}_{}.json'.format(self.iteration, self.branch))
def run(self):
from skopt.benchmarks import branin
with self.output().localize('w') as tmp:
tmp.dump({'x': self.branch_data, 'y': branin(self.branch_data)})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment