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_proj_dpp_sampler_from_eigdec_mode_KuTa12(self):
        """ Test whether 'KuTa12' 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

        Complexity :math:`\\mathcal{O}(N rank^3)`
        """
        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.flush_samples()
        for _ in range(self.nb_samples):
            dpp.sample_exact(mode='KuTa12')

        self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples))
        self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples))
    def test_proj_dpp_sampler_from_kernel_mode_Schur(self):
        """ Test whether 'Schur' 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

        Evaluate the conditionals using the Schur complement updates
        """
        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_vecs * eig_vals).dot(eig_vecs.T)})

        dpp.flush_samples()
        for _ in range(self.nb_samples):
            dpp.sample_exact(mode='Schur')

        self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples))
        self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples))
    def test_proj_dpp_sampler_generic_kernel(self):
        """ Test whether 'Chol' 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.
        The ``projection`` argument is set to ``False`` to make sure the :py:func:`~dppy.exact_sampling.dpp_sampler_generic_kernel` is used

        This is the default sampler when calling `.sample_exact()`
        """
        eig_vals = np.ones(self.rank)
        eig_vecs, _ = qr(rndm.randn(self.N, self.rank), mode='economic')
        dpp = FiniteDPP(kernel_type='correlation',
                        projection=False,
                        **{'K': (eig_vecs * eig_vals).dot(eig_vecs.T)})

        dpp.flush_samples()
        for _ in range(self.nb_samples):
            dpp.sample_exact(mode='Chol')

        self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples))
        self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples))
    def test_proj_dpp_sampler_from_kernel_mode_Chol(self):
        """ Test whether 'Chol' 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.

        Complexity :math:`\\mathcal{O}(N rank^2)`

        .. seealso::

            - :cite:`Pou19` Algorithm 1
        """
        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_vecs * eig_vals).dot(eig_vecs.T)})

        dpp.flush_samples()
        for _ in range(self.nb_samples):
            dpp.sample_exact(mode='Chol')

        self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples))
        self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples))
    def test_proj_dpp_sampler_from_kernel_mode_GS(self):
        """ Test whether 'GS' 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

        Complexity :math:`\\mathcal{O}(N rank^2)`

        This is the default sampler when calling `.sample_exact()`
        """
        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_vecs * eig_vals).dot(eig_vecs.T)})

        dpp.flush_samples()
        for _ in range(self.nb_samples):
            dpp.sample_exact(mode='GS')

        # dpp.compute_K()

        self.assertTrue(self.singleton_adequation(dpp, dpp.list_of_samples))
        self.assertTrue(self.doubleton_adequation(dpp, dpp.list_of_samples))
    def test_correlation_kernel_projection_A_zono(self):
        A = rndm.randn(self.rank, self.N)

        dpp = FiniteDPP(kernel_type='correlation',
                        projection=True,
                        **{'A_zono': A})

        for mode in ('GS', 'GS_bis', 'KuTa12'):

            dpp.flush_samples()
            for _ in range(self.nb_samples):
                dpp.sample_exact(mode)

            self.check_right_cardinality(dpp, dpp.list_of_samples)

        for mode in ('zonotope', 'E'):

            dpp.flush_samples()
            dpp.sample_mcmc(mode,
                            **{'size': self.rank, 'nb_iter': self.nb_samples})

            self.check_right_cardinality(dpp, dpp.list_of_samples[0])
    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 mode in ('GS', 'GS_bis', 'KuTa12'):

            dpp.flush_samples()
            for _ in range(self.nb_samples):
                dpp.sample_exact(mode)

            self.check_right_cardinality(dpp, dpp.list_of_samples)

        for mode in ('AED', 'AD'):

            dpp.flush_samples()
            dpp.sample_mcmc(mode,
                            **{'nb_iter': self.nb_samples})

            self.check_right_cardinality(dpp, dpp.list_of_samples[0])
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_correlation_kernel_projection_kernel_eig(self):

        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)})

        for mode in ('GS', 'GS_bis', 'KuTa12'):

            dpp.flush_samples()
            for _ in range(self.nb_samples):
                dpp.sample_exact(mode)

            self.check_right_cardinality(dpp, dpp.list_of_samples)

        for mode in ('E'):

            dpp.flush_samples()
            dpp.sample_mcmc(mode,
                            **{'size': self.rank, 'nb_iter': self.nb_samples})

            self.check_right_cardinality(dpp, dpp.list_of_samples[0])
    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 mode in ('GS', 'GS_bis', 'KuTa12'):

            dpp.flush_samples()
            for _ in range(self.nb_samples):
                dpp.sample_exact(mode)

            self.check_right_cardinality(dpp, dpp.list_of_samples)

        for mode in ('AED', 'AD'):

            dpp.flush_samples()
            dpp.sample_mcmc(mode,
                            **{'nb_iter': self.nb_samples})

            self.check_right_cardinality(dpp, dpp.list_of_samples[0])
