예제 #1
0
    def compute_trajectory(self, random_start_state=None):
        logger.debug("Entering")

        if random_start_state is not None:
            np.random.set_state(random_start_state)
        else:
            random_start_state = np.random.get_state()

        # momentum
        L_p = np.linalg.cholesky(np.eye(self.D) * self.sigma_p)
        self.logp = lambda x: log_gaussian_pdf(
            x, Sigma=L_p, compute_grad=False, is_cholesky=True)
        self.dlogp = lambda x: log_gaussian_pdf(
            x, Sigma=L_p, compute_grad=True, is_cholesky=True)
        self.p_sample = lambda: sample_gaussian(
            N=1, mu=np.zeros(self.D), Sigma=L_p, is_cholesky=True)[0]

        # set up target and momentum densities and gradients
        self.set_up()

        dlogq_est = self.update_density_estimate()

        # random number of steps?
        if self.max_steps is not None:
            steps = np.random.randint(self.num_steps, self.max_steps + 1)
        else:
            steps = self.num_steps

        logger.info("Simulating trajectory for at least L=%d steps of size %.2f" % \
                     (self.num_steps, self.step_size))
        # starting state
        p0 = self.p_sample()
        q0 = self.q_sample()

        Qs, Ps = leapfrog(q0, self.dlogq, p0, self.dlogp, self.step_size,
                          steps)

        # run second integrator for same amount of steps
        steps_taken = len(Qs)
        Qs_est, Ps_est = leapfrog(q0, dlogq_est, p0, self.dlogp,
                                  self.step_size, steps_taken)
        logger.info("%d steps taken" % steps_taken)

        logger.info("Computing average acceptance probabilities")
        log_acc = compute_log_accept_pr(q0, p0, Qs, Ps, self.logq, self.logp)
        log_acc_est = compute_log_accept_pr(q0, p0, Qs_est, Ps_est, self.logq,
                                            self.logp)
        acc_mean = np.mean(np.exp(log_acc))
        acc_est_mean = np.mean(np.exp(log_acc_est))
        idx09 = int(len(log_acc) * 0.9)
        acc_mean10 = np.mean(np.exp(log_acc[idx09:]))
        acc_est_mean10 = np.mean(np.exp(log_acc_est[idx09:]))

        logger.info("Computing average volumes")
        log_det = compute_log_det_trajectory(Qs, Ps)
        log_det_est = compute_log_det_trajectory(Qs_est, Ps_est)

        logger.info("Average acceptance prob: %.2f, %.2f" %
                    (acc_mean, acc_est_mean))
        logger.info("Average acceptance prob (last 10 percent): %.2f, %.2f" %
                    (acc_mean10, acc_est_mean10))
        logger.info("Log-determinant: %.2f, %.2f" % (log_det, log_det_est))

        logger.debug("Leaving")
        return acc_mean, acc_est_mean, log_det, log_det_est, steps_taken, random_start_state
