botorch
botorch copied to clipboard
In the actual experiment, the newly obtained candidate points exceed the choices when i use optimize_acqf_discrete function
🐛 Bug
When I am conducting actual chemical experiments, I take the solvent ratio as the input of my multi-objective Bayesian optimization, and use optimize_ acqf_ This function is used to search for the evaluation point of the next experiment in the solution space I have given. But the result given by my algorithm is not in the solution space given by me. How can I solve this problem? Thank you!
My code will attach as follow. `import os from botorch.exceptions.warnings import BotorchWarning, OptimizationWarning import torch import logging import warnings from copy import deepcopy import numpy as np from botorch.optim.fit import fit_gpytorch_scipy np.random.seed(0) import random from botorch.models.utils import fantasize as fantasize_flag, validate_input_scaling random.seed(0) torch.manual_seed(0) from botorch.acquisition.multi_objective.analytic import ExpectedHypervolumeImprovement from gpytorch.mlls.sum_marginal_log_likelihood import SumMarginalLogLikelihood import torch.nn as nn import gpytorch from botorch.settings import debug from botorch.models.gp_regression import SingleTaskGP from botorch.models.transforms.outcome import Standardize from gpytorch.mlls.exact_marginal_log_likelihood import ExactMarginalLogLikelihood from botorch.utils.transforms import unnormalize from botorch.utils.sampling import draw_sobol_samples from botorch.optim.optimize import optimize_acqf, optimize_acqf_list,optimize_acqf_discrete from botorch.models.converter import batched_to_model_list, model_list_to_batched from botorch.utils.multi_objective.box_decompositions.non_dominated import NondominatedPartitioning from botorch.acquisition.multi_objective.monte_carlo import qExpectedHypervolumeImprovement from botorch import fit_gpytorch_model from botorch.exceptions.errors import UnsupportedError from botorch.sampling.samplers import SobolQMCNormalSampler from botorch.exceptions import BadInitialCandidatesWarning from botorch.utils.multi_objective.pareto import is_non_dominated from botorch.utils.multi_objective.hypervolume import Hypervolume from botorch.optim.utils import sample_all_priors import sys from gpytorch.utils.errors import NotPSDError from gpytorch.kernels.matern_kernel import MaternKernel from gpytorch.kernels.scale_kernel import ScaleKernel from gpytorch.means.constant_mean import ConstantMean from gpytorch.models.exact_gp import ExactGP from gpytorch.priors.torch_priors import GammaPrior from botorch.models.gpytorch import BatchedMultiOutputGPyTorchModel torch.set_default_tensor_type(torch.DoubleTensor) from gpytorch.likelihoods.gaussian_likelihood import ( _GaussianLikelihoodBase, FixedNoiseGaussianLikelihood, GaussianLikelihood,) from gpytorch.constraints.constraints import GreaterThan from gpytorch.distributions.multivariate_normal import MultivariateNormal
a_np=np.array([[0.09,0.11,1000,23,0,120,1], [0.1,0.12,1000,140,20,120,1], [0.11,0.13,1000,130,10,150,1], [0.12,0.14,1000,110,40,120,1], [0.08, 0.11, 1000, 120, 30, 140, 0.8], [0.012, 0.11, 1000, 100, 50, 120, 0.9]]) a_tensor=torch.from_numpy(a_np)
MIN_INFERRED_NOISE_LEVEL = 1e-4 class GPRegressionModel2(BatchedMultiOutputGPyTorchModel, gpytorch.models.ExactGP): def init(self,train_X,train_Y,likelihood =None,covar_module= None,mean_module = None, outcome_transform = None,input_transform = None,) : with torch.no_grad(): transformed_X = self.transform_inputs( X=train_X, input_transform=input_transform )
print(c) print(hvs_qehvi_all) print(pareto_x) print(pareto_y) print(end-start)`
As youcan see,my entire code upload. My input is the real experiment results, i use the optimize_acqf_discrete function to find the new_candidate in my design space( Design space in code is a_tensor) However ,in the trial the new_candidates is not in my design space . Thank you!
The trial result is tensor([[8.0480e-02, 1.0440e-01, 4.0000e+06, 1.2723e+04, 2.5000e+03, 4.3200e+03, 9.5000e-01], [8.4800e-02, 1.0560e-01, 4.0000e+06, 1.3993e+04, 2.0000e+03, 4.3200e+03, 1.0000e+00], [8.4000e-02, 1.0480e-01, 4.0000e+06, 1.7803e+04, 1.0000e+03, 4.3200e+03, 1.0000e+00]]) my design space is: a_np=np.array([[0.09,0.11,1000,23,0,120,1], [0.1,0.12,1000,140,20,120,1], [0.11,0.13,1000,130,10,150,1], [0.12,0.14,1000,110,40,120,1], [0.08, 0.11, 1000, 120, 30, 140, 0.8], [0.012, 0.11, 1000, 100, 50, 120, 0.9]])
What exactly is new_candidates? That variable doesn't appear in your code. Do you mean new_x?
Is a_tensor in normalized space? Noe that you're calling new_x = unnormalize(candidates.detach(), bounds=self.standard_bounds) but it doesn't seem that a_np (from which a_tensor is constructed) is normalized as well.
Hi,thank you for your quick reply. the a_tensor is in my normailized space,Should I divide by the maximum value of each constraint boundary?
a_np=np.array([[0.09,0.11,1000,23,0,120,1], [0.1,0.12,1000,140,20,120,1], [0.11,0.13,1000,130,10,150,1], [0.12,0.14,1000,110,40,120,1], [0.08, 0.11, 1000, 120, 30, 140, 0.8], [0.012, 0.11, 1000, 100, 50, 120, 0.9]]) a_tensor=torch.from_numpy(a_np)
Should I divide by the maximum value of each constraint boundary
Yes, I highly recommend performing the optimization with input domain normalized to the unit cube [0, 1]^d. Our default models use priors on the lenghtscales of the kernel that will likely not work very well (i.e. result in poor model fits) if the scale is very different (e.g. 3 orders of magnitude larger as for your third dimension).
That doesn't explain the fact that the candidates are not elements of a_tensor - even with a crappy model they should be picked from the input to optimize_acqf_discrete. What's going on here:
candidates, _ = optimize_acqf_discrete(
acq_function=acq_func,
q=self.BATCH_SIZE,
choices=a_tensor,
max_batch_size=2048,
unique=True,
)
new_x = unnormalize(candidates.detach(), bounds=self.standard_bounds)
Here candidates should be picked from a_tensor, and new_x should be the candidates normalized back to your original domain (and thus not elements of a_tensor). Is it not true that the elements of candidates are elements of a_tensor (if that's the case sth is wrong, but I suspect that this should work fine).
Btw, if all you want to do is solve a multi-objective optimization problem and don't necessarily care about changing details / components of the optimization I recommend you take a look at Ax (https://ax.dev/) - it has a much simpler interface and will take care of all the pesky issues such as normalization etc. for you. It uses botorch under the hood for the optimization.
Btw, if all you want to do is solve a multi-objective optimization problem and don't necessarily care about changing details / components of the optimization I recommend you take a look at Ax (https://ax.dev/) - it has a much simpler interface and will take care of all the pesky issues such as normalization etc. for you. It uses botorch under the hood for the optimization.
Thank you for your reply ! I will try it later. Have a nice Day!