def generate_initialization(distribution): """ Run mjhmc for BURN_IN_STEPS on distribution, generating a fair set of initial states :param distribution: Distribution object. Must have nbatch == MAX_N_PARTICLES :returns: a set of fair initial states and an estimate of the variance for emc and true both :rtype: tuple: (array of shape (distribution.ndims, MAX_N_PARTICLES), float, float) """ print('Generating fair initialization for {} by burning in {} steps'.format( type(distribution).__name__, BURN_IN_STEPS)) assert BURN_IN_STEPS > VAR_STEPS assert distribution.nbatch == MAX_N_PARTICLES mjhmc = MarkovJumpHMC(distribution=distribution, resample=False) for _ in xrange(BURN_IN_STEPS - VAR_STEPS): mjhmc.sampling_iteration() assert mjhmc.resample == False emc_var_estimate, mjhmc = online_variance(mjhmc, distribution) # we discard v since p(x,v) = p(x)p(v) fair_x = mjhmc.state.copy().X # otherwise will go into recursive loop distribution.mjhmc = False control = ControlHMC(distribution=distribution.reset()) for _ in xrange(BURN_IN_STEPS - VAR_STEPS): control.sampling_iteration() true_var_estimate, control = online_variance(control, distribution) return (fair_x, emc_var_estimate, true_var_estimate)
def sampler_speedometer(): """ Tests average sample speed of different samplers in different configurations :returns: Just prints info :rtype: None """ gaussian = Gaussian() np.random.seed(2015) pot = ProductOfT(ndims=36,nbasis=36) mjhmc_gauss = MarkovJumpHMC(distribution=gaussian) mjhmc_gauss_nr = MarkovJumpHMC(distribution=gaussian, resample=False) control_gauss = ControlHMC(distribution=gaussian) mjhmc_pot = MarkovJumpHMC(distribution=pot) mjhmc_pot_nr = MarkovJumpHMC(distribution=pot, resample=False) control_pot = ControlHMC(distribution=pot) m_g_r_avg = time_per_sample(mjhmc_gauss) m_g_nr_avg = time_per_sample(mjhmc_gauss_nr) c_g_avg = time_per_sample(control_gauss) m_p_r_avg = time_per_sample(mjhmc_pot) m_p_nr_avg = time_per_sample(mjhmc_pot_nr) c_p_avg = time_per_sample(control_pot) print "Average times per samples..." print "resampled MJHMC numpy gradient: {}".format(m_g_r_avg) print "not resampled MJHMC numpy gradient: {}".format(m_g_nr_avg) print "control HMC numpy gradient: {}".format(c_g_avg) print "resampled MJHMC theano gradient: {}".format(m_p_r_avg) print "not resampled MJHMC theano gradient: {}".format(m_p_nr_avg) print "control HMC theano gradient: {}".format(c_p_avg)
def generate_figure_samples(samples_per_frame, n_frames, burnin = int(1e4)): """ Generates the figure :param samples_per_frame: number of sample steps between each frame :param n_frames: number of frames to draw :returns: None :rtype: None """ n_samples = samples_per_frame * n_frames ndims = 36 nbasis = 72 rand_val = rand(ndims,nbasis/2,density=0.25) W = np.concatenate([rand_val.toarray(), -rand_val.toarray()],axis=1) logalpha = np.random.randn(nbasis, 1) poe = ProductOfT(nbatch=1, W=W, logalpha=logalpha) ## NUTS uses a different number of grad evals for each update step!! ## makes it very hard to compare against others w/ same number of update steps # # NUTS # print "NUTS" # nuts_init = poe.Xinit[:, 0] # nuts_samples = nuts6(poe.reset(), n_samples, nuts_burnin, nuts_init)[0] # nuts_frames = [nuts_samples[f_idx * samples_per_frame, :] for f_idx in xrange(0, n_frames)] # x_init = nuts_samples[0, :].reshape(ndims, 1) ## burnin print "MJHMC burnin" x_init = poe.Xinit #[:, [0]] mjhmc = MarkovJumpHMC(distribution=poe.reset(), **mjhmc_params) mjhmc.state = HMCState(x_init.copy(), mjhmc) mjhmc_samples = mjhmc.sample(burnin) print mjhmc_samples.shape x_init = mjhmc_samples[:, [0]] # control HMC print "Control" hmc = ControlHMC(distribution=poe.reset(), **control_params) hmc.state = HMCState(x_init.copy(), hmc) hmc_samples = hmc.sample(n_samples) hmc_frames = [hmc_samples[:, f_idx * samples_per_frame].copy() for f_idx in xrange(0, n_frames)] # MJHMC print "MJHMC" mjhmc = MarkovJumpHMC(distribution=poe.reset(), resample=False, **mjhmc_params) mjhmc.state = HMCState(x_init.copy(), mjhmc) mjhmc_samples = mjhmc.sample(n_samples) mjhmc_frames = [mjhmc_samples[:, f_idx * samples_per_frame].copy() for f_idx in xrange(0, n_frames)] print mjhmc.r_count, hmc.r_count print mjhmc.l_count, hmc.l_count print mjhmc.f_count, hmc.f_count print mjhmc.fl_count, hmc.fl_count frames = [mjhmc_frames, hmc_frames] names = ['MJHMC', 'ControlHMC'] frame_grads = [f_idx * samples_per_frame for f_idx in xrange(0, n_frames)] return frames, names, frame_grads
def generate_figure_samples(samples_per_frame, n_frames, burnin=int(1e4)): """ Generates the figure :param samples_per_frame: number of sample steps between each frame :param n_frames: number of frames to draw :returns: None :rtype: None """ n_samples = samples_per_frame * n_frames ndims = 36 nbasis = 72 rand_val = rand(ndims, nbasis / 2, density=0.25) W = np.concatenate([rand_val.toarray(), -rand_val.toarray()], axis=1) logalpha = np.random.randn(nbasis, 1) poe = ProductOfT(nbatch=1, W=W, logalpha=logalpha) ## NUTS uses a different number of grad evals for each update step!! ## makes it very hard to compare against others w/ same number of update steps # # NUTS # print "NUTS" # nuts_init = poe.Xinit[:, 0] # nuts_samples = nuts6(poe.reset(), n_samples, nuts_burnin, nuts_init)[0] # nuts_frames = [nuts_samples[f_idx * samples_per_frame, :] for f_idx in xrange(0, n_frames)] # x_init = nuts_samples[0, :].reshape(ndims, 1) ## burnin print "MJHMC burnin" x_init = poe.Xinit # [:, [0]] mjhmc = MarkovJumpHMC(distribution=poe.reset(), **mjhmc_params) mjhmc.state = HMCState(x_init.copy(), mjhmc) mjhmc_samples = mjhmc.sample(burnin) print mjhmc_samples.shape x_init = mjhmc_samples[:, [0]] # control HMC print "Control" hmc = ControlHMC(distribution=poe.reset(), **control_params) hmc.state = HMCState(x_init.copy(), hmc) hmc_samples = hmc.sample(n_samples) hmc_frames = [hmc_samples[:, f_idx * samples_per_frame].copy() for f_idx in xrange(0, n_frames)] # MJHMC print "MJHMC" mjhmc = MarkovJumpHMC(distribution=poe.reset(), resample=False, **mjhmc_params) mjhmc.state = HMCState(x_init.copy(), mjhmc) mjhmc_samples = mjhmc.sample(n_samples) mjhmc_frames = [mjhmc_samples[:, f_idx * samples_per_frame].copy() for f_idx in xrange(0, n_frames)] print mjhmc.r_count, hmc.r_count print mjhmc.l_count, hmc.l_count print mjhmc.f_count, hmc.f_count print mjhmc.fl_count, hmc.fl_count frames = [mjhmc_frames, hmc_frames] names = ["MJHMC", "ControlHMC"] frame_grads = [f_idx * samples_per_frame for f_idx in xrange(0, n_frames)] return frames, names, frame_grads
def generate_initialization(distribution): """ Run mjhmc for BURN_IN_STEPS on distribution, generating a fair set of initial states :param distribution: Distribution object. Must have nbatch == MAX_N_PARTICLES :returns: a set of fair initial states and an estimate of the variance for emc and true both :rtype: tuple: (array of shape (distribution.ndims, MAX_N_PARTICLES), float, float) """ print( 'Generating fair initialization for {} by burning in {} steps'.format( type(distribution).__name__, BURN_IN_STEPS)) assert BURN_IN_STEPS > VAR_STEPS # must rebuild graph to nbatch=MAX_N_PARTICLES if distribution.backend == 'tensorflow': distribution.build_graph() mjhmc = MarkovJumpHMC(distribution=distribution, resample=False) for _ in xrange(BURN_IN_STEPS - VAR_STEPS): mjhmc.sampling_iteration() assert mjhmc.resample == False emc_var_estimate, mjhmc = online_variance(mjhmc, distribution) # we discard v since p(x,v) = p(x)p(v) mjhmc_endpt = mjhmc.state.copy().X # otherwise will go into recursive loop distribution.mjhmc = False try: distribution.gen_init_X() except NotImplementedError: print("No explicit init method found, using mjhmc endpoint") distribution.E_count = 0 distribution.dEdX_count = 0 control = ControlHMC(distribution=distribution) for _ in xrange(BURN_IN_STEPS - VAR_STEPS): control.sampling_iteration() true_var_estimate, control = online_variance(control, distribution) control_endpt = control.state.copy().X return mjhmc_endpt, emc_var_estimate, true_var_estimate, control_endpt
def generate_initialization(distribution): """ Run mjhmc for BURN_IN_STEPS on distribution, generating a fair set of initial states :param distribution: Distribution object. Must have nbatch == MAX_N_PARTICLES :returns: a set of fair initial states and an estimate of the variance for emc and true both :rtype: tuple: (array of shape (distribution.ndims, MAX_N_PARTICLES), float, float) """ print('Generating fair initialization for {} by burning in {} steps'.format( type(distribution).__name__, BURN_IN_STEPS)) assert BURN_IN_STEPS > VAR_STEPS # must rebuild graph to nbatch=MAX_N_PARTICLES if distribution.backend == 'tensorflow': distribution.build_graph() mjhmc = MarkovJumpHMC(distribution=distribution, resample=False) for _ in xrange(BURN_IN_STEPS - VAR_STEPS): mjhmc.sampling_iteration() assert mjhmc.resample == False emc_var_estimate, mjhmc = online_variance(mjhmc, distribution) # we discard v since p(x,v) = p(x)p(v) mjhmc_endpt = mjhmc.state.copy().X # otherwise will go into recursive loop distribution.mjhmc = False try: distribution.gen_init_X() except NotImplementedError: print("No explicit init method found, using mjhmc endpoint") distribution.E_count = 0 distribution.dEdX_count = 0 control = ControlHMC(distribution=distribution) for _ in xrange(BURN_IN_STEPS - VAR_STEPS): control.sampling_iteration() true_var_estimate, control = online_variance(control, distribution) control_endpt = control.state.copy().X return mjhmc_endpt, emc_var_estimate, true_var_estimate, control_endpt
def ladder_numerical_err_hist(distr=None, n_steps=int(1e5)): """ Compute a histogram of the numerical integration error on the state ladder. Implicitly assumes that such a distribution exists and is shared by all ladders Args: distr: distribution object to run on, make sure n_batch is big Returns: energies = {E(L^j \zeta) : j \in {0, ..., k}}^{n_batch} run_lengths: list of observed ladder sizes """ distr = distr or Gaussian(nbatch=1) sampler = ControlHMC(distribution=distr) # [[ladder_energies]] energies = [] run_lengths = [] r_counts = [0] ladder_energies = [np.squeeze(sampler.state.H())] run_length = 0 for _ in range(n_steps): if sampler.r_count == r_counts[-1]: run_length += 1 ladder_energies.append(np.squeeze(sampler.state.H())) else: run_lengths.append(run_length) run_length = 0 energies.append(np.array(ladder_energies)) ladder_energies = [np.squeeze(sampler.state.H())] r_counts.append(sampler.r_count) sampler.sampling_iteration() centered_energies = [] for ladder_energies in energies: centered_energies += list(ladder_energies - ladder_energies[0]) return centered_energies, run_lengths