def test_q_probability_of_improvement(self, cuda=False): device = torch.device("cuda") if cuda else torch.device("cpu") 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=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=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() res = acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # basic test, qmc, no resample sampler = SobolQMCNormalSampler(num_samples=2) 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() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # basic test, qmc, resample sampler = SobolQMCNormalSampler(num_samples=2, resample=True) 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() acqf(X) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs))
def test_get_base_sample_shape_no_collapse(self): sampler = SobolQMCNormalSampler(num_samples=4, collapse_batch_dims=False) self.assertFalse(sampler.resample) self.assertEqual(sampler.sample_shape, torch.Size([4])) self.assertFalse(sampler.collapse_batch_dims) # check sample shape non-batched posterior = _get_posterior() bss = sampler._get_base_sample_shape(posterior=posterior) self.assertEqual(bss, torch.Size([4, 2, 1])) # check sample shape batched posterior = _get_posterior_batched() bss = sampler._get_base_sample_shape(posterior=posterior) self.assertEqual(bss, torch.Size([4, 3, 2, 1]))
def test_get_base_sample_shape(self): sampler = SobolQMCNormalSampler(num_samples=4) self.assertFalse(sampler.resample) self.assertEqual(sampler.sample_shape, torch.Size([4])) self.assertTrue(sampler.collapse_batch_dims) # check sample shape non-batched posterior = _get_posterior() bss = sampler._get_base_sample_shape(posterior=posterior) self.assertEqual(bss, torch.Size([4, 2, 1])) # check sample shape batched posterior = _get_posterior_batched() bss = sampler._get_base_sample_shape(posterior=posterior) self.assertEqual(bss, torch.Size([4, 1, 2, 1]))
def test_forward_no_collapse(self, cuda=False): for dtype in (torch.float, torch.double): # no resample sampler = SobolQMCNormalSampler(num_samples=4, seed=1234, collapse_batch_dims=False) self.assertFalse(sampler.resample) self.assertEqual(sampler.seed, 1234) self.assertFalse(sampler.collapse_batch_dims) # check samples non-batched posterior = _get_posterior(cuda=cuda, dtype=dtype) samples = sampler(posterior) self.assertEqual(samples.shape, torch.Size([4, 2, 1])) self.assertEqual(sampler.seed, 1235) # ensure samples are the same samples2 = sampler(posterior) self.assertTrue(torch.allclose(samples, samples2)) self.assertEqual(sampler.seed, 1235) # ensure this works with a differently shaped posterior posterior_batched = _get_posterior_batched(cuda=cuda, dtype=dtype) samples_batched = sampler(posterior_batched) self.assertEqual(samples_batched.shape, torch.Size([4, 3, 2, 1])) self.assertEqual(sampler.seed, 1236) # resample sampler = SobolQMCNormalSampler(num_samples=4, resample=True, collapse_batch_dims=False) self.assertTrue(sampler.resample) self.assertFalse(sampler.collapse_batch_dims) initial_seed = sampler.seed # check samples non-batched posterior = _get_posterior(cuda=cuda, dtype=dtype) samples = sampler(posterior=posterior) self.assertEqual(samples.shape, torch.Size([4, 2, 1])) self.assertEqual(sampler.seed, initial_seed + 1) # ensure samples are not the same samples2 = sampler(posterior) self.assertFalse(torch.allclose(samples, samples2)) self.assertEqual(sampler.seed, initial_seed + 2) # ensure this works with a differently shaped posterior posterior_batched = _get_posterior_batched(cuda=cuda, dtype=dtype) samples_batched = sampler(posterior_batched) self.assertEqual(samples_batched.shape, torch.Size([4, 3, 2, 1])) self.assertEqual(sampler.seed, initial_seed + 3)
def test_unsupported_dimension(self): sampler = SobolQMCNormalSampler(num_samples=2) mean = torch.zeros(1112) cov = DiagLazyTensor(torch.ones(1112)) mvn = MultivariateNormal(mean, cov) posterior = GPyTorchPosterior(mvn) with self.assertRaises(UnsupportedError) as e: sampler(posterior) self.assertIn("Requested: 1112", str(e.exception))
def test_q_expected_improvement_batch(self, cuda=False): device = torch.device("cuda") if cuda else torch.device("cpu") for dtype in (torch.float, torch.double): # the event shape is `b x q x t` = 2 x 2 x 1 samples = torch.zeros(2, 2, 1, device=device, dtype=dtype) samples[0, 0, 0] = 1.0 mm = MockModel(MockPosterior(samples=samples)) # X is a dummy and unused b/c of mocking X = torch.zeros(1, 1, 1, device=device, dtype=dtype) # test batch mode sampler = IIDNormalSampler(num_samples=2) acqf = qExpectedImprovement(model=mm, best_f=0, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # test shifting best_f value acqf = qExpectedImprovement(model=mm, best_f=-1, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 2.0) self.assertEqual(res[1].item(), 1.0) # test batch mode, no resample sampler = IIDNormalSampler(num_samples=2, seed=12345) acqf = qExpectedImprovement(model=mm, best_f=0, sampler=sampler) res = acqf(X) # 1-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) res = acqf(X.expand(2, 1, 1)) # 2-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # the base samples should have the batch dim collapsed self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X.expand(2, 1, 1)) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # test batch mode, qmc, no resample sampler = SobolQMCNormalSampler(num_samples=2) acqf = qExpectedImprovement(model=mm, best_f=0, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # test batch mode, qmc, resample sampler = SobolQMCNormalSampler(num_samples=2, resample=True) acqf = qExpectedImprovement(model=mm, best_f=0, sampler=sampler) res = acqf(X) # 1-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs)) res = acqf(X.expand(2, 1, 1)) # 2-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # the base samples should have the batch dim collapsed self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X.expand(2, 1, 1)) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs))
def test_q_upper_confidence_bound_batch(self, cuda=False): # TODO: T41739913 Implement tests for all MCAcquisitionFunctions device = torch.device("cuda") if cuda else torch.device("cpu") for dtype in (torch.float, torch.double): samples = torch.zeros(2, 2, 1, device=device, dtype=dtype) samples[0, 0, 0] = 1.0 mm = MockModel(MockPosterior(samples=samples)) # X is a dummy and unused b/c of mocking X = torch.zeros(1, 1, 1, device=device, dtype=dtype) # test batch mode sampler = IIDNormalSampler(num_samples=2) acqf = qUpperConfidenceBound(model=mm, beta=0.5, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # test batch mode, no resample sampler = IIDNormalSampler(num_samples=2, seed=12345) acqf = qUpperConfidenceBound(model=mm, beta=0.5, sampler=sampler) res = acqf(X) # 1-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) res = acqf(X.expand(2, 1, 1)) # 2-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # the base samples should have the batch dim collapsed self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X.expand(2, 1, 1)) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # test batch mode, qmc, no resample sampler = SobolQMCNormalSampler(num_samples=2) acqf = qUpperConfidenceBound(model=mm, beta=0.5, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # test batch mode, qmc, resample sampler = SobolQMCNormalSampler(num_samples=2, resample=True) acqf = qUpperConfidenceBound(model=mm, beta=0.5, sampler=sampler) res = acqf(X) # 1-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs)) res = acqf(X.expand(2, 1, 1)) # 2-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # the base samples should have the batch dim collapsed self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X.expand(2, 1, 1)) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs))
def test_q_noisy_expected_improvement_batch(self, cuda=False): device = torch.device("cuda") if cuda else torch.device("cpu") for dtype in (torch.float, torch.double): # the event shape is `b x q x t` = 2 x 3 x 1 samples_noisy = torch.zeros(2, 3, 1, device=device, dtype=dtype) samples_noisy[0, 0, 0] = 1.0 mm_noisy = MockModel(MockPosterior(samples=samples_noisy)) # X is `q x d` = 1 x 1 X = torch.zeros(1, 1, 1, device=device, dtype=dtype) X_baseline = torch.zeros(1, 1, device=device, dtype=dtype) # test batch mode sampler = IIDNormalSampler(num_samples=2) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # test batch mode, no resample sampler = IIDNormalSampler(num_samples=2, seed=12345) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) # 1-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 3, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) res = acqf(X.expand(2, 1, 1)) # 2-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # the base samples should have the batch dim collapsed self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 3, 1])) bs = acqf.sampler.base_samples.clone() acqf(X.expand(2, 1, 1)) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # test batch mode, qmc, no resample sampler = SobolQMCNormalSampler(num_samples=2) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 3, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # test X_pending w/ batch mode, qmc, resample sampler = SobolQMCNormalSampler(num_samples=2, resample=True, seed=12345) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) # 1-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 3, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs)) res = acqf(X.expand(2, 1, 1)) # 2-dim batch self.assertEqual(res[0].item(), 1.0) self.assertEqual(res[1].item(), 0.0) # the base samples should have the batch dim collapsed self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 3, 1])) bs = acqf.sampler.base_samples.clone() acqf(X.expand(2, 1, 1)) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs))
def test_q_noisy_expected_improvement(self, cuda=False): device = torch.device("cuda") if cuda else torch.device("cpu") for dtype in (torch.float, torch.double): # the event shape is `b x q x t` = 1 x 2 x 1 samples_noisy = torch.tensor([1.0, 0.0], device=device, dtype=dtype) samples_noisy = samples_noisy.view(1, 2, 1) # X_baseline is `q' x d` = 1 x 1 X_baseline = torch.zeros(1, 1, device=device, dtype=dtype) mm_noisy = MockModel(MockPosterior(samples=samples_noisy)) # X is `q x d` = 1 x 1 X = torch.zeros(1, 1, device=device, dtype=dtype) # basic test sampler = IIDNormalSampler(num_samples=2) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) self.assertEqual(res.item(), 1.0) # basic test, no resample sampler = IIDNormalSampler(num_samples=2, seed=12345) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) self.assertEqual(res.item(), 1.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # basic test, qmc, no resample sampler = SobolQMCNormalSampler(num_samples=2) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) self.assertEqual(res.item(), 1.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertTrue(torch.equal(acqf.sampler.base_samples, bs)) # basic test, qmc, resample sampler = SobolQMCNormalSampler(num_samples=2, resample=True, seed=12345) acqf = qNoisyExpectedImprovement(model=mm_noisy, X_baseline=X_baseline, sampler=sampler) res = acqf(X) self.assertEqual(res.item(), 1.0) self.assertEqual(acqf.sampler.base_samples.shape, torch.Size([2, 1, 2, 1])) bs = acqf.sampler.base_samples.clone() acqf(X) self.assertFalse(torch.equal(acqf.sampler.base_samples, bs))