예제 #2
0
    def compute_trajectory(self, random_start_state=None):
        logger.debug("Entering")

        if random_start_state is not None:
            np.random.set_state(random_start_state)
        else:
            random_start_state = np.random.get_state()

        # momentum
        L_p = np.linalg.cholesky(np.eye(self.D) * self.sigma_p)
        self.logp = lambda x: log_gaussian_pdf(
            x, Sigma=L_p, compute_grad=False, is_cholesky=True)
        self.dlogp = lambda x: log_gaussian_pdf(
            x, Sigma=L_p, compute_grad=True, is_cholesky=True)
        self.p_sample = lambda: sample_gaussian(
            N=1, mu=np.zeros(self.D), Sigma=L_p, is_cholesky=True)[0]
        self.p_sample = lambda: sample_gaussian(
            N=1, mu=np.zeros(self.D), Sigma=L_p, is_cholesky=True)[0]

        # set up target and momentum densities and gradients
        self.set_up()

        logger.info("Learning kernel bandwidth")
        sigma = select_sigma_grid(self.Z, lmbda=self.lmbda, log2_sigma_max=15)
        logger.info("Using lmbda=%.2f, sigma: %.2f" % (self.lmbda, sigma))

        logger.info("Computing kernel matrix")
        K = gaussian_kernel(self.Z, sigma=sigma)

        logger.info("Estimate density in RKHS")
        b = _compute_b_sym(self.Z, K, sigma)
        C = _compute_C_sym(self.Z, K, sigma)
        a = score_matching_sym(self.Z, sigma, self.lmbda, K, b, C)

        #         logger.info("Computing objective function")
        #         J = _objective_sym(Z, sigma, self.lmbda, a, K, b, C)
        #         J_xval = np.mean(xvalidate(Z, 5, sigma, self.lmbda, K))
        #         logger.info("N=%d, sigma: %.2f, lambda: %.2f, J(a)=%.2f, XJ(a)=%.2f" % \
        #                 (self.N, sigma, self.lmbda, J, J_xval))

        kernel_grad = lambda x, X=None: gaussian_kernel_grad(x, X, sigma)
        dlogq_est = lambda x: log_pdf_estimate_grad(x, a, self.Z, kernel_grad)


        logger.info("Simulating trajectory for L=%d steps of size %.2f" % \
                     (self.num_steps, self.step_size))
        # starting state
        p0 = self.p_sample()
        q0 = self.q_sample()

        Qs, Ps = leapfrog(q0, self.dlogq, p0, self.dlogp, self.step_size,
                          self.num_steps, self.max_steps)

        # run second integrator for same amount of steps
        steps_taken = len(Qs)
        logger.info("%d steps taken" % steps_taken)
        Qs_est, Ps_est = leapfrog(q0, dlogq_est, p0, self.dlogp,
                                  self.step_size, steps_taken)

        logger.info("Computing average acceptance probabilities")
        log_acc = compute_log_accept_pr(q0, p0, Qs, Ps, self.logq, self.logp)
        log_acc_est = compute_log_accept_pr(q0, p0, Qs_est, Ps_est, self.logq,
                                            self.logp)
        acc_mean = np.mean(np.exp(log_acc))
        acc_est_mean = np.mean(np.exp(log_acc_est))

        logger.info("Computing average volumes")
        log_det = compute_log_det_trajectory(Qs, Ps)
        log_det_est = compute_log_det_trajectory(Qs_est, Ps_est)

        logger.info("Average acceptance prob: %.2f, %.2f" %
                    (acc_mean, acc_est_mean))
        logger.info("Log-determinant: %.2f, %.2f" % (log_det, log_det_est))

        logger.debug("Leaving")
        return acc_mean, acc_est_mean, log_det, log_det_est, steps_taken, random_start_state
예제 #3
0
# initial
samples[0] = q_current
samples_est[0] = q_current_est

# run MCMC
for i in np.arange(1, num_iterations):
    print("%d/%d" % (i + 1, num_iterations))
    # sample momentum
    p = p_sample()
    momentums[i] = p
    
    # simulate Hamiltonian flow, use last point as proposal
    num_steps = np.random.randint(num_steps_min, num_steps_max + 1)
    step_size = np.random.rand() * (step_size_max - step_size_min) + step_size_min
    Qs, Ps = leapfrog(q_current, dlogq, p, dlogp, step_size, num_steps)
    Qs_est, Ps_est = leapfrog(q_current_est, dlogq_est, p, dlogp, step_size, num_steps)
    proposals[i] = Qs[-1]
    proposals_est[i] = Qs_est[-1]
    
    # compute acceptance probability
    acc_prob[i] = np.exp(compute_log_accept_pr_single(q_current, p, Qs[-1], Ps[-1], logq, logp))
    acc_prob_est[i] = np.exp(compute_log_accept_pr_single(q_current_est, p, Qs_est[-1], Ps_est[-1], logq, logp))
    
    if False:
        # visualise trajectories and acceptance probability along
        plot_array(Xs, Ys, np.exp(G), plot_contour=False)
        plot_2d_trajectory(Qs, "r-")
        plot_2d_trajectory(Qs_est, "b-")
        plt.show()
    
