Example #1
0
 def grad_multiple(self, X):
     X_centered = X - self.mu
     return np.array([
         log_gaussian_pdf(x,
                          Sigma=self.L,
                          is_cholesky=True,
                          compute_grad=True) for x in X_centered
     ])
Example #2
0
def log_prior_log_pdf(x):
    D = len(x)
    return log_gaussian_pdf(x, mu=0. * np.ones(D), Sigma=np.eye(D) * 5)
Example #3
0
 def grad(self, x):
     return log_gaussian_pdf(x - self.mu,
                             Sigma=self.L,
                             is_cholesky=True,
                             compute_grad=True)
Example #4
0
def compute_avg_acceptance(q0,
                           logq,
                           dlogq,
                           sigma_p,
                           num_steps,
                           step_size,
                           plot=False,
                           X=None,
                           est=None,
                           plot_i=None,
                           plot_j=None,
                           ax=None,
                           plot_only_trajectory=False):
    """
    Computes HMC trajectory using provided gradient handle, and computes acceptance
    rate using provided log_pdf handle.
    
    HMC momentum is an isotropic Gaussian with specified variance.
    
    @param q0 starting state
    @param logq log_pdf handle
    @param dlogq gradient of log_pdf handle
    @param sigma_p standard deviation momentium
    @param num_steps number of leapfrog steps
    @param step_size step size in leapfrog integrator
    @param plot visualise trajectory (all following parameters need to be provided)
    """

    D = len(q0)

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

    # starting state
    p0 = p_sample()

    # integrate HMC trajectory
    logger.info("Simulating trajectory for L=%d steps of size %.2f" % \
                     (num_steps, step_size))
    Qs, Ps = leapfrog(q0, dlogq, p0, dlogp, step_size, num_steps)

    # compute average acceptance probabilities (using true log_pdf, not estimated one)
    logger.info("Computing average acceptance probabilities")
    log_acc = compute_log_accept_pr(q0, p0, Qs, Ps, logq, logp)
    acc_mean = np.exp(log_mean_exp(log_acc))

    if plot:
        import matplotlib.pyplot as plt
        if ax is None:
            fig = plt.figure(figsize=(16, 4))
            ax = fig.add_subplot(111)

        x_min = np.min([np.min(Qs[:, plot_i]), np.min(X[:, plot_i])])
        x_max = np.max([np.max(Qs[:, plot_i]), np.max(X[:, plot_i])])
        y_min = np.min([np.min(Qs[:, plot_j]), np.min(X[:, plot_j])])
        y_max = np.max([np.max(Qs[:, plot_j]), np.max(X[:, plot_j])])
        if not plot_only_trajectory:
            # build grid that covers trajectory and data
            Xs = np.linspace(x_min, x_max)
            Ys = np.linspace(y_min, y_max)
            XX, YY = np.meshgrid(Xs, Ys)
            X_grid = np.array([XX.ravel(), YY.ravel()]).T

            # compute estimated gradients on grid
            grad_grid = est.grad(X_grid)
            grad_grid_norm = np.linalg.norm(grad_grid, axis=1)

            visualise_array_2d(Xs,
                               Ys,
                               grad_grid_norm.reshape(len(Ys), len(Xs)).T,
                               samples=X,
                               ax=ax)
        else:
            ax.plot(X[:, plot_i], X[:, plot_j], 'b.')
        ax.plot(Qs[:, plot_i], Qs[:, plot_j], 'r-')
        ax.set_xlim([x_min, x_max])
        ax.set_ylim([y_min, y_max])
        ax.plot(q0[plot_i], q0[plot_j], "r*", markersize=15)
        ax.plot(Qs[-1, plot_i], Qs[-1, plot_j], "b*", markersize=15)
        ax.set_title(
            "Estimated gradient of log-density and HMC trajectory from random data point"
        )
        ax.set_xlabel("Component %d" % plot_i)
        ax.set_ylabel("Component %d" % plot_j)
        plt.show()

    return acc_mean