Beispiel #12
0
from scipy.linalg import qr
import matplotlib.pyplot as plt
from dppy.finite_dpps import FiniteDPP

r, N = 5, 10
e_vals = np.ones(r)
e_vecs, _ = qr(np.random.randn(N, r), mode='economic')

dpp_L = FiniteDPP('likelihood',
                  projection=True,
                  **{'L_eig_dec': (e_vals, e_vecs)})

nb_samples = 1000
dpp_L.flush_samples
for _ in range(nb_samples):
    dpp_L.sample_exact()

sizes = list(map(len, dpp_L.list_of_samples))

p = 0.5  # binomial parameter
rv = binom(r, p)

fig, ax = plt.subplots(1, 1)

x = np.arange(0, r + 1)

pdf = rv.pmf(x)
ax.plot(x, pdf, 'ro', ms=8, label=r'pdf $Bin({}, {})$'.format(r, p))

hist = np.histogram(sizes, bins=np.arange(0, r + 2), density=True)[0]
ax.vlines(x, 0, hist, colors='b', lw=5, alpha=0.5, label='hist of sizes')
Beispiel #13
0
for (i_cand, n_cand) in enumerate(n_list):
    result = []
    print(n_cand)
    I_train = sample_without_replacement(n_population=X_all.shape[0],
                                         n_samples=int(n_cand),
                                         random_state=r)

    X_train = X_all[I_train, :]
    n = X_train.shape[0]

    with Timer(verbose=False) as t_vfx:
        vfx_dpp_sampler = FiniteDPP(kernel_type='likelihood',
                                    L_eval_X_data=(dot_func, X_train))
        S_vfx = vfx_dpp_sampler.sample_exact('vfx',
                                             rls_oversample_bless=2.5,
                                             rls_oversample_dppvfx=2,
                                             random_state=r,
                                             desired_expected_size=desired_k,
                                             verbose=False)
    result.append({'n': n, 'alg': 'vfx', 'time': t_vfx.secs, 'k': len(S_vfx)})

    with Timer(verbose=False) as t_vfx_resample:
        S_vfx_resample = vfx_dpp_sampler.sample_exact(
            'vfx',
            rls_oversample_bless=2.5,
            rls_oversample_dppvfx=2,
            random_state=r,
            desired_expected_size=desired_k,
            verbose=False)
    result.append({
        'n': n,
        'alg': 'vfx_resample',
Beispiel #14
0
def vfx_sampling_do_sampling_loop(X_data,
                                  eval_L,
                                  intermediate_sample_info,
                                  rng,
                                  max_iter=1000,
                                  verbose=True,
                                  **kwargs):
    """Given pre-computed information, run a rejection sampling loop to generate DPP samples.
        :param array_like X_data: dataset such that L = eval_L(X_data), out of which we are sampling objects
        according to a DPP
        :param callable eval_L: likelihood function. Given two sets of n points X and m points Y, eval_L(X, Y) should
        compute the (n x m) matrix containing the likelihood between points. The function should also
        accept a single argument X and return eval_L(X) = eval_L(X, X).
        As an example, see the implementation of any of the kernels provided by scikit-learn
        (e.g. sklearn.gaussian_process.kernels.PairwiseKernel).
        :param _IntermediateSampleInfo intermediate_sample_info: Pre-computed information necessary for the
        vfx rejection sampling loop, as returned by :func:`vfx_sampling_precompute_constants.`
        :param np.random.RandomState rng: random source used for sampling
        :param max_iter: maximum number of intermediate sample rejections before giving up.
        :type max_iter:
            int, default 1000
        :param bool verbose: controls verbosity of debug output, including progress bars.
        The progress bar reports the execution of the rejection sampling loop, showing:
            - acc_thresh: latest computed probability of acceptance
            - rej_iter: iteration of the rejection sampling loop (i.e. rejections so far)
        :type verbose:
            bool, default True
        :param dict kwargs: we add a unused catch all kwargs argument to make sure that the user can pass the
        same set of parameters to both vfx_sampling_precompute_constants and vfx_sampling_do_sampling_loop. This
        way if there is any spurious non-shared parameter (e.g. rls_oversample_bless) we simply ignore it.
        :return: Sample from a DPP (as a list) and number of rejections as int
        :rtype: tuple(list, int)
    """
    # TODO: taking as input a catch-all kwargs can be misleading for the user. e.g. if there is a typo in a paremater
    # it will silently ignore it and use the default instead

    n, d = X_data.shape

    # rename it to pre-computed state for shortness
    pc_state = intermediate_sample_info

    # Phase 3: rejection sampling loop

    with get_progress_bar(disable=not verbose) as prog_bar:
        for rej_iter in range(max_iter):
            # sample t
            lam = np.ceil(pc_state.q * np.exp(pc_state.s / pc_state.q))
            t = rng.poisson(lam=lam.astype('int'))

            # sample sigma subset
            sigma = rng.choice(n,
                               size=t,
                               p=pc_state.rls_estimate / pc_state.s,
                               replace=True)
            sigma_uniq, sigma_uniq_count = np.unique(sigma, return_counts=True)
            X_sigma_uniq = X_data[sigma_uniq, :]

            # compute log(Det(I + \tilda{L}_sigma)) = log(Det(I + W*L_sigma*W))
            # with W_ii = ( s / (q * l_i) )^1/2
            # this is done by computing
            # log(Det(I + W*L_sigma*W))
            # = log(Det(W * (W^-2 + L_sigma) * W))
            # = log(Det(W) * Det(W^-2 + L_sigma) * Det(W))
            # = log(Det(W)) + log(Det(W^-2 + L_sigma)) + log(Det(W))
            # = log(Det(W^2)) + log(Det(W^-2 + L_sigma))
            # = -log(Det(W^-2)) + log(Det(W^-2 + L_sigma))

            W_square_inv = (pc_state.q * pc_state.rls_estimate[sigma_uniq] /
                            (pc_state.s * sigma_uniq_count))

            I_L_sigma = (
                pc_state.alpha_star * eval_L(X_sigma_uniq, X_sigma_uniq) +
                np.diag(W_square_inv))

            s_logdet, logdet_I_L_sigma = np.linalg.slogdet(I_L_sigma)
            if not s_logdet >= 0.0:
                raise ValueError(
                    'logdet_I_L_sigma is negative, this should never happen. '
                    's: {}'.format(s_logdet))

            logdet_W_square_inv = np.sum(np.log(W_square_inv))

            acc_thresh = (pc_state.z + logdet_I_L_sigma - logdet_W_square_inv -
                          pc_state.logdet_I_A -
                          t * pc_state.s / pc_state.q).item()

            if acc_thresh >= 0.1:
                raise ValueError(
                    'Accepting with probability larger than 1, this should never happen. '
                    's: {}'.format(np.exp(acc_thresh)))

            accept = np.log(rng.rand()) <= acc_thresh

            prog_bar.set_postfix(acc_thresh=np.exp(acc_thresh),
                                 rej_count=rej_iter)
            prog_bar.update()

            if accept:
                break
        else:
            raise ValueError(
                'The vfx sampler reached the maximum number of rejections allowed '
                'for the intermediate sample selection ({}), try to increase the q factor '
                '(see q_func parameter) or the Nystrom approximation accuracy '
                '(see rls_oversample_* parameters).'.format(max_iter))

    # Phase 4: use L_tilda to perform exact DPP sampling
    # compute alpha_star * L_tilda = alpha_star * W*L_sigma*W
    W = (
        np.sqrt(pc_state.s * sigma_uniq_count) /
        np.sqrt(pc_state.q * pc_state.rls_estimate[sigma_uniq]).reshape(-1, 1))

    L_tilda = pc_state.alpha_star * W.T * eval_L(X_sigma_uniq,
                                                 X_sigma_uniq) * W

    E, U = np.linalg.eigh(L_tilda)

    # this has to be here rather than at the top to avoid circular dependencies
    # TODO: maybe refactor to avoid this
    from dppy.finite_dpps import FiniteDPP
    DPP = FiniteDPP(kernel_type='likelihood', L_eig_dec=(E, U))
    S_tilda = np.array(DPP.sample_exact(random_state=rng), dtype=int)

    S = sigma_uniq[S_tilda].ravel().tolist()

    return S, rej_iter
Beispiel #15
0
  def sample_histo(self, user_histo, action_ratio=0.8, max_samp_by_user=5,  max_state=100, max_action=50, nb_states=[], nb_actions=[]):
    '''
    For a given historic, make one or multiple sampling.
    If no optional argument given for nb_states and nb_actions, then the sampling
    is random and each sample can have differents size for action and state.
    To normalize sampling we need to give list of the numbers of states and actions
    to be sampled.

    Parameters
    ----------
    user_histo :        DataFrame
                        historic of user
    delimiter :         string, optional
                        delimiter for the csv
    action_ratio :      float, optional
                        ratio form which movies in history will be selected
    max_samp_by_user:   int, optional
                        Nulber max of sample to make by user
    max_state :         int, optional
                        Number max of movies to take for the 'state' column
    max_action :        int, optional
                        Number max of movies to take for the 'action' action
    nb_states :         array(int), optional
                        Numbers of movies to be taken for each sample made on user's historic
    nb_actions :        array(int), optional
                        Numbers of rating to be taken for each sample made on user's historic
    
    Returns
    -------
    states :            List(String)
                        All the states sampled, format of a sample: itemId&rating
    actions :           List(String)
                        All the actions sampled, format of a sample: itemId&rating
    '''

    n = len(user_histo)
    sep = int(action_ratio * n)

    r, N = 4, 1682

    DPP = FiniteDPP('likelihood',
                **{'L_eval_X_data': (example_eval_L_linear, randn(N, r))})

    for _ in range(1682):
        DPP.sample_exact('vfx')

    nb_sample = random.randint(1, max_samp_by_user)
    if not nb_states:
      nb_states = [min(random.randint(1, sep), max_state) for i in range(DPP.list_of_samples)]
    if not nb_actions:
      nb_actions = [min(random.randint(1, n - sep), max_action) for i in range(DPP.list_of_samples)]
    assert len(nb_states) == len(nb_actions), 'Given array must have the same size'
    
    states  = []
    actions = []
    # SELECT SAMPLES IN HISTO
    for i in range(len(nb_states)):
      sample_states = user_histo.iloc[0:sep].sample(nb_states[i])
      sample_actions = user_histo.iloc[-(n - sep):].sample(nb_actions[i])
      
      sample_state =  []
      sample_action = []
      for j in range(nb_states[i]):
        row   = sample_states.iloc[j]
        # FORMAT STATE
        state = str(row.loc['itemId']) + '&' + str(row.loc['rating'])
        sample_state.append(state)
      
      for j in range(nb_actions[i]):
        row    = sample_actions.iloc[j]
        # FORMAT ACTION
        action = str(row.loc['itemId']) + '&' + str(row.loc['rating'])
        sample_action.append(action)

      states.append(sample_state)
      actions.append(sample_action)
    return states, actions
Beispiel #16
0
def alpha_dpp_sampling_do_sampling_loop(X_data,
                                        eval_L,
                                        intermediate_sample_info,
                                        rng,
                                        max_iter=1000,
                                        verbose=True,
                                        **kwargs):
    """Given pre-computed information, run a rejection sampling loop to generate samples from an alpha-rescaled DPP,
    where the alpha rescaling is provided as a field of the intermediate_sample_info structture.
        :param array_like X_data: dataset such that L = eval_L(X_data), out of which we are sampling objects
        according to a DPP
        :param callable eval_L: likelihood function. Given two sets of n points X and m points Y, eval_L(X, Y) should
        compute the (n x m) matrix containing the likelihood between points. The function should also
        accept a single argument X and return eval_L(X) = eval_L(X, X).
        As an example, see the implementation of any of the kernels provided by scikit-learn
        (e.g. sklearn.gaussian_process.kernels.PairwiseKernel).
        :param _IntermediateSampleInfoAlphaRescale intermediate_sample_info: Pre-computed information necessary for the
        alpha-dpp rejection sampling loop, as returned by :func:`alpha_dpp_sampling_precompute_constants.`
        :param np.random.RandomState rng: random source used for sampling
        :param max_iter:  maximum number of intermediate sample rejections before giving up.
        :type max_iter:
            int, default 1000
        :param bool verbose: controls verbosity of debug output, including progress bars.
        The progress bar reports the execution of the rejection sampling loop, showing:
            - acc_thresh: latest computed probability of acceptance
            - rej_iter: iteration of the rejection sampling loop (i.e. rejections so far)
        :type verbose:
            bool, default True
        :param dict kwargs: we add a unused catch all kwargs argument to make sure that the user can pass the
        same set of parameters to both alpha_dpp_sampling_precompute_constants and alpha_dpp_sampling_do_sampling_loop.
        This way if there is any spurious non-shared parameter (e.g. rls_oversample_bless) we simply ignore it.
        :return: Sample from an alpha-rescaled DPP (as a list), number of rejections as int, and a modified copy of
        intermediate_sample_info with updated estimates for the marginal inclusion probabilities (i.e. ridge leverage scores).
        :rtype: tuple(list, int, _IntermediateSampleInfoAlphaRescale)
    """
    # TODO: taking as input a catch-all kwargs can be misleading for the user. e.g. if there is a typo in a paremater
    # it will silently ignore it and use the default instead

    n, d = X_data.shape

    # rename it to pre-computed state for shortness
    pc_state = intermediate_sample_info

    rls_bound = pc_state.rls_upper_bound.copy()
    rls_bound_valid = pc_state.rls_upper_bound_valid.copy()

    # Phase 3: rejection sampling loop
    with get_progress_bar(disable=not verbose) as prog_bar:
        for rej_iter in range(max_iter):
            # sample all s_i
            rls_bound_old = rls_bound.copy()
            s_vec = rng.poisson(lam=pc_state.r * np.exp(1.0 / pc_state.r) *
                                rls_bound)

            idx_active_items = s_vec.nonzero()[0]

            s_vec_filtered = s_vec.copy()
            idx_rls_to_recompute = idx_active_items[np.logical_not(
                rls_bound_valid[idx_active_items])]
            if len(idx_rls_to_recompute) > 0:
                rls_estimate = estimate_rls_from_weighted_dict_eigendecomp(
                    X_data[idx_rls_to_recompute, :], eval_L,
                    pc_state.dict_alphadpp, pc_state.eigvecs_L_hat,
                    pc_state.eigvals_L_hat, pc_state.alpha_hat)

                if np.any(rls_estimate > rls_bound[idx_rls_to_recompute]):
                    raise ValueError(
                        'Some estimated RLS are larger than the pre-computed bound,'
                        ' this should never happen. Double check your kernel function.'
                        'Maximum/minimum ratio: {}'.format(
                            np.ptp(rls_estimate /
                                   rls_bound[idx_rls_to_recompute])))

                rls_bound[idx_rls_to_recompute] = rls_estimate
                rls_bound_valid[idx_rls_to_recompute] = True

                acceptance_prob = rls_bound[
                    idx_rls_to_recompute] / rls_bound_old[idx_rls_to_recompute]

                s_vec_filtered[idx_rls_to_recompute] = rng.binomial(
                    s_vec[idx_rls_to_recompute], acceptance_prob)

            t = s_vec_filtered.sum()
            sigma_uniq = np.nonzero(s_vec_filtered)[0]
            sigma_uniq_count = s_vec_filtered[sigma_uniq]

            # sample sigma subset
            X_sigma_uniq = X_data[sigma_uniq, :]

            # compute log(Det(I + \tilda{L}_sigma)) = log(Det(I + A*L_sigma*A))
            # with A_ii = ( 1 / (r * l_i) )^1/2
            #
            # For numerical stability we will also de-alias identical sigmas, which amounts to summing their weights

            A = np.sqrt(sigma_uniq_count /
                        (pc_state.r * rls_bound[sigma_uniq])).reshape(-1, 1)

            I_L_sigma = (pc_state.alpha_hat * A.T *
                         eval_L(X_sigma_uniq, X_sigma_uniq) * A +
                         np.eye(A.shape[0]))

            s_logdet, logdet_I_L_sigma = np.linalg.slogdet(I_L_sigma)
            if not s_logdet >= 0.0:
                raise ValueError(
                    'logdet_I_L_sigma is negative, this should never happen. '
                    's: {}'.format(s_logdet))

            deff_alpha_L_hat = np.sum(
                1.0 - 1.0 /
                (pc_state.alpha_hat * pc_state.eigvals_L_hat + 1.0))
            log_det_alpha_L_hat = np.sum(
                np.log(1.0 + (pc_state.alpha_hat * pc_state.eigvals_L_hat)))

            acc_thresh = (deff_alpha_L_hat + logdet_I_L_sigma -
                          log_det_alpha_L_hat - (t / pc_state.r)).item()

            if acc_thresh >= 0.0:
                raise ValueError(
                    'Accepting with probability larger than 1, this should never happen. '
                    's: {}'.format(np.exp(acc_thresh)))

            accept = np.log(rng.rand()) <= acc_thresh

            prog_bar.set_postfix(acc_thresh=np.exp(acc_thresh),
                                 rej_count=rej_iter)
            prog_bar.update()

            if accept:
                break
        else:
            raise ValueError(
                'The alpha-dpp sampler reached the maximum number of rejections allowed '
                'for the intermediate sample selection ({}), try to increase the q factor '
                '(see q_func parameter) or the Nystrom approximation accuracy '
                '(see rls_oversample_* parameters).'.format(max_iter))

    # Phase 4: use L_tilda to perform exact DPP sampling
    # compute alpha_star * L_tilda = alpha_star * A*L_sigma*A
    # with A_ii = ( 1 / (r * l_i) )^1/2
    A = np.sqrt(sigma_uniq_count /
                (pc_state.r * rls_bound[sigma_uniq])).reshape(-1, 1)

    L_tilda = pc_state.alpha_hat * A.T * eval_L(X_sigma_uniq, X_sigma_uniq) * A

    E, U = np.linalg.eigh(L_tilda)

    # this has to be here rather than at the top to avoid circular dependencies
    # TODO: maybe refactor to avoid this
    from dppy.finite_dpps import FiniteDPP
    DPP = FiniteDPP(kernel_type='likelihood', L_eig_dec=(E, U))
    S_tilda = np.array(DPP.sample_exact(random_state=rng), dtype=int)

    S = sigma_uniq[S_tilda].ravel().tolist()

    intermediate_sample_info = intermediate_sample_info._replace(
        rls_upper_bound=rls_bound)
    intermediate_sample_info = intermediate_sample_info._replace(
        rls_upper_bound_valid=rls_bound_valid)

    return S, rej_iter, intermediate_sample_info
def run_dpp_option2(current_player,
                    meta_game,
                    meta_probabilities,
                    dpp_iters=10000,
                    uniform=False):

    rng = RandomState(0)

    meta_game = meta_game[current_player]
    if current_player == 0:
        nb_policies = meta_game.shape[1]
        probabilities_enemy = meta_probabilities[1]
    elif current_player == 1:
        nb_policies = meta_game.shape[0]
        meta_game = meta_game.T
        probabilities_enemy = meta_probabilities[0]
    else:
        raise NotImplementedError

    L = np.zeros((nb_policies, nb_policies))

    for n in range(nb_policies):
        for m in range(n, nb_policies):
            L[n,
              m] = np.dot(meta_game[:, n], meta_game[:, m]) / (np.linalg.norm(
                  meta_game[:, n]) * np.linalg.norm(meta_game[:, m]))
            if n != m:
                L[m, n] = L[n, m]

    DPP = FiniteDPP(kernel_type='likelihood', projection=False, **{'L': L})

    K = np.eye(L.shape[0]) - np.linalg.inv(L + np.eye(L.shape[0]))
    E_cardinality = np.trace(K)

    # Sample and probabilities
    sample_size = 0
    iters = 0
    while sample_size < E_cardinality:
        sample = np.array(DPP.sample_exact(mode='GS', random_state=rng))
        sample_size = len(sample)
        iters += 1
        if iters > dpp_iters:
            sample = np.arange(len(probabilities_enemy))
            print(
                " ####################### TOO MANY!! #######################################"
            )
            break

    if not uniform:
        if len(sample) == len(probabilities_enemy):
            return probabilities_enemy
        probabilities_enemy_rectified = np.zeros_like(probabilities_enemy)
        probabilities_enemy_rectified[sample] = probabilities_enemy[sample]
        return probabilities_enemy_rectified
    else:
        if len(sample) == len(probabilities_enemy):
            return (1. / len(sample)) * np.ones_like(probabilities_enemy)
        probabilities_enemy_rectified = np.zeros_like(probabilities_enemy)
        probabilities_enemy_rectified[sample] = (
            1. / len(sample)) * np.ones_like(probabilities_enemy)[sample]
        return probabilities_enemy_rectified
Beispiel #18
0
def update_set(x_pool,
               x_train,
               y_pool,
               y_train,
               step,
               method='basic_bern',
               model=None,
               nn_runs=100):
    images = torch.FloatTensor(x_pool)
    inferencer = Inferencer(model)

    if method == 'random':
        idxs = range(step)
    elif method == 'AL_dpp':
        mask = build_mask('basic_bern')
        estimator = build_estimator('bald_masked',
                                    inferencer,
                                    dropout_mask=mask,
                                    num_classes=10,
                                    keep_runs=True,
                                    nn_runs=nn_runs)
        estimator.estimate(images)  # to generate mcd
        mcd = estimator.last_mcd_runs().reshape(-1, nn_runs * 10)
        dpp = FiniteDPP('likelihood', **{'L': np.corrcoef(mcd)})
        idxs = set()
        while len(idxs) < step:
            dpp.sample_exact()
            idxs.update(dpp.list_of_samples[-1])
        idxs = list(idxs)[:step]
    elif method == 'error_oracle':
        predictions = F.softmax(inferencer(images),
                                dim=1).detach().cpu().numpy()
        errors = -np.log(predictions[np.arange(len(predictions)), y_pool])
        idxs = np.argsort(errors)[::-1][:step]
    elif method == 'stoch_oracle':
        predictions = F.softmax(inferencer(images),
                                dim=1).detach().cpu().numpy()
        errors = -np.log(predictions[np.arange(len(predictions)), y_pool])
        idxs = np.random.choice(len(predictions),
                                step,
                                replace=False,
                                p=errors / sum(errors))
    elif method == 'max_entropy':
        predictions = F.softmax(inferencer(images),
                                dim=1).detach().cpu().numpy()
        entropies = entropy(predictions)
        idxs = np.argsort(entropies)[::-1][:10]
        print(idxs)
    else:
        mask = build_mask(method)
        estimator = build_estimator('bald_masked',
                                    inferencer,
                                    dropout_mask=mask,
                                    num_classes=10,
                                    nn_runs=nn_runs)
        estimations = estimator.estimate(images)
        idxs = np.argsort(estimations)[::-1][:step]
        estimator.reset()

    x_add, y_add = np.copy(x_pool[idxs]), np.copy(y_pool[idxs])
    x_train = np.concatenate((x_train, x_add))
    y_train = np.concatenate((y_train, y_add))
    x_pool = np.delete(x_pool, idxs, axis=0)
    y_pool = np.delete(y_pool, idxs, axis=0)

    return x_pool, x_train, y_pool, y_train
Beispiel #19
0
def update_set(x_pool,
               x_train,
               y_pool,
               y_train,
               step,
               method='mc_dropout',
               model=None,
               nn_runs=100,
               task='classification',
               samples=None):

    if samples is None:
        device = 'cuda' if torch.cuda.is_available() else 'cpu'
        samples = torch.DoubleTensor(x_pool).to(device)

    if method == 'random':
        idxs = range(step)
    elif method == 'AL_dpp':
        mask = build_mask('mc_dropout')
        estimator = build_estimator('bald_masked',
                                    model,
                                    dropout_mask=mask,
                                    num_classes=10,
                                    keep_runs=True,
                                    nn_runs=nn_runs)
        estimator.estimate(samples)  # to generate mcd
        mcd = estimator.last_mcd_runs().reshape(-1, nn_runs * 10)
        dpp = FiniteDPP('likelihood', **{'L': np.corrcoef(mcd)})
        idxs = set()
        while len(idxs) < step:
            dpp.sample_exact()
            idxs.update(dpp.list_of_samples[-1])
        idxs = list(idxs)[:step]
    elif method == 'error_oracle':
        predictions = F.softmax(model(samples), dim=1).detach().cpu().numpy()
        errors = -np.log(predictions[np.arange(len(predictions)), y_pool])
        idxs = np.argsort(errors)[::-1][:step]
    elif method == 'stoch_oracle':
        predictions = F.softmax(model(samples), dim=1).detach().cpu().numpy()
        errors = -np.log(predictions[np.arange(len(predictions)), y_pool])
        idxs = np.random.choice(len(predictions),
                                step,
                                replace=False,
                                p=errors / sum(errors))
    elif method == 'max_entropy':
        predictions = F.softmax(model(samples), dim=1).detach().cpu().numpy()
        entropies = entropy(predictions)
        idxs = np.argsort(entropies)[::-1][:step]
    else:
        if task == 'classification':
            estimator = build_estimator('bald_masked',
                                        model,
                                        dropout_mask=method,
                                        num_classes=10,
                                        nn_runs=nn_runs)
        else:
            estimator = build_estimator('mcdue_masked',
                                        model,
                                        dropout_mask=method,
                                        nn_runs=nn_runs)
        estimations = estimator.estimate(samples)
        idxs = np.argsort(estimations)[::-1][:step]
        estimator.reset()

    x_add, y_add = np.copy(x_pool[idxs]), np.copy(y_pool[idxs])
    x_train = np.concatenate((x_train, x_add))
    y_train = np.concatenate((y_train, y_add))
    x_pool = np.delete(x_pool, idxs, axis=0)
    y_pool = np.delete(y_pool, idxs, axis=0)

    return x_pool, x_train, y_pool, y_train