def DPP_graph(adjacency, p=10): """ DPP on graph Reference: Graph Sampling with Determinantal Processes, Tremblay and Amblard and Barthelmé, 2017 : https://arxiv.org/pdf/1703.01594.pdf Input: - adjacency: adjacency matrix - p: proportion for the filter Output: - indices of the sample """ n = adjacency.shape[0] D = adjacency @ np.ones(n) L = D - adjacency eig_vals, eig_vecs = np.linalg.eigh(L) filt = np.diag(eig_vals < np.percentile(eig_vals, p)) K = eig_vecs @ filt @ eig_vecs.T DPP = FiniteDPP('correlation', **{'K': K}) DPP.sample_exact() return DPP.list_of_samples[-1]
def test_likelihood_kernel_L_gram_factor(self): phi = rndm.randn(self.rank, self.N) dpp = FiniteDPP(kernel_type='likelihood', projection=False, **{'L_gram_factor': phi}) for size in self.sizes: for mode in ('GS', 'GS_bis', 'KuTa12'): dpp.flush_samples() for _ in range(self.nb_samples): dpp.sample_exact_k_dpp(size, mode) self.check_right_cardinality(dpp, dpp.list_of_samples) for mode in ('AED', 'AD'): dpp.flush_samples() dpp.sample_mcmc_k_dpp(size, **{'nb_iter': self.nb_samples}) self.check_right_cardinality(dpp, dpp.list_of_samples[0])
def test_instanciation_from_eig_vals_equal_01(self): rank, N = 6, 10 eig_vals = np.ones(rank) eig_vecs, _ = qr(rndm.randn(N, rank), mode='economic') dpp = FiniteDPP(kernel_type='correlation', projection=True, **{'K_eig_dec': (eig_vals, eig_vecs)}) dpp.compute_K() K = (eig_vecs * eig_vals).dot(eig_vecs.T) self.assertTrue(np.allclose(dpp.K, K)) # If projection=True with self.assertRaises(ValueError) as context: dpp.compute_L() self.assertTrue('cannot be computed' in str(context.exception)) # If projection=False dpp = FiniteDPP(kernel_type='correlation', projection=False, **{'K_eig_dec': (eig_vals, eig_vecs)}) with self.assertRaises(FloatingPointError) as context: dpp.compute_L() self.assertTrue('cannot be computed' in str(context.exception))
def test_likelihood_kernel(self): eig_vals = 1 + rndm.geometric(p=0.5, size=self.rank) eig_vecs, _ = qr(rndm.randn(self.N, self.rank), mode='economic') dpp = FiniteDPP(kernel_type='likelihood', projection=False, **{'L': (eig_vecs * eig_vals).dot(eig_vecs.T)}) for size in self.sizes: for mode in ('GS', 'GS_bis', 'KuTa12'): dpp.flush_samples() for _ in range(self.nb_samples): dpp.sample_exact_k_dpp(size, mode) self.check_right_cardinality(dpp, dpp.list_of_samples) for mode in ('AED', 'AD'): dpp.flush_samples() dpp.sample_mcmc_k_dpp(size, **{'nb_iter': self.nb_samples}) self.check_right_cardinality(dpp, dpp.list_of_samples[0])
def test_kernel_eig(self): eig_vals = rndm.rand(self.rank) eig_vecs, _ = qr(rndm.randn(self.N, self.rank), mode='economic') dpp = FiniteDPP(kernel_type='correlation', projection=False, **{'K_eig_dec': (eig_vals, eig_vecs)}) for size in self.sizes: for mode in ('GS', 'GS_bis', 'KuTa12'): dpp.flush_samples() for _ in range(self.nb_samples): dpp.sample_exact_k_dpp(size, mode) self.check_right_cardinality(dpp, dpp.list_of_samples) for mode in ('AED', 'AD'): dpp.flush_samples() dpp.sample_mcmc_k_dpp(size, **{'nb_iter': self.nb_samples}) self.check_right_cardinality(dpp, dpp.list_of_samples[0])
def sample_dpp_multiple_ts(kernel, k, num_masks): ''' return a list of length num_masks each element is a numpy array of length k as the sampling result ''' DPP = FiniteDPP('likelihood', **{'L': kernel}) for _ in range(num_masks): DPP.sample_exact_k_dpp(size=k) return DPP.list_of_samples
def select_with_dpp(pred_c, k): rng = np.random.RandomState(1) pred_c = np.array(pred_c) #pred_shape=(10,100) #100はout_putの出力 A = pred_c.dot(pred_c.T) DPP = FiniteDPP('likelihood', **{'L': A}) add = DPP.sample_exact_k_dpp(size=k, random_state=rng) #[7, 1, 5, 9]みたいな print(add) return add
def select( self, x: np.ndarray, a_x: np.ndarray, batch_size: int ) -> Tuple[np.ndarray, np.ndarray]: """Select a batch of points by sampling from a k-dpp.""" likelihood = self.kernel(x) + self.alpha * np.eye(len(x)) dpp = FiniteDPP("likelihood", L=likelihood) dpp.sample_exact_k_dpp(size=batch_size) indices = dpp.list_of_samples[0] return x[indices], a_x[indices]
def test_mcmc_sampler_zonotope(self): """ Test whether 'zonotope' MCMC sampling mode generates samples with the right 1 and 2 points inclusion probabilities when DPP defined by orthogonal projection correlation kernel K = A.T (A A.T)^-1 A """ A = rndm.randn(self.rank, self.N) dpp = FiniteDPP(kernel_type='correlation', projection=True, **{'A_zono': A}) dpp.sample_mcmc(mode='zonotope', **{'nb_iter': 1000}) self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples[0])) self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples[0]))
def test_instanciation_from_kernel(self): rank, N = 6, 10 eig_vals = 1 + rndm.geometric(p=0.5, size=rank) eig_vecs, _ = qr(rndm.randn(N, rank), mode='economic') dpp = FiniteDPP(kernel_type='likelihood', projection=False, **{'L': (eig_vecs * eig_vals).dot(eig_vecs.T)}) dpp.compute_K() K = (eig_vecs * (eig_vals / (1.0 + eig_vals))).dot(eig_vecs.T) self.assertTrue(np.allclose(dpp.K, K))
def test_instanciation_from_kernel(self): rank, N = 6, 10 eig_vals = rndm.rand(rank) eig_vecs, _ = qr(rndm.randn(N, rank), mode='economic') dpp = FiniteDPP(kernel_type='correlation', projection=False, **{'K': (eig_vecs * eig_vals).dot(eig_vecs.T)}) dpp.compute_L() L = (eig_vecs * (eig_vals / (1.0 - eig_vals))).dot(eig_vecs.T) self.assertTrue(np.allclose(dpp.L, L))
def test_instanciation_from_eig_vals_equal_01(self): rank, N = 6, 10 eig_vals = np.ones(rank) eig_vecs, _ = qr(rndm.randn(N, rank), mode='economic') dpp = FiniteDPP(kernel_type='likelihood', projection=True, **{'L_eig_dec': (eig_vals, eig_vecs)}) dpp.compute_L() L = (eig_vecs * eig_vals).dot(eig_vecs.T) self.assertTrue(np.allclose(dpp.L, L))
def ppo_update(env, kuhn_pop, k, lambda_weight=0.1, ppo_kwargs=None, dpp=True, dpp_sample=True, switch=False): M = kuhn_pop.get_metagame(k) meta_nash, _ = fictitious_play(payoffs=M, iters=1000) meta_nash = meta_nash[-1] M = f.normalize(torch.from_numpy(M).float(), dim=1, p=2) # Normalise L = M @ M.t() # Compute kernel L_card = torch.trace( torch.eye(L.shape[0]) - torch.inverse(L + torch.eye(L.shape[0]))) # Compute cardinality if dpp_sample: L_np = L_numpy(L) DPP = FiniteDPP(kernel_type='likelihood', projection=False, **{'L': L_np}) sample_size = 0 while sample_size < L_card: # Ensure at least as many as expected sample = np.array(DPP.sample_exact(mode='GS')) sample_size = len(sample) sample -= 1 metanash_rectified = np.zeros_like(meta_nash) metanash_rectified[sample] = meta_nash[sample] meta_nash = metanash_rectified # Create PPO trainer agent1 = kuhn_pop.pop[k] agent2 = kuhn_pop.agg_agents(meta_nash) ppo_trainer = PPOTrainer(env, agent1, agent2, kuhn_pop, lambda_weight=lambda_weight, dpp=dpp, **ppo_kwargs) # Train and update in population exp_return, _ = ppo_trainer.train(switch=switch) kuhn_pop.update_hashed_agent(k) return exp_return, L_card
def test_mcmc_sampler_basis_exchange(self): """ Test whether 'E' (basis_exchange) MCMC sampling mode generates samples with the right 1 and 2 points inclusion probabilities when DPP defined by orthogonal projection correlation kernel K from its eigendecomposition """ eig_vals = np.ones(self.rank) eig_vecs, _ = qr(rndm.randn(self.N, self.rank), mode='economic') dpp = FiniteDPP(kernel_type='correlation', projection=True, **{'K_eig_dec': (eig_vals, eig_vecs)}) dpp.sample_mcmc_k_dpp(size=self.rank, **{'nb_iter': 1000}) self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples[0])) self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples[0]))
def __call__(self, x, dropout_rate=0.5, layer_num=0): mask_len = x.shape[-1] k = int(mask_len * (1 - dropout_rate)) if layer_num not in self.layer_correlations: x_matrix = x.cpu().numpy() if self.covariance: L = np.cov(x_matrix.T) else: L = np.corrcoef(x_matrix.T) if self.noise_level is not None: L += self.noise_level * np.eye(len(L)) if not self.ht_norm: self.dpps[layer_num] = FiniteDPP('likelihood', **{'L': L}) self.dpps[layer_num].sample_exact( ) # to trigger eig values generation else: eigen_values = np.linalg.eigh(L)[0] "Get tilted k-dpp, see amblard2018" nu = get_nu(eigen_values, k) I = torch.eye(len(L)).to(x.device) L_tilted = np.exp(nu) * torch.DoubleTensor(L).to(x.device) K_tilted = torch.mm(L_tilted, torch.inverse(L_tilted + I)).double() self.dpps[layer_num] = FiniteDPP( 'correlation', **{"K": K_tilted.detach().cpu().numpy()}) self.norm[layer_num] = torch.reciprocal(torch.diag(K_tilted)) self.L = L_tilted self.K = K_tilted # Keep data for debugging self.layer_correlations[layer_num] = L mask = torch.ones(mask_len).double().to(x.device) return mask mask = torch.zeros(mask_len).double().to(x.device) ids = self.dpps[layer_num].sample_exact_k_dpp(k) if self.ht_norm: mask[ids] = self.norm[layer_num][ids] else: mask[ids] = mask_len / len(ids) return mask
def __call__(self, x, dropout_rate=0.5, layer_num=0): if layer_num not in self.layer_correlations: # warm-up, generatign correlations masks x_matrix = x.cpu().numpy() self.x_matrix = x_matrix micro = 1e-12 x_matrix += np.random.random(x_matrix.shape) * micro # for computational stability correlations = np.corrcoef(x_matrix.T) self.dpps[layer_num] = FiniteDPP('likelihood', **{'L': correlations}) self.layer_correlations[layer_num] = correlations return x.data.new(x.data.size()[-1]).fill_(1) # sampling nodes ids dpp = self.dpps[layer_num] for _ in range(ATTEMPTS): dpp.sample_exact() ids = dpp.list_of_samples[-1] if len(ids): # We should retry if mask is zero-length break mask_len = x.data.size()[-1] mask = x.data.new(mask_len).fill_(0) mask[ids] = mask_len/len(ids) return x.data.new(mask)
def __call__(self, x, dropout_rate=0.5, layer_num=0): if layer_num not in self.layer_correlations: x_matrix = x.cpu().numpy() correlations = np.corrcoef(x_matrix.T) if self.noise_level is not None: correlations += self.noise_level * np.eye(len(correlations)) self.dpps[layer_num] = FiniteDPP('likelihood', **{'L': correlations}) self.dpps[layer_num].sample_exact() # to trigger eig values generation self.ranks[layer_num] = self._rank(self.dpps[layer_num]) # Keep data for debugging self.ranks_history[layer_num].append(self.ranks[layer_num]) self.layer_correlations[layer_num] = correlations return x.data.new(x.data.size()[-1]).fill_(1) mask = x.data.new(x.data.size()[-1]).fill_(0) k = int(self.ranks[layer_num] * (1 - dropout_rate)) self.dpps[layer_num].sample_exact_k_dpp(k) ids = self.dpps[layer_num].list_of_samples[-1] mask[ids] = 1 / (1 - dropout_rate + 1e-10) return x.data.new(mask)
def test_instanciation_from_valid_parameters(self): for idx, (proj, param) in enumerate(self.list_of_valid_params): with self.subTest(index=idx, projection=proj, param=param.keys()): self.assertIsInstance(FiniteDPP('correlation', proj, **param), FiniteDPP)
def DPP_kernel(adjacency, kernel, k=50): """ DPP on graph using the kernel as L Input: - adjacency: adjacency matrix - kernel: kernel for L - k: number of nodes Output: - indices of the sample """ L = kernel(adjacency) DPP = FiniteDPP('likelihood', **{'L': L}) inds = DPP.sample_exact_k_dpp(k) return inds
def test_instanciation_from_invalid_key(self): with self.assertRaises(ValueError) as context: FiniteDPP(kernel_type='correlation', projection=False, **{'random_key': 0}) self.assertTrue('Invalid parametrization of correlation kernel' in str( context.exception))
def test_instanciation_from_invalid_parameter_key(self): kernel_type, projection = 'likelihood', False for key in ['K', 'K_eig_dec', 'A_zono', 'random_key']: with self.subTest(key=key): with self.assertRaises(ValueError) as context: FiniteDPP(kernel_type, projection, **{key: 0}) self.assertIn('Invalid param', str(context.exception))
def test_computation_of_likehood_kernel_from_valid_parameters(self): kernel_type = 'likelihood' for idx, (proj, param) in enumerate(self.list_of_valid_params): with self.subTest(index=idx, projection=proj, param=param.keys()): dpp = FiniteDPP(kernel_type, projection=proj, **param) dpp.compute_L() if 'L' in param: L = param['L'] elif 'L_eig_dec' in param: e_vals, e_vecs = param['L_eig_dec'] L = (e_vecs * e_vals).dot(e_vecs.T) elif 'L_gram_factor' in param: L = param['L_gram_factor'].T.dot(param['L_gram_factor']) self.assertTrue(np.allclose(dpp.L, L))
def test_instanciation_from_invalid_parameter_key(self): kernel_type, projection = 'correlation', False for key in ['L', 'L_eig_dec', 'L_gram_factor', 'random_key']: with self.subTest(key=key): with self.assertRaises(ValueError) as context: FiniteDPP(kernel_type, projection, **{key: (0, 0)}) self.assertIn('Invalid param', str(context.exception))
def run_adequation_tests(self, kernel_type, list_dpp_params, dict_sampler_mode_param, adequation_to_check): for sampler, modes in dict_sampler_mode_param.items(): for md, md_params in modes.items(): for idx, (proj, dpp_param) in enumerate(list_dpp_params): dpp = FiniteDPP(kernel_type, projection=proj, **dpp_param) with self.subTest(idx=idx, dpp=(dpp.kernel_type, dpp.projection, dpp.params_keys), sampler=(sampler, md, md_params)): dpp.flush_samples() samples = self.get_samples(dpp, sampler, md, **md_params) for adeq_typ in adequation_to_check: with self.subTest(adequation=adeq_typ): adeq, msg = self.adequation( adeq_typ, samples, dpp) self.assertTrue(adeq, msg)
def test_instanciation_with_projection_true_should_raise_warning(self): # raise warning when projection not set to True # https://docs.python.org/3/library/warnings.html with warnings.catch_warnings(record=True) as w: FiniteDPP(kernel_type='likelihood', projection=True, **{'L_eig_dec': (self.e_vals_eq_01, self.e_vecs)}) self.assertIn('Weird setting', str(w[-1].message))
def test_computation_of_likehood_kernel_should_raise_warning_with_L_eval( self): def eval_L_linear(X, Y=None): if Y is None: return X.dot(X.T) else: return X.dot(Y.T) X_data = rndm.rand(100, 6) dpp = FiniteDPP(kernel_type='likelihood', projection=False, **{'L_eval_X_data': (eval_L_linear, X_data)}) # raise warning when projection not set to True # https://docs.python.org/3/library/warnings.html with warnings.catch_warnings(record=True) as w: dpp.compute_L() self.assertIn('Weird setting', str(w[-1].message))
def test_instanciation_from_A_zono_with_projection_false_should_raise_warning( self): kernel_type, projection = 'correlation', False dpp_param = {'A_zono': self.A_zono} # raise warning when projection not set to True # https://docs.python.org/3/library/warnings.html with warnings.catch_warnings(record=True) as w: FiniteDPP(kernel_type, projection, **dpp_param) self.assertIn('Weird setting', str(w[-1].message))
def test_computation_of_correlation_kernel_from_valid_parameters(self): kernel_type = 'correlation' for idx, (proj, param) in enumerate(self.list_of_valid_params): with self.subTest(index=idx, projection=proj, param=param.keys()): dpp = FiniteDPP(kernel_type, projection=proj, **param) dpp.compute_K() if 'K' in param: K = param['K'] elif 'K_eig_dec' in param: e_vals, e_vecs = param['K_eig_dec'] K = (e_vecs * e_vals).dot(e_vecs.T) elif 'A_zono' in param: e_vals = np.ones(param['A_zono'].shape[0]) e_vecs, _ = la.qr(param['A_zono'].T, mode='economic') K = (e_vecs * e_vals).dot(e_vecs.T) self.assertTrue(np.allclose(dpp.K, K))
def dpp(B): ''' B is the (n,d)-matrix from the paper ''' U, s, _ = np.linalg.svd(B) eig_vals = np.zeros(len(U)) eig_vals[:len(s)] = np.abs(s)**2 DPP = FiniteDPP(kernel_type='correlation', projection=False, **{'K_eig_dec': (eig_vals, U)}) return DPP
def test_instanciation_from_A_zono(self): rank, N = 6, 10 A = rndm.randn(rank, N) dpp = FiniteDPP(kernel_type='correlation', projection=True, **{'A_zono': A}) dpp.compute_K() K = A.T.dot(np.linalg.inv(A.dot(A.T))).dot(A) self.assertTrue(np.allclose(dpp.K, K)) # raise warning when projection not set to True # https://docs.python.org/3/library/warnings.html with warnings.catch_warnings(record=True) as w: FiniteDPP(kernel_type='correlation', projection=False, **{'A_zono': rndm.randn(rank, N)}) self.assertTrue('Weird setting' in str(w[-1].message)) # Raise error when not full row rank with self.assertRaises(ValueError) as context: FiniteDPP(kernel_type='correlation', projection=True, **{'A_zono': rndm.randn(N, rank)}) self.assertTrue('not full row rank' in str(context.exception))