def test_gen_bernoulli(self): W = gen_rp(100, 1000, dist='bernoulli') fake_dists = pairwise_distance(fake_data, fake_data) proj = fake_data.matmul(W) dists = pairwise_distance(proj, proj) self.assertLess( (fake_dists - dists).abs().mean() / fake_dists.abs().mean(), 0.1) # no strict guarantee... W = gen_rp(real_d, 1000, dist='bernoulli') real_dists = pairwise_distance(real_data, real_data) proj = real_data.matmul(W) dists = pairwise_distance(proj, proj) self.assertLess( (real_dists - dists).abs().mean() / fake_dists.abs().mean(), 0.1) # no strict guarantee...
def testd4J2(self): d = 4 k = 1 J = 2 P = torch.cat([gen_rp(d, k, dist='gaussian') for _ in range(J)], dim=1).t() newP, _ = space_equally(P, 0.1, 10000)
def create_additive_rp_kernel(d, J, learn_proj=False, kernel_type='RBF', space_proj=False, prescale=False, ard=True, init_lengthscale_range=(1., 1.), ski=False, ski_options=None, proj_dist='gaussian', batch_kernel=True, mem_efficient=False, k=1, keops=False): if k > 1 and (mem_efficient or batch_kernel or space_proj): raise ValueError("Can't have k > 1 with memory efficient GAM kernel or a batch kernel or spaced projections.") projs = [rp.gen_rp(d, k, dist=proj_dist) for _ in range(J)] # bs = [torch.zeros(1) for _ in range(J)] if space_proj: newW, _ = rp.space_equally(torch.cat(projs,dim=1).t(), lr=0.1, niter=5000) # newW = rp.compute_spherical_t_design(num_dims-1, N=J) newW.requires_grad = False projs = [newW[i:i+k, :].t() for i in range(0, J*k, k)] proj_module = torch.nn.Linear(d, J*k, bias=False) proj_module.weight.data = torch.cat(projs, dim=1).t() # proj_module.bias.data = torch.cat(bs, dim=0) def make_kernel(active_dim=None): kernel = _map_to_kernel(True, kernel_type, keops, active_dims=active_dim) if hasattr(kernel, 'period_length'): kernel.initialize(period_length=torch.tensor([1.])) else: kernel.initialize(lengthscale=torch.tensor([1.])) kernel = ScaleKernel(kernel) kernel.initialize(outputscale=torch.tensor([1/J])) if ski: kernel = gpytorch.kernels.GridInterpolationKernel(kernel, **ski_options) return kernel if mem_efficient: if ski: raise ValueError("Not implemented yet") if batch_kernel: raise ValueError("Impossible to have batch kernel and memory efficient GAM") if kernel_type != 'RBF': raise ValueError("Memory efficient GAM with alternative sub-kernels not implemented yet.") add_kernel = MemoryEfficientGamKernel() elif batch_kernel: kernel = make_kernel(None) add_kernel = gpytorch.kernels.AdditiveStructureKernel(kernel, J) else: kernels = [make_kernel(list(range(i, i+k))) for i in range(0, J*k, k)] add_kernel = gpytorch.kernels.AdditiveKernel(*kernels) if ard: if prescale: ard_num_dims = d # print('prescaling') else: ard_num_dims = J*k initial_ls = _sample_from_range(ard_num_dims, init_lengthscale_range) else: ard_num_dims = None initial_ls = _sample_from_range(1, init_lengthscale_range) proj_kernel = ScaledProjectionKernel(proj_module, add_kernel, prescale=prescale, ard_num_dims=ard_num_dims, learn_proj=learn_proj) proj_kernel.initialize(lengthscale=initial_ls) return proj_kernel
def testd2J4(self): d = 2 k = 1 J = 4 P = torch.cat([gen_rp(d, k, dist='gaussian') for _ in range(J)], dim=1).t() newP, loss = space_equally(P, 0.1, 10000) self.assertNotAlmostEqual(loss.item(), 0)
def test_gen_spherical(self): W = gen_rp(100, 1000, dist='sphere') fake_dists = pairwise_distance(fake_data, fake_data) proj = fake_data.matmul(W) dists = pairwise_distance(proj, proj) self.assertLess( (fake_dists - dists).abs().mean() / fake_dists.abs().mean(), 0.1) # no strict guarantee... self.assertAlmostEqual(W[:, 0].norm().item(), W[:, 1].norm().item()) W = gen_rp(real_d, 1000, dist='sphere') real_dists = pairwise_distance(real_data, real_data) proj = real_data.matmul(W) dists = pairwise_distance(proj, proj) self.assertLess( (real_dists - dists).abs().mean() / fake_dists.abs().mean(), 0.1) # no strict guarantee...
def test_gen_gaussian(self): W = gen_rp(100, 1000, dist='gaussian') fake_dists = pairwise_distance(fake_data, fake_data) proj = fake_data.matmul(W) dists = pairwise_distance(proj, proj) self.assertLess( (fake_dists - dists).abs().mean() / fake_dists.abs().mean(), 0.1) # no strict guarantee... # ex_norm = fake_data[0, :].norm() # proj_norm = proj[0, :].norm() # self.assertLess((ex_norm - proj_norm).abs(), 0.01) W = gen_rp(real_d, 1000, dist='gaussian') real_dists = pairwise_distance(real_data, real_data) proj = real_data.matmul(W) dists = pairwise_distance(proj, proj) self.assertLess( (real_dists - dists).abs().mean() / fake_dists.abs().mean(), 0.1) # no strict guarantee...
def create_general_rp_poly_kernel(d, degrees, learn_proj=False, weighted=False, kernel_type='RBF', init_lengthscale_range=(1.0, 1.0), init_mixin_range=(1.0, 1.0), ski=False, ski_options=None, X=None, keops=False): out_dim = sum(degrees) W = torch.cat([rp.gen_rp(d, 1) for _ in range(out_dim)], dim=1).t() b = torch.zeros(out_dim) projection_module = torch.nn.Linear(d, out_dim, bias=False) projection_module.weight = torch.nn.Parameter(W) projection_module.bias = torch.nn.Parameter(b) kernel, kwargs = _map_to_kernel(False, kernel_type, keops) kernel = GeneralizedProjectionKernel(degrees, d, kernel, projection_module, learn_proj, weighted, ski, ski_options, X=X, **kwargs) kernel.initialize(init_mixin_range, init_lengthscale_range) return kernel
def create_rp_poly_kernel(d, k, J, activation=None, learn_proj=False, weighted=False, kernel_type='RBF', space_proj=False, init_mixin_range=(1.0, 1.0), init_lengthscale_range=(1.0, 1.0), ski=False, ski_options=None, X=None, proj_dist='gaussian', keops=False ): projs = [rp.gen_rp(d, k, dist=proj_dist) for _ in range(J)] bs = [torch.zeros(k) for _ in range(J)] if space_proj: # TODO: If k>1, could implement equal spacing for each set of projs newW, _ = rp.space_equally(torch.cat(projs,dim=1).t(), lr=0.1, niter=5000) # newW = rp.compute_spherical_t_design(num_dims-1, t=4, N=J) newW.requires_grad = False projs = [newW[i:i+1, :].t() for i in range (J)] kernel, kwargs = _map_to_kernel(False, kernel_type, keops) kernel = PolynomialProjectionKernel(J, k, d, kernel, projs, bs, activation=activation, learn_proj=learn_proj, weighted=weighted, ski=ski, ski_options=ski_options, X=X, **kwargs) kernel.initialize(init_mixin_range, init_lengthscale_range) return kernel