Skip to content

Instantly share code, notes, and snippets.

@iaroslav-ai
Created March 6, 2017 07:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iaroslav-ai/ded34b4e492f1b5dc8e9ddbe3c5cb166 to your computer and use it in GitHub Desktop.
Save iaroslav-ai/ded34b4e492f1b5dc8e9ddbe3c5cb166 to your computer and use it in GitHub Desktop.
Knowledge transfer for sequential model based optimization
from scipy.optimize import minimize, basinhopping, differential_evolution
import numpy as np
from autograd import numpy as np, grad
class SkoptProxy():
def __init__(self, ModelClass, bounds):
self.ModelClass = ModelClass
self.X = []
self.Y = []
self.C = []
self.context = None
self.bounds = bounds
def sample(self):
r = np.array([np.random.uniform(a,b) for a, b in self.bounds])
return r
def set_context(self, c):
self.context = c
def concat_context(self, C, X):
return np.column_stack([C, X])
def ask(self):
X, Y = self.X, self.Y
i = len(Y)
if i < 10:
x = self.sample()
return x
X = self.concat_context(self.C, X)
model = GaussianProcessRegressor(kernel=Matern())
model = model.fit(X, Y)
y_opt = np.min(Y)
def acquisition_function(x):
x = self.concat_context([self.context], [x])
exploitation, exploration = model.predict(x, return_std=True)
result = exploitation[0] - exploration[0] # ((i%3)/2.0)*
return result
# find some random x's with good values
values = []
for i in range(128):
x = self.sample()
y = acquisition_function(x)
values.append((x, y))
values.sort(key=lambda v: v[1])
best_est = np.inf
best_par = None
# select the best random points
for x0, y0 in values[:5]:
x = minimize(acquisition_function, x0, bounds=self.bounds).x
y = acquisition_function(x)
if y < best_est:
best_est = y
best_par = x
return best_par
def tell(self, x, y):
self.X.append(x)
self.Y.append(y)
self.C.append(self.context)
from skopt import space
from sklearn.svm import SVR
class MultiTaskOptProb():
def __init__(self):
self.space = {
'C': space.Real(-5.0, 5.0),
'gamma': space.Real(-5.0, 5.0),
'epsilon': space.Real(-5.0, 5.0),
}
self.idx = 0
def reset(self):
X = np.random.randn(256, 5)
w = np.random.rand(5)
Y = np.dot(X, w)
pw = np.random.uniform(1.0, 2.0)
nz = np.random.uniform(0.1, 1.0)
Y = np.sign(Y) * (np.abs(Y) ** pw)
Y = Y + np.random.randn(len(Y))*nz
I = np.random.rand(len(X)) < 0.6
X, Xv = X[I], X[~I]
Y, Yv = Y[I], Y[~I]
z = np.zeros(10)
z[self.idx] = 1.0
self.idx += 1
self.data = X, Y, Xv, Yv
# return task specific features
return np.concatenate([z]) # , [pw], [nz]
def step(self, P):
params = {k:10**p for k,p in zip(self.space.keys(), P)}
model = SVR(**params)
X, Y, Xv, Yv = self.data
model.fit(X, Y)
score = model.score(Xv, Yv)
return -score
import json
from skopt import Optimizer
from skopt.learning import GaussianProcessRegressor, RandomForestRegressor, ExtraTreesRegressor
import random
from skopt.learning.gaussian_process.kernels import Matern
MAX_SUBPROBLEM_STEPS=24
MAX_SIMILAR_TASKS=8
REPEATS = 5
recalculate = True
results_file = 'results.json'
if recalculate:
results = {}
for rep in range(REPEATS):
spc = MultiTaskOptProb().space
def get_skopt_optimizer():
return Optimizer(
[spc[k] for k in spc.keys()],
GaussianProcessRegressor(kernel=Matern()),
acq_optimizer="lbfgs"
)
A = SkoptProxy(GaussianProcessRegressor, [(spc[k].low, spc[k].high) for k in spc.keys()])
B = get_skopt_optimizer()
for solver in [A, B]:
task = MultiTaskOptProb()
if not solver.__class__.__name__ in results:
results[solver.__class__.__name__] = []
for similar_task in range(MAX_SIMILAR_TASKS):
print("Episode " + str(similar_task))
trace = []
best_y = np.inf
context = task.reset()
try:
solver.set_context(context)
except AttributeError:
solver = get_skopt_optimizer()
for i in range(MAX_SUBPROBLEM_STEPS):
P = solver.ask()
try:
v = task.step(P)
except BaseException as ex:
v = 1.0
print ex
if best_y > v:
best_y = v
best_x = P
print("#" + str(i) + ", "+ str(best_y))
try:
solver.tell(P, v)
except BaseException as ex:
pass
trace.append(float(best_y))
results[solver.__class__.__name__].append(trace)
else:
results = json.load(open(results_file))
with open(results_file, 'w') as f:
json.dump(results, f)
colors = ['red', 'blue']
name_maps = {SkoptProxy.__name__:'GP, Knowledge transfer', Optimizer.__name__:'Skopt GP, from scratch'}
def visualize_results(results):
import matplotlib.pyplot as plt
for k, c in zip(results.keys(), colors):
y = np.mean(results[k], axis=0)
x = range(len(y))
plt.scatter(x, y, c=c, label=name_maps[k])
plt.xlabel('Iteration')
plt.ylabel('Avg. objective')
plt.grid()
plt.legend()
plt.show()
visualize_results(results)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment