-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
{ | ||
"metadata": { | ||
"signature": "sha256:56f96cf17697048e79058823a57f2bcddffd55678dfbbcba6f2b6ae8a0b99738" | ||
}, | ||
"nbformat": 3, | ||
"nbformat_minor": 0, | ||
"worksheets": [ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"In this example we will use various Optunity solvers to minimize the following simple 2d parabola:\n", | ||
"$$f(x, y) = (x - x_{off})^2 + (y - y_{off})^2,$$\n", | ||
"where $x_{off}$ and $y_{off}$ are randomly determined offsets." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"def create_objective_function():\n", | ||
" xoff = random.random()\n", | ||
" yoff = random.random()\n", | ||
" def f(x, y):\n", | ||
" return (x - xoff)**2 + (y - yoff - 5)**2\n", | ||
" return f" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [], | ||
"prompt_number": 1 | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We start with the necessary imports." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"%matplotlib inline # comment this line when running the notebook yourself\n", | ||
"import math\n", | ||
"import optunity\n", | ||
"import random\n", | ||
"import numpy as np\n", | ||
"import matplotlib.pyplot as plt\n", | ||
"import matplotlib.ticker as ticker" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [], | ||
"prompt_number": 2 | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"First we check which solvers are available. This is available via `optunity.available_solvers`." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"solvers = optunity.available_solvers()\n", | ||
"print('Available solvers: ' + ', '.join(solvers))" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"output_type": "stream", | ||
"stream": "stdout", | ||
"text": [ | ||
"Available solvers: particle swarm, tpe, sobol, nelder-mead, random search, cma-es, grid search\n" | ||
] | ||
} | ||
], | ||
"prompt_number": 3 | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"To run an experiment, we start by generating an objective function." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"f = create_objective_function()" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [], | ||
"prompt_number": 4 | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Now we use every available solver to optimize the objective function within the box $x\\in\\ ]-5, 5[$ and $y\\in\\ ]-5, 5[$ and save the results." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"logs = {}\n", | ||
"for solver in solvers:\n", | ||
" pars, details, _ = optunity.minimize(f, num_evals=100, x=[-5, 5], y=[-5, 5], solver_name=solver)\n", | ||
" logs[solver] = np.array([details.call_log['args']['x'],\n", | ||
" details.call_log['args']['y']])" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [], | ||
"prompt_number": 6 | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Finally, lets look at the results, that is the trace of each solver along with contours of the objective function." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"# make sure different traces are somewhat visually separable\n", | ||
"colors = ['r', 'g', 'b', 'y', 'k', 'y', 'r', 'g']\n", | ||
"markers = ['x', '+', 'o', 's', 'p', 'x', '+', 'o']\n", | ||
"\n", | ||
"# compute contours of the objective function\n", | ||
"delta = 0.025\n", | ||
"x = np.arange(-5.0, 5.0, delta)\n", | ||
"y = np.arange(-5.0, 5.0, delta)\n", | ||
"X, Y = np.meshgrid(x, y)\n", | ||
"Z = f(X, Y)\n", | ||
"\n", | ||
"CS = plt.contour(X, Y, Z)\n", | ||
"plt.clabel(CS, inline=1, fontsize=10, alpha=0.5)\n", | ||
"for i, solver in enumerate(solvers):\n", | ||
" plt.scatter(logs[solver][0,:], logs[solver][1,:], c=colors[i], marker=markers[i], alpha=0.80)\n", | ||
"\n", | ||
"plt.xlim([-5, 5])\n", | ||
"plt.ylim([-5, 5])\n", | ||
"plt.axis('equal')\n", | ||
"plt.legend(solvers)\n", | ||
"plt.show()" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [], | ||
"prompt_number": 7 | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Now lets see the performance of the solvers across in 100 repeated experiments. We will do 100 experiments for each solver and then report the resulting statistics. This may take a while to run." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"collapsed": false, | ||
"input": [ | ||
"optima = dict([(s, []) for s in solvers])\n", | ||
"for i in range(100):\n", | ||
" f = create_objective_function()\n", | ||
"\n", | ||
" for solver in solvers:\n", | ||
" pars, details, _ = optunity.minimize(f, num_evals=100, x=[-5, 5], y=[-5, 5],\n", | ||
" solver_name=solver)\n", | ||
" # the above line can be parallelized by adding `pmap=optunity.pmap`\n", | ||
" # however this is incompatible with IPython\n", | ||
"\n", | ||
" optima[solver].append(details.optimum)\n", | ||
" logs[solver] = np.array([details.call_log['args']['x'],\n", | ||
" details.call_log['args']['y']])\n", | ||
"\n", | ||
"from collections import OrderedDict\n", | ||
"log_optima = OrderedDict()\n", | ||
"means = OrderedDict()\n", | ||
"std = OrderedDict()\n", | ||
"for k, v in optima.items():\n", | ||
" log_optima[k] = [-math.log10(val) for val in v]\n", | ||
" means[k] = sum(log_optima[k]) / len(v)\n", | ||
" std[k] = np.std(log_optima[k])\n", | ||
"\n", | ||
"plt.barh(np.arange(len(means)), means.values(), height=0.8, xerr=std.values(), alpha=0.5)\n", | ||
"plt.xlabel('number of correct digits')\n", | ||
"plt.yticks(np.arange(len(means))+0.4, list(means.keys()))\n", | ||
"plt.tight_layout()\n", | ||
"plt.show()" | ||
], | ||
"language": "python", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"metadata": {}, | ||
"output_type": "display_data", | ||
"png": "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\n", | ||
"text": [ | ||
"<matplotlib.figure.Figure at 0x7fd78b35ce90>" | ||
] | ||
} | ||
], | ||
"prompt_number": 8 | ||
} | ||
], | ||
"metadata": {} | ||
} | ||
] | ||
} |