예제 #1
0
def create_per(sigma2, lengthscale, period_length):
    per = PeriodicKernel()
    per.lengthscale = lengthscale
    per.period_length = period_length
    kernel = ScaleKernel(per)
    kernel.outputscale = sigma2
    return kernel
예제 #2
0
    def test_computes_periodic_function(self):
        a = torch.tensor([4, 2, 8], dtype=torch.float).view(3, 1)
        b = torch.tensor([0, 2], dtype=torch.float).view(2, 1)
        lengthscale = 2
        period = 3
        kernel = PeriodicKernel().initialize(log_lengthscale=math.log(lengthscale), log_period_length=math.log(period))
        kernel.eval()

        actual = torch.zeros(3, 2)
        for i in range(3):
            for j in range(2):
                val = 2 * torch.pow(torch.sin(math.pi * (a[i] - b[j]) / 3), 2) / lengthscale
                actual[i, j] = torch.exp(-val).item()

        res = kernel(a, b).evaluate()
        self.assertLess(torch.norm(res - actual), 1e-5)
예제 #3
0
    def test_batch(self):
        a = torch.tensor([[4, 2, 8], [1, 2, 3]],
                         dtype=torch.float).view(2, 3, 1)
        b = torch.tensor([[0, 2], [-1, 2]], dtype=torch.float).view(2, 2, 1)
        period = torch.tensor(1, dtype=torch.float).view(1, 1, 1)
        lengthscale = torch.tensor(2, dtype=torch.float).view(1, 1, 1)
        kernel = PeriodicKernel().initialize(lengthscale=lengthscale,
                                             period_length=period)
        kernel.eval()

        actual = torch.zeros(2, 3, 2)
        for k in range(2):
            actual[k] = kernel(a[k], b[k]).evaluate()

        res = kernel(a, b).evaluate()
        self.assertLess(torch.norm(res - actual), 1e-5)
예제 #4
0
    def test_computes_periodic_function(self):
        a = torch.Tensor([4, 2, 8]).view(3, 1)
        b = torch.Tensor([0, 2]).view(2, 1)
        lengthscale = 2
        period = 1
        kernel = PeriodicKernel().initialize(log_lengthscale=math.log(lengthscale), log_period_length=math.log(period))
        kernel.eval()

        actual = torch.zeros(3, 2)
        for i in range(3):
            for j in range(2):
                val = 2 * torch.pow(torch.sin(math.pi * (a[i] - b[j])), 2) / lengthscale
                actual[i, j] = torch.exp(-val)[0]

        res = kernel(Variable(a), Variable(b)).evaluate().data
        self.assertLess(torch.norm(res - actual), 1e-5)
예제 #5
0
 def test_is_pd(self):
     # ensures 1d input is positive definite with additional jitter
     x = torch.randn(100).reshape(-1, 1)
     kernel = PeriodicKernel()
     with torch.no_grad():
         K = kernel(x, x).evaluate() + 1e-4 * torch.eye(len(x))
         eig = torch.symeig(K)[0]
         self.assertTrue((eig > 0.0).all().item())
예제 #6
0
    def test_batch_separate(self):
        a = torch.tensor([[4, 2, 8], [1, 2, 3]], dtype=torch.float).view(2, 3, 1)
        b = torch.tensor([[0, 2], [-1, 2]], dtype=torch.float).view(2, 2, 1)
        period = torch.tensor([1, 2], dtype=torch.float).view(2, 1, 1)
        lengthscale = torch.tensor([2, 1], dtype=torch.float).view(2, 1, 1)
        kernel = PeriodicKernel(batch_shape=torch.Size([2])).initialize(lengthscale=lengthscale, period_length=period)
        kernel.eval()

        actual = torch.zeros(2, 3, 2)
        for k in range(2):
            for i in range(3):
                for j in range(2):
                    val = 2 * torch.pow(torch.sin(math.pi * (a[k, i] - b[k, j]) / period[k]), 2) / lengthscale[k]
                    actual[k, i, j] = torch.exp(-val).item()

        res = kernel(a, b).evaluate()
        self.assertLess(torch.norm(res - actual), 1e-5)
예제 #7
0
 def test_multidimensional_inputs(self):
     # test taken from issue #835
     # ensures multidimensional input results in a positive definite kernel matrix, with additional jitter
     x = torch.randn(1000, 2)
     kernel = PeriodicKernel()
     with torch.no_grad():
         K = kernel(x, x).evaluate() + 1e-4 * torch.eye(len(x))
         eig = torch.symeig(K)[0]
         self.assertTrue((eig > 0.0).all().item())
예제 #8
0
    def test_batch_separate(self):
        a = torch.tensor([[4, 2, 8], [1, 2, 3]],
                         dtype=torch.float).view(2, 3, 1)
        b = torch.tensor([[0, 2], [-1, 2]], dtype=torch.float).view(2, 2, 1)
        period = torch.tensor([1, 2], dtype=torch.float).view(2, 1, 1)
        lengthscale = torch.tensor([2, 1], dtype=torch.float).view(2, 1, 1)
        kernel = PeriodicKernel(batch_shape=torch.Size([2])).initialize(
            lengthscale=lengthscale, period_length=period)
        kernel.eval()

        actual = torch.zeros(2, 3, 2)
        for k in range(2):
            diff = a[k].unsqueeze(1) - b[k].unsqueeze(0)
            diff = diff * math.pi / period[k].unsqueeze(-1)
            actual[k] = diff.sin().pow(2).sum(dim=-1).div(
                lengthscale[k]).mul(-2.0).exp_()

        res = kernel(a, b).evaluate()
        self.assertLess(torch.norm(res - actual), 1e-5)
    def __init__(self,
                 mean_name='constant',
                 kernel_name='RBF',
                 grid_bounds=[(-1, 1), (-1, 1)],
                 grid_size=100,
                 num_samples=1000):

        self.mean = mean_name
        self.kernel = kernel_name
        self.num_samples = num_samples
        self.grid_bounds = grid_bounds
        self.grid_size = grid_size
        self.x_dim = 2  # x and y dim are fixed for this dataset.
        self.y_dim = 1

        self.data = []

        # create grid
        grid = torch.zeros(grid_size, len(grid_bounds))
        for i in range(len(grid_bounds)):
            grid_diff = float(grid_bounds[i][1] -
                              grid_bounds[i][0]) / (grid_size - 2)
            grid[:,
                 i] = torch.linspace(grid_bounds[i][0] - grid_diff,
                                     grid_bounds[i][1] + grid_diff, grid_size)

        x = gpytorch.utils.grid.create_data_from_grid(grid)

        # initialize likelihood and model
        likelihood = gpytorch.likelihoods.GaussianLikelihood()

        mean_dict = {'constant': ConstantMean()}
        kernel_dict = {
            'RBF': RBFKernel(),
            'cosine': CosineKernel(),
            'linear': LinearKernel(),
            'periodic': PeriodicKernel(),
            'LCM': LCMKernel(base_kernels=[CosineKernel()], num_tasks=1),
            'polynomial': PolynomialKernel(power=3),
            'matern': MaternKernel()
        }

        # evaluate GP on prior distribution
        with gpytorch.settings.prior_mode(True):
            model = ExactGPModel(x,
                                 None,
                                 likelihood,
                                 mean_module=mean_dict[self.mean],
                                 kernel_module=gpytorch.kernels.GridKernel(
                                     kernel_dict[self.kernel], grid=grid))
            gp = model(x)
            for i in range(num_samples):
                y = gp.sample()
                self.data.append(
                    (x, y.unsqueeze(1)))  #+torch.randn(y.size())*0.2))
    def __init__(self,
                 mean_list,
                 kernel_list,
                 num_points=100,
                 num_samples=1000,
                 amplitude_range=(-5., 5.)):
        self.mean_list = mean_list
        self.kernel_list = kernel_list
        self.num_config = len(mean_list) * len(kernel_list)
        self.num_samples = num_samples
        self.num_points = num_points
        self.x_dim = 1  # x and y dim are fixed for this dataset.
        self.y_dim = 1
        self.amplitude_range = amplitude_range
        self.data = []

        # initialize likelihood and model
        x = torch.linspace(self.amplitude_range[0], self.amplitude_range[1],
                           num_points).unsqueeze(1)

        likelihood = gpytorch.likelihoods.GaussianLikelihood()
        mean_dict = {'constant': ConstantMean(), 'linear': LinearMean(1)}
        kernel_dict = {
            'RBF': RBFKernel(),
            'cosine': CosineKernel(),
            'linear': LinearKernel(),
            'periodic': PeriodicKernel(period_length=0.5),
            'LCM': LCMKernel(base_kernels=[CosineKernel()], num_tasks=1),
            'polynomial': PolynomialKernel(power=2),
            'matern': MaternKernel()
        }

        # create a different GP from each possible configuration
        for mean in self.mean_list:
            for kernel in self.kernel_list:
                # evaluate GP on prior distribution
                with gpytorch.settings.prior_mode(True):
                    model = ExactGPModel(x,
                                         None,
                                         likelihood,
                                         mean_module=mean_dict[mean],
                                         kernel_module=kernel_dict[kernel])

                    gp = model(x)
                    # sample from current configuration
                    for i in range(num_samples // self.num_config + 1):
                        y = gp.sample()
                        self.data.append(
                            (x, y.unsqueeze(1)))  #+torch.randn(y.shape)*0))
예제 #11
0
    def test_random_fourier_features(self):
        # test kernel that is not Scale, RBF, or Matern
        with self.assertRaises(NotImplementedError):
            RandomFourierFeatures(
                kernel=PeriodicKernel(),
                input_dim=2,
                num_rff_features=3,
            )

        # test batched kernel
        with self.assertRaises(NotImplementedError):
            RandomFourierFeatures(
                kernel=RBFKernel(batch_shape=torch.Size([2])),
                input_dim=2,
                num_rff_features=3,
            )
        tkwargs = {"device": self.device}
        for dtype in (torch.float, torch.double):
            tkwargs["dtype"] = dtype
            # test init
            # test ScaleKernel
            base_kernel = RBFKernel(ard_num_dims=2)
            kernel = ScaleKernel(base_kernel).to(**tkwargs)
            rff = RandomFourierFeatures(
                kernel=kernel,
                input_dim=2,
                num_rff_features=3,
            )
            self.assertTrue(torch.equal(rff.outputscale, kernel.outputscale))
            # check that rff makes a copy
            self.assertFalse(rff.outputscale is kernel.outputscale)
            self.assertTrue(
                torch.equal(rff.lengthscale, base_kernel.lengthscale))
            # check that rff makes a copy
            self.assertFalse(rff.lengthscale is kernel.lengthscale)

            for sample_shape in [torch.Size(), torch.Size([5])]:
                # test not ScaleKernel
                rff = RandomFourierFeatures(
                    kernel=base_kernel,
                    input_dim=2,
                    num_rff_features=3,
                    sample_shape=sample_shape,
                )
                self.assertTrue(
                    torch.equal(rff.outputscale, torch.tensor(1, **tkwargs)))
                self.assertTrue(
                    torch.equal(rff.lengthscale, base_kernel.lengthscale))
                # check that rff makes a copy
                self.assertFalse(rff.lengthscale is kernel.lengthscale)
                self.assertEqual(rff.weights.shape,
                                 torch.Size([*sample_shape, 2, 3]))
                self.assertEqual(rff.bias.shape, torch.Size([*sample_shape,
                                                             3]))
                self.assertTrue(
                    ((rff.bias <= 2 * pi) & (rff.bias >= 0.0)).all())

            # test forward
            for sample_shape in [torch.Size(), torch.Size([7])]:
                rff = RandomFourierFeatures(
                    kernel=kernel,
                    input_dim=2,
                    num_rff_features=3,
                    sample_shape=sample_shape,
                )
                for input_batch_shape in [torch.Size([]), torch.Size([5])]:
                    X = torch.rand(*input_batch_shape, *sample_shape, 1, 2,
                                   **tkwargs)
                    Y = rff(X)
                    self.assertTrue(
                        Y.shape,
                        torch.Size([*input_batch_shape, *sample_shape, 1, 1]))
                    _constant = torch.sqrt(2 * rff.outputscale /
                                           rff.weights.shape[-1])
                    _arg_to_cos = X / base_kernel.lengthscale @ rff.weights
                    _bias_expanded = rff.bias.unsqueeze(-2)
                    expected_Y = _constant * (torch.cos(_arg_to_cos +
                                                        _bias_expanded))
                    self.assertTrue(torch.allclose(Y, expected_Y))

            # test get_weights
            for sample_shape in [torch.Size(), torch.Size([5])]:
                with mock.patch("torch.randn",
                                wraps=torch.randn) as mock_randn:
                    rff._get_weights(
                        base_kernel=base_kernel,
                        input_dim=2,
                        num_rff_features=3,
                        sample_shape=sample_shape,
                    )
                    mock_randn.assert_called_once_with(
                        *sample_shape,
                        2,
                        3,
                        dtype=base_kernel.lengthscale.dtype,
                        device=base_kernel.lengthscale.device,
                    )
                # test get_weights with Matern kernel
                with mock.patch(
                        "torch.randn",
                        wraps=torch.randn) as mock_randn, mock.patch(
                            "torch.distributions.Gamma",
                            wraps=torch.distributions.Gamma) as mock_gamma:
                    base_kernel = MaternKernel(ard_num_dims=2).to(**tkwargs)
                    rff._get_weights(
                        base_kernel=base_kernel,
                        input_dim=2,
                        num_rff_features=3,
                        sample_shape=sample_shape,
                    )
                    mock_randn.assert_called_once_with(
                        *sample_shape,
                        2,
                        3,
                        dtype=base_kernel.lengthscale.dtype,
                        device=base_kernel.lengthscale.device,
                    )
                    mock_gamma.assert_called_once_with(
                        base_kernel.nu,
                        base_kernel.nu,
                    )
예제 #12
0
 def create_kernel_with_prior(self, period_length_prior):
     return PeriodicKernel(period_length_prior=period_length_prior)
예제 #13
0
 def create_kernel_ard(self, num_dims, **kwargs):
     return PeriodicKernel(ard_num_dims=num_dims, **kwargs)
예제 #14
0
 def create_kernel_no_ard(self, **kwargs):
     return PeriodicKernel(**kwargs)