Last active
September 24, 2022 12:03
-
-
Save gngdb/a94776788d6c82d69e96fe7db5d7acd4 to your computer and use it in GitHub Desktop.
An example using scipy.optimize's basin hopping with torch calculating gradients
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
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "hungry-scanning", | |
"metadata": {}, | |
"source": [ | |
"An example using the global optimization algorithm [Basin Hopping][basin] to optimize a scalar function, with gradients on the inner loop conjugate gradient optimizer provided by pytorch. This could be adapted to use the [other global optimizers][global] implemented in `scipy.optimize`.\n", | |
"\n", | |
"Toy Function\n", | |
"===========\n", | |
"\n", | |
"I need a toy function to maximize in 1D. How about this:\n", | |
"\n", | |
"[global]: https://docs.scipy.org/doc/scipy/reference/optimize.html#global-optimization\n", | |
"[basin]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html#scipy.optimize.basinhopping" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "competitive-sheep", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import torch" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"id": "seeing-steering", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def toy(x):\n", | |
" x = x - .5 # bias to place the max in the range (0,1)\n", | |
" return torch.exp(-2.*x**2)*torch.cos(16.*x)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"id": "western-ethernet", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"plt.style.use(\"ggplot\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"id": "central-authorization", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[<matplotlib.lines.Line2D at 0x7fe66f23fc70>]" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"x = torch.linspace(0,1,100)\n", | |
"plt.plot(x, toy(x))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "overall-worth", | |
"metadata": {}, | |
"source": [ | |
"Torch Function\n", | |
"============\n", | |
"\n", | |
"I need a wrapper function:\n", | |
"\n", | |
"1. Takes numpy array (with one value in it)\n", | |
"2. Turns it into a torch tensor that requires grad\n", | |
"3. Passes it through the above function\n", | |
"4. Calculates the gradient\n", | |
"5. Returns the function value as float and the gradient as numpy array" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"id": "distinguished-index", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def torch_wrapper(x):\n", | |
" x = torch.tensor(x, requires_grad=True) # numpy array -> torch tensor\n", | |
" # DON'T NEED TO ZERO GRADIENT BECAUSE GRADIENT WILL BE NONE AT INIT\n", | |
" # if x.grad is not None:\n", | |
" # x.grad.zero_() # zero the gradient, same as optimizer.zero_grads()\n", | |
" f = -toy(x) # negated because we're minimizing to find an optimum\n", | |
" f.backward()\n", | |
" return f.item(), x.grad.numpy()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "overall-competition", | |
"metadata": {}, | |
"source": [ | |
"Run Basin Hopping\n", | |
"================\n", | |
"\n", | |
"Basin hopping runs an internal optimizer, I'm going to choose [conjugate gradients][conjugate] and the arguments must be passed in [minimizer_kwargs][kwargs].\n", | |
"\n", | |
"* `method=\"CG\"` selects the conjugate gradient algorithm\n", | |
"* `disp=True` displays status messages, just for this example\n", | |
"* `jac=True` tells the inner optimizer to expect `func` (in this case, `torch_wrapper`) to return a tuple of `(func_val, grad_array)`; as the docs say:\n", | |
"\n", | |
"> If jac is a Boolean and is True, fun is assumed to return and objective and gradient as an (f, g) tuple. Methods ‘Newton-CG’, ‘trust-ncg’, ‘dogleg’, ‘trust-exact’, and ‘trust-krylov’ require that either a callable be supplied, or that fun return the objective and gradient.\n", | |
"\n", | |
"[conjugate]: https://docs.scipy.org/doc/scipy/reference/optimize.minimize-cg.html#optimize-minimize-cg\n", | |
"[kwargs]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html#scipy.optimize.basinhopping" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"id": "adjusted-singles", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import scipy.optimize" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"id": "organized-stake", | |
"metadata": { | |
"scrolled": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"basinhopping step 0: f -0.738092\n", | |
"basinhopping step 1: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 2: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 3: f -0.0649789 trial_f -0.0649789 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 4: f -0.000502366 trial_f -0.000502366 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 5: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 6: f -0.0649789 trial_f -0.0649789 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 7: f -0.0649789 trial_f -0.00774549 accepted 0 lowest_f -0.738092\n", | |
"basinhopping step 8: f -0.0649789 trial_f -0.0649789 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 9: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 10: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 11: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 12: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 13: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 14: f -0.000502366 trial_f -0.000502366 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 15: f -0.000502366 trial_f -0.000502366 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 16: f -0.00774549 trial_f -0.00774549 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 17: f -0.296759 trial_f -0.296759 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 18: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"found new global minimum on step 18 with function value -1\n", | |
"basinhopping step 19: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 20: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 21: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 22: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 23: f -0.738092 trial_f -0.00774549 accepted 0 lowest_f -1\n", | |
"basinhopping step 24: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 25: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 26: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 27: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 28: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 29: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 30: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 31: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 32: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 33: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 34: f -8.57577e-10 trial_f -8.57577e-10 accepted 1 lowest_f -1\n", | |
"basinhopping step 35: f -9.83625e-12 trial_f -9.83625e-12 accepted 1 lowest_f -1\n", | |
"basinhopping step 36: f -6.92756e-10 trial_f -6.92756e-10 accepted 1 lowest_f -1\n", | |
"basinhopping step 37: f 2.56061e-10 trial_f 2.56061e-10 accepted 1 lowest_f -1\n", | |
"basinhopping step 38: f -1.89463e-11 trial_f -1.89463e-11 accepted 1 lowest_f -1\n", | |
"basinhopping step 39: f -8.41884e-11 trial_f -8.41884e-11 accepted 1 lowest_f -1\n", | |
"basinhopping step 40: f -2.38918e-07 trial_f -2.38918e-07 accepted 1 lowest_f -1\n", | |
"basinhopping step 41: f -3.20204e-07 trial_f -3.20204e-07 accepted 1 lowest_f -1\n", | |
"basinhopping step 42: f -1.77182e-05 trial_f -1.77182e-05 accepted 1 lowest_f -1\n", | |
"basinhopping step 43: f -0.000502366 trial_f -0.000502366 accepted 1 lowest_f -1\n", | |
"basinhopping step 44: f -1.77192e-05 trial_f -1.77192e-05 accepted 1 lowest_f -1\n", | |
"basinhopping step 45: f -3.38004e-07 trial_f -3.38004e-07 accepted 1 lowest_f -1\n", | |
"basinhopping step 46: f -3.53261e-09 trial_f -3.53261e-09 accepted 1 lowest_f -1\n", | |
"basinhopping step 47: f 3.71179e-09 trial_f 3.71179e-09 accepted 1 lowest_f -1\n", | |
"basinhopping step 48: f 3.06148e-08 trial_f 3.06148e-08 accepted 1 lowest_f -1\n", | |
"basinhopping step 49: f -7.20242e-10 trial_f -7.20242e-10 accepted 1 lowest_f -1\n", | |
"adaptive stepsize: acceptance rate 0.920000 target 0.500000 new stepsize 0.555556 old stepsize 0.5\n", | |
"basinhopping step 50: f -1.8799e-11 trial_f -1.8799e-11 accepted 1 lowest_f -1\n", | |
"basinhopping step 51: f 4.79491e-12 trial_f 4.79491e-12 accepted 1 lowest_f -1\n", | |
"basinhopping step 52: f -1.69689e-11 trial_f -1.69689e-11 accepted 1 lowest_f -1\n", | |
"basinhopping step 53: f -1.4664e-11 trial_f -1.4664e-11 accepted 1 lowest_f -1\n", | |
"basinhopping step 54: f -1.85035e-15 trial_f -1.85035e-15 accepted 1 lowest_f -1\n", | |
"basinhopping step 55: f -1.00309e-16 trial_f -1.00309e-16 accepted 1 lowest_f -1\n", | |
"basinhopping step 56: f 8.76664e-19 trial_f 8.76664e-19 accepted 1 lowest_f -1\n", | |
"basinhopping step 57: f -3.74651e-17 trial_f -3.74651e-17 accepted 1 lowest_f -1\n", | |
"basinhopping step 58: f 1.26588e-15 trial_f 1.26588e-15 accepted 1 lowest_f -1\n", | |
"basinhopping step 59: f 3.21604e-18 trial_f 3.21604e-18 accepted 1 lowest_f -1\n", | |
"basinhopping step 60: f -2.81502e-20 trial_f -2.81502e-20 accepted 1 lowest_f -1\n", | |
"basinhopping step 61: f -2.42157e-23 trial_f -2.42157e-23 accepted 1 lowest_f -1\n", | |
"basinhopping step 62: f 2.19138e-21 trial_f 2.19138e-21 accepted 1 lowest_f -1\n", | |
"basinhopping step 63: f 6.45057e-25 trial_f 6.45057e-25 accepted 1 lowest_f -1\n", | |
"basinhopping step 64: f 8.3955e-29 trial_f 8.3955e-29 accepted 1 lowest_f -1\n", | |
"basinhopping step 65: f 4.99976e-29 trial_f 4.99976e-29 accepted 1 lowest_f -1\n", | |
"basinhopping step 66: f 1.08694e-26 trial_f 1.08694e-26 accepted 1 lowest_f -1\n", | |
"basinhopping step 67: f 6.77215e-25 trial_f 6.77215e-25 accepted 1 lowest_f -1\n", | |
"basinhopping step 68: f 1.65313e-21 trial_f 1.65313e-21 accepted 1 lowest_f -1\n", | |
"basinhopping step 69: f 3.01779e-18 trial_f 3.01779e-18 accepted 1 lowest_f -1\n", | |
"basinhopping step 70: f -5.08264e-20 trial_f -5.08264e-20 accepted 1 lowest_f -1\n", | |
"basinhopping step 71: f 5.43143e-22 trial_f 5.43143e-22 accepted 1 lowest_f -1\n", | |
"basinhopping step 72: f -9.18275e-20 trial_f -9.18275e-20 accepted 1 lowest_f -1\n", | |
"basinhopping step 73: f 3.43676e-22 trial_f 3.43676e-22 accepted 1 lowest_f -1\n", | |
"basinhopping step 74: f 1.09878e-25 trial_f 1.09878e-25 accepted 1 lowest_f -1\n", | |
"basinhopping step 75: f -2.1628e-23 trial_f -2.1628e-23 accepted 1 lowest_f -1\n", | |
"basinhopping step 76: f 1.0914e-25 trial_f 1.0914e-25 accepted 1 lowest_f -1\n", | |
"basinhopping step 77: f 1.5329e-28 trial_f 1.5329e-28 accepted 1 lowest_f -1\n", | |
"basinhopping step 78: f 1.06108e-28 trial_f 1.06108e-28 accepted 1 lowest_f -1\n", | |
"basinhopping step 79: f 8.7774e-33 trial_f 8.7774e-33 accepted 1 lowest_f -1\n", | |
"basinhopping step 80: f -4.55858e-39 trial_f -4.55858e-39 accepted 1 lowest_f -1\n", | |
"basinhopping step 81: f -2.66178e-40 trial_f -2.66178e-40 accepted 1 lowest_f -1\n", | |
"basinhopping step 82: f -1.24256e-43 trial_f -1.24256e-43 accepted 1 lowest_f -1\n", | |
"basinhopping step 83: f -1.18363e-43 trial_f -1.18363e-43 accepted 1 lowest_f -1\n", | |
"basinhopping step 84: f 2.40247e-38 trial_f 2.40247e-38 accepted 1 lowest_f -1\n", | |
"basinhopping step 85: f -1.29757e-34 trial_f -1.29757e-34 accepted 1 lowest_f -1\n", | |
"basinhopping step 86: f 5.52329e-30 trial_f 5.52329e-30 accepted 1 lowest_f -1\n", | |
"basinhopping step 87: f 5.48749e-30 trial_f 5.48749e-30 accepted 1 lowest_f -1\n", | |
"basinhopping step 88: f -3.53814e-35 trial_f -3.53814e-35 accepted 1 lowest_f -1\n", | |
"basinhopping step 89: f -2.4334e-35 trial_f -2.4334e-35 accepted 1 lowest_f -1\n", | |
"basinhopping step 90: f -6.95159e-31 trial_f -6.95159e-31 accepted 1 lowest_f -1\n", | |
"basinhopping step 91: f 7.90719e-33 trial_f 7.90719e-33 accepted 1 lowest_f -1\n", | |
"basinhopping step 92: f -1.90114e-35 trial_f -1.90114e-35 accepted 1 lowest_f -1\n", | |
"basinhopping step 93: f 1.0968e-32 trial_f 1.0968e-32 accepted 1 lowest_f -1\n", | |
"basinhopping step 94: f -4.36463e-32 trial_f -4.36463e-32 accepted 1 lowest_f -1\n", | |
"basinhopping step 95: f -3.95555e-32 trial_f -3.95555e-32 accepted 1 lowest_f -1\n", | |
"basinhopping step 96: f -1.19614e-34 trial_f -1.19614e-34 accepted 1 lowest_f -1\n", | |
"basinhopping step 97: f -1.27009e-36 trial_f -1.27009e-36 accepted 1 lowest_f -1\n", | |
"basinhopping step 98: f -5.54331e-39 trial_f -5.54331e-39 accepted 1 lowest_f -1\n", | |
"basinhopping step 99: f -1.60483e-44 trial_f -1.60483e-44 accepted 1 lowest_f -1\n", | |
"adaptive stepsize: acceptance rate 0.960000 target 0.500000 new stepsize 0.617284 old stepsize 0.555556\n", | |
"basinhopping step 100: f 1.09229e-37 trial_f 1.09229e-37 accepted 1 lowest_f -1\n" | |
] | |
} | |
], | |
"source": [ | |
"x0 = 0.1\n", | |
"res = scipy.optimize.basinhopping(torch_wrapper, x0, disp=True,\n", | |
" minimizer_kwargs=dict(method=\"CG\", jac=True)\n", | |
" )" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"id": "antique-associate", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
" fun: -1.0\n", | |
" lowest_optimization_result: fun: -1.0\n", | |
" jac: array([-9.46579248e-08])\n", | |
" message: 'Optimization terminated successfully.'\n", | |
" nfev: 14\n", | |
" nit: 5\n", | |
" njev: 14\n", | |
" status: 0\n", | |
" success: True\n", | |
" x: array([0.5])\n", | |
" message: ['requested number of basinhopping iterations completed successfully']\n", | |
" minimization_failures: 0\n", | |
" nfev: 486\n", | |
" nit: 100\n", | |
" njev: 466\n", | |
" x: array([0.5])" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"res" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"id": "transparent-grade", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Optimum found at [0.5] with value 1.0\n" | |
] | |
} | |
], | |
"source": [ | |
"xstar = res.x\n", | |
"f = -res.fun\n", | |
"print(f\"Optimum found at {xstar} with value {f}\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "cleared-poison", | |
"metadata": {}, | |
"source": [ | |
"Bounds\n", | |
"======\n", | |
"\n", | |
"Adding bounds to this algorithm is slightly different than the standard `scipy.optimize`, where we just enter `bounds=(xmin, xmax)`. There's an example way to implement bounds at the bottom of the [basin hopping page][bounds]. It works by rejecting steps into domains outside the bounds:\n", | |
"\n", | |
"[bounds]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html#scipy.optimize.basinhopping" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"id": "integrated-paraguay", | |
"metadata": { | |
"scrolled": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"basinhopping step 0: f -0.738092\n", | |
"basinhopping step 1: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"found new global minimum on step 1 with function value -1\n", | |
"basinhopping step 2: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 3: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 4: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 5: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 6: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 7: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 8: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 9: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 10: f -0.738092 trial_f -0.00774549 accepted 0 lowest_f -1\n", | |
"basinhopping step 11: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 12: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 13: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 14: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 15: f -0.738092 trial_f -0.296759 accepted 0 lowest_f -1\n", | |
"basinhopping step 16: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 17: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 18: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 19: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 20: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 21: f -0.738092 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 22: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 23: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 24: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 25: f -0.738092 trial_f -0.00774549 accepted 0 lowest_f -1\n", | |
"basinhopping step 26: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 27: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 28: f -0.738092 trial_f -0.00774549 accepted 0 lowest_f -1\n", | |
"basinhopping step 29: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 30: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 31: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 32: f -0.738092 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 33: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 34: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 35: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 36: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 37: f -0.738092 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 38: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 39: f -0.738092 trial_f -0.296759 accepted 0 lowest_f -1\n", | |
"basinhopping step 40: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 41: f -1 trial_f -1.77193e-05 accepted 0 lowest_f -1\n", | |
"basinhopping step 42: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 43: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 44: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 45: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 46: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 47: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 48: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 49: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"adaptive stepsize: acceptance rate 0.640000 target 0.500000 new stepsize 0.555556 old stepsize 0.5\n", | |
"basinhopping step 50: f -0.738092 trial_f -0.00774549 accepted 0 lowest_f -1\n", | |
"basinhopping step 51: f -0.738092 trial_f -0.296759 accepted 0 lowest_f -1\n", | |
"basinhopping step 52: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 53: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 54: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 55: f -1 trial_f -0.296759 accepted 0 lowest_f -1\n", | |
"basinhopping step 56: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 57: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 58: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 59: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 60: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 61: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 62: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 63: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 64: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 65: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 66: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 67: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 68: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 69: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 70: f -1 trial_f -0.738092 accepted 0 lowest_f -1\n", | |
"basinhopping step 71: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 72: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 73: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 74: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 75: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 76: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 77: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 78: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 79: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 80: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 81: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 82: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 83: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 84: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 85: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 86: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 87: f -0.738092 trial_f -0.296759 accepted 0 lowest_f -1\n", | |
"basinhopping step 88: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 89: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 90: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 91: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 92: f -0.738092 trial_f -0.00774549 accepted 0 lowest_f -1\n", | |
"basinhopping step 93: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 94: f -1 trial_f -0.0649789 accepted 0 lowest_f -1\n", | |
"basinhopping step 95: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 96: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 97: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"basinhopping step 98: f -1 trial_f -1 accepted 1 lowest_f -1\n", | |
"basinhopping step 99: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -1\n", | |
"adaptive stepsize: acceptance rate 0.700000 target 0.500000 new stepsize 0.617284 old stepsize 0.555556\n", | |
"basinhopping step 100: f -0.738092 trial_f -0.0649789 accepted 0 lowest_f -1\n" | |
] | |
} | |
], | |
"source": [ | |
"class MyBounds(object):\n", | |
" def __init__(self, xmax=1.0, xmin=0.):\n", | |
" self.xmax = xmax\n", | |
" self.xmin = xmin\n", | |
" def __call__(self, **kwargs):\n", | |
" x = kwargs[\"x_new\"][0]\n", | |
" tmax = x <= self.xmax\n", | |
" tmin = x >= self.xmin\n", | |
" return tmax and tmin\n", | |
"\n", | |
"mybounds = MyBounds()\n", | |
"\n", | |
"x0 = 0.1\n", | |
"res = scipy.optimize.basinhopping(torch_wrapper, x0, disp=True,\n", | |
" minimizer_kwargs=dict(method=\"CG\", jac=True),\n", | |
" accept_test=mybounds)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"id": "explicit-kinase", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
" fun: -1.0\n", | |
" lowest_optimization_result: fun: -1.0\n", | |
" jac: array([-2.77111667e-12])\n", | |
" message: 'Optimization terminated successfully.'\n", | |
" nfev: 14\n", | |
" nit: 5\n", | |
" njev: 14\n", | |
" status: 0\n", | |
" success: True\n", | |
" x: array([0.5])\n", | |
" message: ['requested number of basinhopping iterations completed successfully']\n", | |
" minimization_failures: 0\n", | |
" nfev: 1180\n", | |
" nit: 100\n", | |
" njev: 1109\n", | |
" x: array([0.5])" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"res" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"id": "other-cleaning", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Optimum found at [0.5] with value 1.0\n" | |
] | |
} | |
], | |
"source": [ | |
"xstar = res.x\n", | |
"f = -res.fun\n", | |
"print(f\"Optimum found at {xstar} with value {f}\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "female-pharmacology", | |
"metadata": {}, | |
"source": [ | |
"Reparameterizing\n", | |
"==============\n", | |
"\n", | |
"I would normally reparameterize when optimizing a bounded value, but this seems to fail with basin hopping." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"id": "honest-beauty", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def torch_wrapper(x):\n", | |
" x = torch.tensor(x, requires_grad=True) # numpy array -> torch tensor\n", | |
" reparam_x = torch.sigmoid(x)\n", | |
" f = -toy(reparam_x) # negated because we're minimizing to find an optimum\n", | |
" f.backward()\n", | |
" return f.item(), x.grad.numpy()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"id": "taken-skirt", | |
"metadata": { | |
"scrolled": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"basinhopping step 0: f -0.738092\n", | |
"basinhopping step 1: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 2: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"found new global minimum on step 2 with function value -0.738092\n", | |
"basinhopping step 3: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 4: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 5: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 6: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 7: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 8: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 9: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 10: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 11: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 12: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 13: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 14: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 15: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 16: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 17: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 18: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 19: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 20: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 21: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 22: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 23: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 24: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 25: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 26: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 27: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 28: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 29: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 30: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"found new global minimum on step 30 with function value -0.738092\n", | |
"basinhopping step 31: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 32: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 33: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 34: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 35: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 36: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 37: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 38: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 39: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 40: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 41: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 42: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 43: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 44: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 45: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 46: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 47: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 48: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 49: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"adaptive stepsize: acceptance rate 0.980000 target 0.500000 new stepsize 0.555556 old stepsize 0.5\n", | |
"basinhopping step 50: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 51: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 52: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 53: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 54: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 55: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 56: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 57: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 58: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 59: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 60: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 61: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 62: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 63: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 64: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 65: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 66: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 67: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 68: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 69: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 70: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 71: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 72: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 73: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 74: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 75: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 76: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 77: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 78: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 79: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 80: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 81: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 82: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 83: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 84: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 85: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 86: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 87: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 88: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 89: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 90: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 91: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 92: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 93: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 94: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 95: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 96: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 97: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 98: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"basinhopping step 99: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n", | |
"adaptive stepsize: acceptance rate 0.990000 target 0.500000 new stepsize 0.617284 old stepsize 0.555556\n", | |
"basinhopping step 100: f -0.738092 trial_f -0.738092 accepted 1 lowest_f -0.738092\n" | |
] | |
} | |
], | |
"source": [ | |
"x0 = -1.\n", | |
"res = scipy.optimize.basinhopping(torch_wrapper, x0, disp=True,\n", | |
" minimizer_kwargs=dict(method=\"CG\", jac=True)\n", | |
" )" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"id": "obvious-mount", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Optimum found at tensor([0.1133], dtype=torch.float64) with value 0.7380915689455229\n" | |
] | |
} | |
], | |
"source": [ | |
"xstar = torch.sigmoid(torch.tensor(res.x))\n", | |
"f = -res.fun\n", | |
"print(f\"Optimum found at {xstar} with value {f}\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "exterior-custom", | |
"metadata": {}, | |
"source": [ | |
"The minimum should be easy to find, here's the reparameterized function it's trying to optimize:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"id": "answering-magic", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[<matplotlib.lines.Line2D at 0x7fe664e18550>]" | |
] | |
}, | |
"execution_count": 16, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"x = torch.linspace(-4., 4., 100)\n", | |
"plt.plot(x, [torch_wrapper(a.item())[0] for a in x]) # list comprehension because torch_wrapper expects scalar" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "conceptual-belgium", | |
"metadata": {}, | |
"source": [ | |
"OK, maybe reparameterizing doesn't work well for basin hopping?" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.8.5" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment