Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_initialize_q_multi_fidelity_knowledge_gradient(self):
for dtype in (torch.float, torch.double):
mean = torch.zeros(1, 1, device=self.device, dtype=dtype)
mm = MockModel(MockPosterior(mean=mean))
# test error when not specifying current_value
with self.assertRaises(UnsupportedError):
qMultiFidelityKnowledgeGradient(
model=mm, num_fantasies=None, cost_aware_utility=mock.Mock()
)
# test default construction
mock_cau = mock.Mock()
current_value = torch.zeros(1, device=self.device, dtype=dtype)
qMFKG = qMultiFidelityKnowledgeGradient(
model=mm,
num_fantasies=32,
current_value=current_value,
cost_aware_utility=mock_cau,
)
self.assertEqual(qMFKG.num_fantasies, 32)
self.assertIsInstance(qMFKG.sampler, SobolQMCNormalSampler)
def test_abstract_raises(self):
with self.assertRaises(TypeError):
MCAcquisitionFunction()
# raise if model is multi-output, but no objective is given
no = "botorch.utils.testing.MockModel.num_outputs"
with mock.patch(no, new_callable=mock.PropertyMock) as mock_num_outputs:
mock_num_outputs.return_value = 2
mm = MockModel(MockPosterior())
with self.assertRaises(UnsupportedError):
DummyMCAcquisitionFunction(model=mm)
def test_MockModel(self):
mp = MockPosterior()
mm = MockModel(mp)
X = torch.empty(0)
self.assertEqual(mm.posterior(X), mp)
self.assertEqual(mm.num_outputs, 0)
mm.state_dict()
mm.load_state_dict()
def test_q_probability_of_improvement(self):
for dtype in (torch.float, torch.double):
# the event shape is `b x q x t` = 1 x 1 x 1
samples = torch.zeros(1, 1, 1, device=self.device, dtype=dtype)
mm = MockModel(MockPosterior(samples=samples))
# X is `q x d` = 1 x 1. X is a dummy and unused b/c of mocking
X = torch.zeros(1, 1, device=self.device, dtype=dtype)
# basic test
sampler = IIDNormalSampler(num_samples=2)
acqf = qProbabilityOfImprovement(model=mm, best_f=0, sampler=sampler)
res = acqf(X)
self.assertEqual(res.item(), 0.5)
# basic test, no resample
sampler = IIDNormalSampler(num_samples=2, seed=12345)
acqf = qProbabilityOfImprovement(model=mm, best_f=0, sampler=sampler)
res = acqf(X)
self.assertEqual(res.item(), 0.5)
self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 1, 1]))
bs = acqf.sampler.base_samples.clone()
def test_expected_improvement_batch(self):
for dtype in (torch.float, torch.double):
mean = torch.tensor([-0.5, 0.0, 0.5], device=self.device, dtype=dtype).view(
3, 1, 1
)
variance = torch.ones(3, 1, 1, device=self.device, dtype=dtype)
mm = MockModel(MockPosterior(mean=mean, variance=variance))
module = ExpectedImprovement(model=mm, best_f=0.0)
X = torch.empty(3, 1, 1, device=self.device, dtype=dtype) # dummy
ei = module(X)
ei_expected = torch.tensor(
[0.19780, 0.39894, 0.69780], device=self.device, dtype=dtype
)
self.assertTrue(torch.allclose(ei, ei_expected, atol=1e-4))
# check for proper error if multi-output model
mean2 = torch.rand(3, 1, 2, device=self.device, dtype=dtype)
variance2 = torch.rand(3, 1, 2, device=self.device, dtype=dtype)
mm2 = MockModel(MockPosterior(mean=mean2, variance=variance2))
with self.assertRaises(UnsupportedError):
ExpectedImprovement(model=mm2, best_f=0.0)
# test objective (single-output)
mean = torch.tensor([[[0.5]], [[0.25]]], device=self.device, dtype=dtype)
def test_MockPosterior(self):
# test basic logic
mp = MockPosterior()
self.assertEqual(mp.device.type, "cpu")
self.assertEqual(mp.dtype, torch.float32)
self.assertEqual(mp.event_shape, torch.Size())
self.assertEqual(
MockPosterior(variance=torch.rand(2)).event_shape, torch.Size([2])
)
# test passing in tensors
mean = torch.rand(2)
variance = torch.eye(2)
samples = torch.rand(1, 2)
mp = MockPosterior(mean=mean, variance=variance, samples=samples)
self.assertEqual(mp.device.type, "cpu")
self.assertEqual(mp.dtype, torch.float32)
self.assertTrue(torch.equal(mp.mean, mean))
self.assertTrue(torch.equal(mp.variance, variance))
self.assertTrue(torch.all(mp.sample() == samples.unsqueeze(0)))
self.assertTrue(
torch.all(mp.sample(torch.Size([2])) == samples.repeat(2, 1, 1))
)
with self.assertRaises(RuntimeError):
mp.sample(sample_shape=torch.Size([2]), base_samples=torch.rand(3))
def test_posterior_mean_batch(self):
for dtype in (torch.float, torch.double):
mean = torch.tensor([-0.5, 0.0, 0.5], device=self.device, dtype=dtype).view(
3, 1, 1
)
mm = MockModel(MockPosterior(mean=mean))
module = PosteriorMean(model=mm)
X = torch.empty(3, 1, 1, device=self.device, dtype=dtype)
pm = module(X)
self.assertTrue(torch.equal(pm, mean.view(-1)))
# check for proper error if multi-output model
mean2 = torch.rand(3, 1, 2, device=self.device, dtype=dtype)
mm2 = MockModel(MockPosterior(mean=mean2))
with self.assertRaises(UnsupportedError):
PosteriorMean(model=mm2)
num_fantasies=n_f,
X_pending=X_pending,
current_value=current_value,
cost_aware_utility=cau,
)
val = qMFKG(X)
patch_f.assert_called_once()
cargs, ckwargs = patch_f.call_args
self.assertEqual(ckwargs["X"].shape, torch.Size([1, 3, 1]))
val_exp = mock_util(X, mean.squeeze(-1) - current_value).mean(dim=0)
self.assertTrue(torch.allclose(val, val_exp, atol=1e-4))
self.assertTrue(torch.equal(qMFKG.extract_candidates(X), X[..., :-n_f, :]))
# test objective (inner MC sampling)
objective = GenericMCObjective(objective=lambda Y: Y.norm(dim=-1))
samples = torch.randn(3, 1, 1, device=self.device, dtype=dtype)
mfm = MockModel(MockPosterior(samples=samples))
X = torch.rand(n_f + 1, 1, device=self.device, dtype=dtype)
with mock.patch.object(MockModel, "fantasize", return_value=mfm) as patch_f:
with mock.patch(NO, new_callable=mock.PropertyMock) as mock_num_outputs:
mock_num_outputs.return_value = 1
mm = MockModel(None)
qMFKG = qMultiFidelityKnowledgeGradient(
model=mm,
num_fantasies=n_f,
objective=objective,
current_value=current_value,
cost_aware_utility=cau,
)
val = qMFKG(X)
patch_f.assert_called_once()
cargs, ckwargs = patch_f.call_args
self.assertEqual(ckwargs["X"].shape, torch.Size([1, 1, 1]))
module = ProbabilityOfImprovement(model=mm, best_f=1.96)
X = torch.zeros(1, 1, device=self.device, dtype=dtype)
pi = module(X)
pi_expected = torch.tensor(0.0250, device=self.device, dtype=dtype)
self.assertTrue(torch.allclose(pi, pi_expected, atol=1e-4))
module = ProbabilityOfImprovement(model=mm, best_f=1.96, maximize=False)
X = torch.zeros(1, 1, device=self.device, dtype=dtype)
pi = module(X)
pi_expected = torch.tensor(0.9750, device=self.device, dtype=dtype)
self.assertTrue(torch.allclose(pi, pi_expected, atol=1e-4))
# check for proper error if multi-output model
mean2 = torch.rand(1, 2, device=self.device, dtype=dtype)
variance2 = torch.ones_like(mean2)
mm2 = MockModel(MockPosterior(mean=mean2, variance=variance2))
with self.assertRaises(UnsupportedError):
ProbabilityOfImprovement(model=mm2, best_f=0.0)
num_fantasies=n_f,
current_value=current_value,
cost_aware_utility=cau,
)
val = qMFKG(X)
patch_f.assert_called_once()
cargs, ckwargs = patch_f.call_args
self.assertEqual(ckwargs["X"].shape, torch.Size([b, 1, 1]))
val_exp = mock_util(X, mean.squeeze(-1) - current_value).mean(dim=0)
self.assertTrue(torch.allclose(val, val_exp, atol=1e-4))
self.assertTrue(torch.equal(qMFKG.extract_candidates(X), X[..., :-n_f, :]))
# pending points and current value
mean = torch.rand(n_f, 1, 1, device=self.device, dtype=dtype)
variance = torch.rand(n_f, 1, 1, device=self.device, dtype=dtype)
X_pending = torch.rand(2, 1, device=self.device, dtype=dtype)
mfm = MockModel(MockPosterior(mean=mean, variance=variance))
current_value = torch.rand(1, device=self.device, dtype=dtype)
X = torch.rand(n_f + 1, 1, device=self.device, dtype=dtype)
with mock.patch.object(MockModel, "fantasize", return_value=mfm) as patch_f:
with mock.patch(NO, new_callable=mock.PropertyMock) as mock_num_outputs:
mock_num_outputs.return_value = 1
mm = MockModel(None)
qMFKG = qMultiFidelityKnowledgeGradient(
model=mm,
num_fantasies=n_f,
X_pending=X_pending,
current_value=current_value,
cost_aware_utility=cau,
)
val = qMFKG(X)
patch_f.assert_called_once()
cargs, ckwargs = patch_f.call_args