import numpy as np
from spotpython.fun.objectivefunctions import Analytical
from spotpython.utils.init import fun_control_init, surrogate_control_init
from spotpython.spot import spot
17 User-Specified Functions: Extending the Analytical Class
This chapter illustrates how user-specified functions can be optimized and analyzed with the spotpython
package by extending the Analytical
class.
17.0.1 The Objective Function: User Specified
We will use an analytical objective function, i.e., a function that can be described by a (closed) formula: \[ f(x) = \sum_i^k x_i^4. \]
This function is continuous, convex and unimodal. The global minimum is \[ f(x) = 0, \text{at } x = (0,0, \ldots, 0). \]
- The
Analytical
class can be extended as follows:
from typing import Optional, Dict
class UserAnalytical(Analytical):
def fun_user_function(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.ndarray:
"""
Custom new function: f(x) = x^4
Args:
X (np.ndarray): Input data as a 2D array.
fun_control (Optional[Dict]): Control parameters for the function.
Returns:
np.ndarray: Computed values with optional noise.
Examples:
>>> import numpy as np
>>> X = np.array([[1, 2, 3], [4, 5, 6]])
>>> fun = UserAnalytical()
>>> fun.fun_user_function(X)
"""
= self._prepare_input_data(X, fun_control)
X
= np.ones(X.shape[1]) * self.offset
offset = np.sum((X - offset) **4, axis=1)
y
# Add noise if specified in fun_control
return self._add_noise(y)
= UserAnalytical()
user_fun = np.array([[0, 0, 0], [1, 1, 1]])
X = user_fun.fun_user_function(X)
results print(results)
[0. 3.]
= UserAnalytical(offset=1.0)
user_fun = np.array([[0, 0, 0], [1, 1, 1]])
X = user_fun.fun_user_function(X)
results print(results)
[3. 0.]
= UserAnalytical(sigma=1.0)
user_fun = np.array([[0, 0, 0], [1, 1, 1]])
X = user_fun.fun_user_function(X)
results print(results)
[0.06691138 3.11495313]
= UserAnalytical().fun_user_function
user_fun = fun_control_init(
fun_control ="USER",
PREFIX= -1.0*np.ones(2),
lower = np.ones(2),
upper =["User Pressure", "User Temp"],
var_name=True,
TENSORBOARD_CLEAN=True)
tensorboard_log= spot.Spot(fun=user_fun,
spot_user =fun_control)
fun_control spot_user.run()
Moving TENSORBOARD_PATH: runs/ to TENSORBOARD_PATH_OLD: runs_OLD/runs_2024_12_14_20_34_18
Created spot_tensorboard_path: runs/spot_logs/USER_maans08_2024-12-14_20-34-18 for SummaryWriter()
spotpython tuning: 3.715394917589437e-05 [#######---] 73.33%
spotpython tuning: 3.715394917589437e-05 [########--] 80.00%
spotpython tuning: 3.715394917589437e-05 [#########-] 86.67%
spotpython tuning: 3.715394917589437e-05 [#########-] 93.33%
spotpython tuning: 1.3840535984457729e-05 [##########] 100.00% Done...
<spotpython.spot.spot.Spot at 0x12ca69e80>
17.0.2 Results
= spot_user.print_results() _
min y: 1.3840535984457729e-05
User Pressure: 0.060781734267030006
User Temp: 0.020927320560756916
spot_user.plot_progress()
17.0.3 A Contour Plot
We can select two dimensions, say \(i=0\) and \(j=1\), and generate a contour plot as follows.
Note:
We have specified identical min_z
and max_z
values to generate comparable plots.
=0, j=1, min_z=0, max_z=2.25) spot_user.plot_contour(i
- The variable importance:
= spot_user.print_importance() _
User Pressure: 77.95830652608618
User Temp: 100.0
spot_user.plot_importance()
17.1 Jupyter Notebook
Note
- The Jupyter-Notebook of this lecture is available on GitHub in the Hyperparameter-Tuning-Cookbook Repository