ScipyGenerator with scipy.optimize.minimize¶
This notebook demonstrates how to use Xopt's ScipyGenerator to drive any supported scipy optimize.minimize method in a sequential ask/tell workflow.
Imports¶
In [1]:
Copied!
import matplotlib.pyplot as plt
from xopt import Evaluator, VOCS, Xopt
from xopt.generators.sequential.scipy import ScipyGenerator
import matplotlib.pyplot as plt
from xopt import Evaluator, VOCS, Xopt
from xopt.generators.sequential.scipy import ScipyGenerator
Define a simple objective¶
We will optimize the 2D Rosenbrock function, exposed through an Xopt evaluator function.
In [2]:
Copied!
def rosenbrock_eval(input_dict):
x0 = input_dict["x0"]
x1 = input_dict["x1"]
y = (1 - x0) ** 2 + 100.0 * (x1 - x0**2) ** 2
return {"y": float(y)}
def rosenbrock_eval(input_dict):
x0 = input_dict["x0"]
x1 = input_dict["x1"]
y = (1 - x0) ** 2 + 100.0 * (x1 - x0**2) ** 2
return {"y": float(y)}
Configure ScipyGenerator¶
Choose a scipy method using method. Here we use L-BFGS-B, but methods such as Nelder-Mead, Powell, and others can also be used.
In [3]:
Copied!
vocs = VOCS(
variables={"x0": [-2.0, 2.0], "x1": [-1.0, 3.0]},
objectives={"y": "MINIMIZE"},
)
generator = ScipyGenerator(
vocs=vocs,
method="L-BFGS-B",
initial_point={"x0": -1.2, "x1": 1.0},
options={"maxiter": 200},
)
evaluator = Evaluator(function=rosenbrock_eval)
X = Xopt(generator=generator, evaluator=evaluator, vocs=vocs)
vocs = VOCS(
variables={"x0": [-2.0, 2.0], "x1": [-1.0, 3.0]},
objectives={"y": "MINIMIZE"},
)
generator = ScipyGenerator(
vocs=vocs,
method="L-BFGS-B",
initial_point={"x0": -1.2, "x1": 1.0},
options={"maxiter": 200},
)
evaluator = Evaluator(function=rosenbrock_eval)
X = Xopt(generator=generator, evaluator=evaluator, vocs=vocs)
Run optimization¶
In [4]:
Copied!
for _ in range(200):
X.step()
best_idx = X.data["y"].argmin()
best = X.data.iloc[best_idx]
print("Evaluations:", len(X.data))
print("Best point:", {"x0": float(best["x0"]), "x1": float(best["x1"])})
print("Best objective:", float(best["y"]))
for _ in range(200):
X.step()
best_idx = X.data["y"].argmin()
best = X.data.iloc[best_idx]
print("Evaluations:", len(X.data))
print("Best point:", {"x0": float(best["x0"]), "x1": float(best["x1"])})
print("Best objective:", float(best["y"]))
/home/runner/work/Xopt/Xopt/xopt/generators/sequential/sequential_generator.py:143: RuntimeWarning: scipy minimize has terminated: CONVERGENCE: RELATIVE REDUCTION OF F <= FACTR*EPSMCH. Returning the latest data point; further Xopt.step() calls will re-evaluate it. Check is_done and result, or call reset() to restart. candidate = self._generate()
Evaluations: 200
Best point: {'x0': 0.9999969191711192, 'x1': 0.9999937960186889}
Best objective: 9.670715229330395e-12
Inspect convergence¶
In [5]:
Copied!
ax = X.data["y"].plot(figsize=(7, 4), logy=True)
ax.set_xlabel("iteration")
ax.set_ylabel("objective y (log scale)")
ax.set_title("ScipyGenerator optimization progression")
plt.tight_layout()
ax = X.data["y"].plot(figsize=(7, 4), logy=True)
ax.set_xlabel("iteration")
ax.set_ylabel("objective y (log scale)")
ax.set_title("ScipyGenerator optimization progression")
plt.tight_layout()