예제 #4
0
    def propose(self, current, current_log_pdf, samples, accepted):
        # random variables from a fixed random stream without modifying the current one
        rnd_state = np.random.get_state()
        np.random.set_state(self.hmc_rnd_state)
         
        if current_log_pdf is None:
            current_log_pdf = self.orig_target.log_pdf(current)
         
        # sample momentum and leapfrog parameters
        p0 = self.momentum.sample()
        num_steps = np.random.randint(self.num_steps_min, self.num_steps_max + 1)
        step_size = np.random.rand() * (self.step_size_max - self.step_size_min) + self.step_size_min
         
        # restore random state
        self.hmc_rnd_state = np.random.get_state()
        np.random.set_state(rnd_state)
         
        logger.debug("Simulating Hamiltonian flow")
        Qs, Ps = leapfrog(current, self.target.grad, p0, self.momentum.grad, step_size, num_steps)
         
        q=Qs[-1]
        p=Ps[-1]
         
        logger.debug("Momentum start: %s" % str(p0))
        logger.debug("Momentum end: %s" % str(p))
         
        # compute acceptance probability, extracting log_pdf of q
        p0_log_pdf = self.momentum.log_pdf(p0)
        p_log_pdf = self.momentum.log_pdf(p)
         
        # use a function call to be able to overload it for KMC
        acc_prob, log_pdf_q = self.accept_prob_log_pdf(current, q, p0_log_pdf, p_log_pdf, current_log_pdf, samples)
         
        if True and (len(samples) % 100) ==0:
            logger.debug("Plotting")
            import matplotlib.pyplot as plt
             
            res = 50
            Xs_q = np.linspace(-4,4, res)
            Ys_q = np.linspace(-4,4, res)
         
            # evaluate density and estimate
            D1=0
            D2=1
            def dummy_grad(X_2d):
                theta = current.copy()
#                 theta = np.mean(self.Z, 0)
                theta[D1]=X_2d[0]
                theta[D2]=X_2d[1]
                return self.target.grad(theta)
                 
            def dummy(X_2d):
                theta = current.copy()
#                 theta = np.mean(self.Z, 0)
                theta[D1]=X_2d[0]
                theta[D2]=X_2d[1]
                return self.target.log_pdf(theta)
             
#             plt.figure()
#             G = evaluate_density_grid(Xs_q, Ys_q, dummy)
#             plot_array(Xs_q, Ys_q, G)
#             plt.plot(self.Z[:,D1], self.Z[:,D2], '.')
#             plt.plot(Qs[:,D1], Qs[:,D2], 'r-')
#             plt.plot(samples[:,D1], samples[:,D2], 'm-')
#             plt.plot(current[D1], current[D2], 'b*', markersize=15)
#             plt.plot(Qs[-1,D1], Qs[-1,D2], 'r*', markersize=15)
             
            plt.figure()
            G_norm, U_q, V, X, Y = evaluate_gradient_grid(Xs_q, Ys_q, dummy_grad)
            plot_array(Xs_q, Ys_q, G_norm)
            plt.plot(self.Z[:,D1], self.Z[:,D2], '.')
            plt.plot(Qs[:,D1], Qs[:,D2], 'r-')
            plt.plot(samples[:,D1], samples[:,D2], 'm-')
            plt.plot(current[D1], current[D2], 'b*', markersize=15)
            plt.plot(Qs[-1,D1], Qs[-1,D2], 'r*', markersize=15)
            plt.quiver(X, Y, U_q, V, color='m')
             
#             plt.figure()
#             plt.plot(Ps[:,D1], Ps[:,D2], 'r-')
#             plt.plot(p0[D1], p0[D2], 'b*', markersize=15)
#             plt.plot(Ps[-1,D1], Ps[-1,D2], 'r*', markersize=15)
#             plt.title('momentum')
             
            acc_probs = np.exp(compute_log_accept_pr(current, p0, Qs, Ps, self.orig_target.log_pdf, self.momentum.log_pdf))
            H_ratios = np.exp(compute_log_accept_pr(current, p0, Qs, Ps, self.target.log_pdf, self.momentum.log_pdf))
            target_ratio = [np.min([1,np.exp(self.orig_target.log_pdf(x)-current_log_pdf)]) for x in Qs]
            momentum_ratio = [np.min([1,np.exp(self.momentum.log_pdf(x)-p0_log_pdf)]) for x in Ps]
            target_log_pdf = np.exp(np.array([self.orig_target.log_pdf(x) for x in Qs]))
# #              
#             plt.figure(figsize=(12,4))
#             plt.subplot(151)
#             plt.plot(acc_probs)
#             plt.plot([0, len(acc_probs)], [acc_probs.mean(), acc_probs.mean()])
#             plt.title("acc_probs")
#             plt.subplot(152)
#             plt.plot(target_ratio)
#             plt.title("target_ratio")
#             plt.subplot(153)
#             plt.plot(momentum_ratio)
#             plt.title("momentum_ratio")
#             plt.subplot(154)
#             plt.plot(H_ratios)
#             plt.title("H_ratios")
#             plt.subplot(155)
#             plt.plot(target_log_pdf)
#             plt.title("target_log_pdf")
             
             
             
            plt.show()
        
        return q, acc_prob, log_pdf_q
