Description
🐛 Bug
See #1220 for context. optimize_acqf
does not support inter-point constraints -- those whose indices
are two-dimensional -- when the acquisition function is qKnowledgeGradient
. This is because gen_one_shot_kg_initial_conditions
does not support inter-point constraints. Since typing constraints correctly is confusing, BoTorch should raise an informative error rather than leaving the user to get a confusing IndexError
and wonder if they typed the constraints wrong :)
To reproduce
from botorch.acquisition import qKnowledgeGradient
from botorch.fit import fit_gpytorch_mll
from botorch.models import SingleTaskGP
from gpytorch.mlls import ExactMarginalLogLikelihood
x = torch.rand((20, 2))
y = x.sum(1, keepdim=True) - 1
model = SingleTaskGP(train_X=x, train_Y=y)
mll = ExactMarginalLogLikelihood(model.likelihood, model)
_ = fit_gpytorch_mll(mll)
bounds = torch.tensor([[0, 0], [1, 1]]).to(x)
q = 2
# should have
# samples[:, 0, 0] * 1 + samples[:, 1, 1] >= 0.5
# where samples is n x q x d
indices = torch.tensor([[0, 0], [1, 1]])
inequality_constraints = [(indices, torch.ones(2).to(x), 0.5)]
acqf = qKnowledgeGradient(model, num_fantasies=8)
candidates, acq_vals = optimize_acqf(
acq_function=acqf,
bounds=bounds,
q=q,
num_restarts=10,
raw_samples=64,
inequality_constraints=inequality_constraints,
)
** Stack trace/error message **
1) IndexError: index 3 is out of bounds for dimension 0 with size 2
File "pytorch/botorch/test/optim/test_optimize.py", line 265, in ftest_optimize_acqf_kg_constrained
candidates, acq_vals = optimize_acqf(
File "botorch/optim/optimize.py", line 557, in optimize_acqf
return _optimize_acqf(opt_acqf_inputs)
File "botorch/optim/optimize.py", line 586, in _optimize_acqf
return _optimize_acqf_batch(
File "botorch/optim/optimize.py", line 269, in _optimize_acqf_batch
batch_initial_conditions = opt_inputs.get_ic_generator()(
File "botorch/optim/initializers.py", line 570, in gen_one_shot_kg_initial_conditions
fantasy_cands, fantasy_vals = optimize_acqf(
File "botorch/optim/optimize.py", line 557, in optimize_acqf
return _optimize_acqf(opt_acqf_inputs)
File "botorch/optim/optimize.py", line 586, in _optimize_acqf
return _optimize_acqf_batch(
File "botorch/optim/optimize.py", line 269, in _optimize_acqf_batch
batch_initial_conditions = opt_inputs.get_ic_generator()(
File "botorch/optim/initializers.py", line 415, in gen_batch_initial_conditions
X_rnd = sample_q_batches_from_polytope(
File "botorch/optim/initializers.py", line 272, in sample_q_batches_from_polytope
samples = get_polytope_samples(
File "botorch/utils/sampling.py", line 800, in get_polytope_samples
constraints = normalize_linear_constraints(bounds, inequality_constraints)
File "botorch/utils/sampling.py", line 754, in normalize_linear_constraints
lower, upper = bounds[:, index]
Expected Behavior
An informative error should be raised explaining that this is not supported. I think the fix here is that gen_one_shot_kg_initial_conditions
should raise an UnsupportedError
or NotImplementedError
if provided inter-point constraints. However, I'm not 100% sure that gen_one_shot_kg_initial_conditions
is the right place for the error, so whoever fixes this should carefully verify that the error is accurate and that usages that don't trigger the error do work.