In [ ]:
%load_ext autoreload
%autoreload 2

In [ ]:
from IPython.core.debugger import Tracer # debugging
from IPython.display import clear_output

import time

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns # prettify matplotlib
from mpl_toolkits.mplot3d import Axes3D # for matplotlib 3D plots

import numpy as np

In [ ]:
# local modules
import optimisation as op
import plot3D
import plotly.offline as py
py.init_notebook_mode(connected=True)

In [ ]:
# make deterministic
np.random.seed(100)

1 Parameter - Grid Search


In [ ]:
f = lambda x: x * np.cos(x)
x = np.linspace(0, 12, 100)
y = f(x)

In [ ]:
plt.figure(figsize=(16,8))
plt.plot(x, y, 'g-')
plt.margins(0.1, 0.1)
plt.xlabel('x')
plt.ylabel('cost')
plt.show()

In [ ]:
ranges = {
    'x' : np.linspace(0, 12, 100)
}
class TestEvaluator(op.LocalEvaluator):
    def test_config(self, config):
        #time.sleep(1)
        return f(config.x)
optimiser = op.GridSearchOptimiser(ranges, queue_size=100)
optimiser.poll_interval = 0 # run the optimiser loop faster, not reccomended when the evaluator is anything but instant
evaluator = TestEvaluator(optimiser)

In [ ]:
optimiser.start(run_async=True)
evaluator.start(run_async=True)

In [ ]:
optimiser.wait_for()
evaluator.wait_for()

In [ ]:
optimiser.report()
print('-'*25)
print(optimiser.log_record)
print('-'*25)
print(evaluator.log_record)

In [ ]:
test_xs, test_ys = zip(*[(s.config.x, s.cost) for s in optimiser.samples])
best_config, best_y = optimiser.best_sample()
best_x = best_config.x

In [ ]:
plt.figure(figsize=(16,8))
plt.plot(x, y, 'g-')
plt.plot(test_xs, test_ys, 'bo', markersize=5)
plt.plot([best_x], [best_y], 'ro', markersize=10)
plt.margins(0.1, 0.1)
plt.xlabel('x')
plt.ylabel('cost')
plt.show()

In [ ]:
optimiser.plot_param('x', plot_boxplot=False, plot_samples=True, plot_means=True)

Note

can use np.logspace to space points out logarithmically rather than linearly, remember that the start and end points are $\mathrm{base}^{\mathrm{start}}$ and $\mathrm{base}^{\mathrm{end}}$ hence why log(start), log(end) is used below

also note that the base of the logarithm is pretty much insignificant (as seen by the blue vs red points)

another point is that the ranges passed to the optimisers need only be numpy arrays, so you can shuffle them or pass custom arrays rather than using linspace or other means.


In [ ]:
import math
n = 100
base = 10
xs = np.logspace(math.log(1e-4, base), math.log(1e4, base), num=n, base=base)
ys = [0.1] * n

base = 2
xs2 = np.logspace(math.log(1e-4, base), math.log(1e4, base), num=n, base=base)
ys2 = [-0.1] * n

plt.figure(figsize=(16,3))
plt.plot(xs, ys, 'bo', markersize=5)
plt.plot(xs2, ys2, 'ro', markersize=5)
plt.axes().set_ylim((-2,2))
plt.margins(0.1, 0.1)
plt.show()

3 Parameters - Grid Search


In [ ]:
def f(x,y):
    return 1.5 * (np.sin(0.5*x)**2 * np.cos(y) + 0.1*x + 0.2*y)

X = np.linspace(-6, 6, 100)
Y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(X, Y)
Z = f(X,Y)

In [ ]:
plot3D.surface3D(X,Y,Z)

In [ ]:
ranges = {
    'x' : np.linspace(-6, 6, num=10),
    'y' : np.linspace(-5, 5, num=10),
    'z' : np.array([-0.5, 0.5]),
    'another' : np.array(['a', 'b'])
}
#np.random.shuffle(ranges['x'])
#np.random.shuffle(ranges['y'])

order = ['x', 'y', 'z', 'another']
class TestEvaluator(op.LocalEvaluator):
    def test_config(self, config):
        #time.sleep(1)
        return f(config.x, config.y) + config.z
optimiser = op.GridSearchOptimiser(ranges, queue_size=100, order=order)
optimiser.poll_interval = 0 # run the optimiser loop faster, not reccomended when the evaluator is anything but instant
#optimiser = op.RandomSearchOptimiser(ranges, queue_size=100, allow_re_tests=False)
evaluator = TestEvaluator(optimiser)

In [ ]:
optimiser.start(run_async=True)
evaluator.start(run_async=True)

In [ ]:
optimiser.wait_for()
evaluator.wait_for()

In [ ]:
optimiser.report()
print(optimiser.log_record)

Scatter plot of parameters against cost


In [ ]:
optimiser.scatter_plot('x', 'y', interactive=True, color_by='cost')

Plot as a surface


In [ ]:
optimiser.surface_plot('x', 'y')

In [ ]:
optimiser.plot_param('x', plot_boxplot=True, plot_samples=True, plot_means=True)
optimiser.plot_param('y', plot_boxplot=True, plot_samples=True, plot_means=True)
optimiser.plot_param('z', plot_boxplot=True, plot_samples=True, plot_means=True)

In [ ]: