def test_degree3(self): # just make sure it doesn't break here. AddK = NewtonGirardAdditiveKernel(RBFKernel(ard_num_dims=3), 3, 3) self.assertEqual(AddK.base_kernel.lengthscale.numel(), 3) self.assertEqual(AddK.outputscale.numel(), 3) testvals = torch.tensor([[1, 2, 3], [7, 5, 2]], dtype=torch.float) add_k_val = AddK(testvals, testvals).evaluate() manual_k1 = ScaleKernel( AdditiveKernel(RBFKernel(active_dims=0), RBFKernel(active_dims=1), RBFKernel(active_dims=2))) manual_k1.initialize(outputscale=1 / 3) manual_k2 = ScaleKernel( AdditiveKernel(RBFKernel(active_dims=[0, 1]), RBFKernel(active_dims=[1, 2]), RBFKernel(active_dims=[0, 2]))) manual_k2.initialize(outputscale=1 / 3) manual_k3 = ScaleKernel(AdditiveKernel(RBFKernel())) manual_k3.initialize(outputscale=1 / 3) manual_k = AdditiveKernel(manual_k1, manual_k2, manual_k3) manual_add_k_val = manual_k(testvals, testvals).evaluate() # np.testing.assert_allclose(add_k_val.detach().numpy(), manual_add_k_val.detach().numpy(), atol=1e-5) self.assertTrue(torch.allclose(add_k_val, manual_add_k_val, atol=1e-5))
def test_optimizing(self): # This tests should pass so long as nothing breaks. torch.random.manual_seed(1) data = torch.randn(40, 4) target = torch.sin(data).sum(dim=-1) d = 4 AddK = NewtonGirardAdditiveKernel(RBFKernel(ard_num_dims=d), d, max_degree=3) class TestGPModel(ExactGP): def __init__(self, train_x, train_y, likelihood, kernel): super().__init__(train_x, train_y, likelihood) self.mean_module = ConstantMean() self.covar_module = kernel def forward(self, x): mean_x = self.mean_module(x) covar_x = self.covar_module(x) return MultivariateNormal(mean_x, covar_x) model = TestGPModel(data, target, GaussianLikelihood(), ScaleKernel(AddK)) optim = torch.optim.Adam(model.parameters(), lr=0.1) mll = ExactMarginalLogLikelihood(model.likelihood, model) model.train() for i in range(2): optim.zero_grad() out = model(data) loss = -mll(out, target) loss.backward() optim.step()
def test_degree1(self): AddK = NewtonGirardAdditiveKernel(RBFKernel(ard_num_dims=3), 3, 1) self.assertEqual(AddK.base_kernel.lengthscale.numel(), 3) self.assertEqual(AddK.outputscale.numel(), 1) testvals = torch.tensor([[1, 2, 3], [7, 5, 2]], dtype=torch.float) add_k_val = AddK(testvals, testvals).evaluate() manual_k = ScaleKernel(AdditiveKernel(RBFKernel(active_dims=0), RBFKernel(active_dims=1), RBFKernel(active_dims=2))) manual_k.initialize(outputscale=1.) manual_add_k_val = manual_k(testvals, testvals).evaluate() # np.testing.assert_allclose(add_k_val.detach().numpy(), manual_add_k_val.detach().numpy(), atol=1e-5) self.assertTrue(torch.allclose(add_k_val, manual_add_k_val, atol=1e-5))
def test_ard(self): base_k = RBFKernel(ard_num_dims=3) base_k.initialize(lengthscale=[1., 2., 3.]) AddK = NewtonGirardAdditiveKernel(base_k, 3, max_degree=1) testvals = torch.tensor([[1, 2, 3], [7, 5, 2]], dtype=torch.float) add_k_val = AddK(testvals, testvals).evaluate() ks = [] for i in range(3): k = RBFKernel(active_dims=i) k.initialize(lengthscale=i + 1) ks.append(k) manual_k = ScaleKernel(AdditiveKernel(*ks)) manual_k.initialize(outputscale=1.) manual_add_k_val = manual_k(testvals, testvals).evaluate() # np.testing.assert_allclose(add_k_val.detach().numpy(), manual_add_k_val.detach().numpy(), atol=1e-5) self.assertTrue(torch.allclose(add_k_val, manual_add_k_val, atol=1e-5))
def create_kernel_ard(self, num_dims, **kwargs): return NewtonGirardAdditiveKernel(RBFKernel(ard_num_dims=num_dims), num_dims, 2, **kwargs)
def create_kernel_no_ard(self, **kwargs): return NewtonGirardAdditiveKernel(RBFKernel(), 4, 2, **kwargs)
def create_newton_girard_additive_kernel(d, max_degree): """Use the Newton-Girard formulae to model higher-order interactions.""" return NewtonGirardAdditiveKernel(RBFKernel(ard_num_dims=d), d, max_degree)