예제 #5
0
def plot_kamiltonian_dnyamics(q0, p0, logq, dlogq, logq_est, dlogq_est,
                              logp, dlogp, Z=None, num_steps=500, step_size=.1,
                              Xs_q=None, Ys_q=None, Xs_p=None, Ys_p=None,
                              plot_dlogq=False, plot_H_or_acc=True):
    D = len(q0)
    
    # compute and plot log-density, if D==2
    plt.figure(figsize=(12, 12))

    if D is 2:
        if Xs_q is None:
            Xs_q = np.linspace(-3, 3)
        
        if Ys_q is None:
            Ys_q = np.linspace(-3, 3)
        
        if Xs_p is None:
            Xs_p = np.linspace(-3, 3)
        
        if Ys_p is None:
            Ys_p = np.linspace(-3, 3)
        
        if plot_dlogq:
            G = evaluate_density_grad_grid(Xs_q, Ys_q, dlogq)
            G_est = evaluate_density_grad_grid(Xs_q, Ys_q, dlogq_est)
        else:
            G = evaluate_density_grid(Xs_q, Ys_q, logq)
            G_est = evaluate_density_grid(Xs_q, Ys_q, logq_est)
            
        M = evaluate_density_grid(Xs_p, Ys_p, logp)
        M_est = evaluate_density_grid(Xs_p, Ys_p, logp)
    
        plt.subplot(321)
        if not plot_dlogq:
            plot_array(Xs_q, Ys_q, np.exp(G))
        else:
            plot_array(Xs_q, Ys_q, G)
            
        if Z is not None:
            plt.plot(Z[:, 0], Z[:, 1], 'bx')
            
        plt.subplot(322)
        plot_array(Xs_q, Ys_q, np.exp(G_est))
        if Z is not None:
            plt.plot(Z[:, 0], Z[:, 1], 'bx')
        
        plt.subplot(323)
        plot_array(Xs_p, Ys_p, np.exp(M))
        plt.subplot(324)
        plot_array(Xs_p, Ys_p, np.exp(M_est))
    
    Qs, Ps = leapfrog(q0, dlogq, p0, dlogp, step_size, num_steps)
    Qs_est, Ps_est = leapfrog(q0, dlogq_est, p0, dlogp, step_size, num_steps)
    Hs = compute_hamiltonian(Qs, Ps, logq, logp)
    Hs_est = compute_hamiltonian(Qs_est, Ps_est, logq, logp)
    
    log_acc = compute_log_accept_pr(q0, p0, Qs, Ps, logq, logp)
    log_acc_est = compute_log_accept_pr(q0, p0, Qs_est, Ps_est, logq, logp)
    acc_mean = np.mean(np.exp(log_acc))
    acc_est_mean = np.mean(np.exp(log_acc_est))
    logger.info("HMC acceptance prob: %.2f" % acc_mean)
    logger.info("KMC acceptance prob: %.2f" % acc_est_mean)

    spread = compute_log_det_trajectory(Qs, Ps)
    spread_est = compute_log_det_trajectory(Qs_est, Ps_est)
    logger.info("HMC spread: %.2f" % (spread))
    logger.info("KMC spread: %.2f" % (spread_est))
    
    plt.subplot(321)
    plot_2d_trajectory(Qs)
    plt.title("True density")
    plt.subplot(322)
    plot_2d_trajectory(Qs_est)
    plt.title("Estimated density")
    
    plt.subplot(323)
    plt.title("Momentum")
    plot_2d_trajectory(Ps)
    plt.subplot(324)
    plt.title("Momentum")
    plot_2d_trajectory(Ps_est)
    
    if plot_H_or_acc:
        ylim = [np.min([Hs.min(), Hs_est.min()]),
                np.max([Hs.max(), Hs_est.max()])]
            
        plt.subplot(325)
        plt.title("Hamiltonian")
        plt.plot(Hs)
        plt.ylim(ylim)
        plt.gca().get_yaxis().get_major_formatter().set_useOffset(False)
        
        plt.subplot(326)
        plt.title("Hamiltonian")
        plt.plot(Hs_est)
        plt.ylim(ylim)
        plt.gca().get_yaxis().get_major_formatter().set_useOffset(False)
    else:
        plt.subplot(325)
        plt.title("Acceptance prob.")
        plt.plot(np.exp(log_acc))
        plt.plot([0,len(log_acc)], [acc_mean, acc_mean], "r")
        plt.gca().get_yaxis().get_major_formatter().set_useOffset(False)
        
        plt.subplot(326)
        plt.title("Acceptance prob.")
        plt.plot(np.exp(log_acc_est))
        plt.plot([0,len(log_acc_est)], [acc_est_mean, acc_est_mean], "r")
        plt.gca().get_yaxis().get_major_formatter().set_useOffset(False)
        
    plt.tight_layout()
예제 #6
0
    # plotting grid
    res = 200
    Xs_q = np.linspace(-3, 3, res)
    Ys_q = np.linspace(-3, 3, res)
    Xs_p = np.linspace(-1, 1, res)
    Ys_p = np.linspace(-1, 1, res)

    # evaluate density and estimate
    G = evaluate_density_grid(Xs_q, Ys_q, logq)
    G_est = evaluate_density_grid(Xs_q, Ys_q, logq_est)

    # evaluate momentum, which is the same for both
    M = evaluate_density_grid(Xs_p, Ys_p, logp)

    # simulate true and approximate Hamiltonian
    Qs, Ps = leapfrog(q0, dlogq, p0, dlogp, step_size, num_steps)
    Qs_est, Ps_est = leapfrog(q0, dlogq_est, p0, dlogp, step_size, num_steps)
    Hs = compute_hamiltonian(Qs, Ps, logq, logp)
    Hs_est = compute_hamiltonian(Qs_est, Ps_est, logq, logp)

    # compute acceptance probabilities
    log_acc = compute_log_accept_pr(q0, p0, Qs, Ps, logq, logp)
    log_acc_est = compute_log_accept_pr(q0, p0, Qs_est, Ps_est, logq, logp)

    # normalise Hamiltonians
    Hs -= Hs.mean()
    Hs_est -= Hs_est.mean()

    plt.figure()
    plot_array(Xs_q, Ys_q, np.exp(G))
    plot_2d_trajectory(Qs)