def _build_prior(self, inputsize, hiddendict, outputsize, scope='prior', Wpriorsigma=None, bpriorsigma=None): W, b = {}, {} Wshape, bshape = [], [] with tf.variable_scope(scope): layerdict = [inputsize] + hiddendict + [outputsize] i = 0 if Wpriorsigma is None: Wpriorsigma = (len(layerdict) - 1) * [0.1] if bpriorsigma is None: bpriorsigma = (len(layerdict) - 1) * [0.1] for h1, h2 in zip(layerdict[:-1], layerdict[1:]): #W[i] = Normal(loc=tf.zeros([h1,h2]),scale=Wpriorsigma[i]*tf.ones([h1,h2])) #b[i] = Normal(loc=tf.zeros(h2),scale=bpriorsigma[i]*tf.ones(h2)) W[i] = Uniform(low=tf.ones([h1, h2]) * (-10000), high=tf.ones([h1, h2]) * 10000) b[i] = Uniform(low=tf.ones(h2) * (-10000), high=tf.ones(h2) * 10000) Wshape.append([h1, h2]) bshape.append([h2]) i += 1 self.W = W self.b = b self.Wshape = Wshape self.bshape = bshape
def recommend_new_user(self, input_user_stack, k=config.K): """Implement the 'fold-in' logic. Calculates user factors for a new user and adds the user to the user matrix to make prediction. """ # initializing parameters _logger.info( "Could not find a match, calculating factors to recommend.") k_shp = a_c + k * a # TODO: t_shp, Why is it not required here? nY = len(input_user_stack) Y = np.ones(shape=(nY, )) seed = np.random.seed(int(time.time())) theta = Gamma(a, 1 / b_c).sample(sample_shape=(k, ), seed=seed).eval(session=tf.Session()) k_rte = b_c + np.sum(theta) gamma_rte = \ Gamma(a_c, b_c / a_c).sample( sample_shape=(1,), seed=seed).eval(session=tf.Session()) + self.beta.sum(axis=0) gamma_shp = \ gamma_rte * theta * \ Uniform(low=.85, high=1.15).sample( sample_shape=(k,), seed=seed).eval(session=tf.Session()) np.nan_to_num(gamma_shp, copy=False) np.nan_to_num(gamma_rte, copy=False) phi = np.empty((nY, k), dtype='float32') add_k_rte = a_c / b_c theta_prev = theta.copy() # running the loop for iter_num in range(iter_score): for i in range(nY): iid = input_user_stack[i] sumphi = 10e-6 maxval = -10**1 phi_st = i for j in range(k): phi[phi_st, j] = psi(gamma_shp[j]) - log(gamma_rte[j]) + psi( self.lam_shp[iid, j]) - log(self.lam_rte[iid, j]) if phi[phi_st, j] > maxval: maxval = phi[phi_st, j] for j in range(k): phi[phi_st, j] = exp(phi[phi_st, j] - maxval) sumphi += phi[phi_st, j] for j in range(k): phi[phi_st, j] *= Y[i] / sumphi gamma_rte = (k_shp / k_rte + self.beta.sum(axis=0, keepdims=True)).reshape(-1) gamma_shp = a + phi.sum(axis=0) theta = gamma_shp / gamma_rte k_rte = add_k_rte + theta.sum() # checking for early stop if np.linalg.norm(theta - theta_prev) < stop_thr: break theta_prev = theta.copy() rec = np.dot(theta, self.beta.T) return self.filter_recommendation(rec, input_user_stack)
def build_update(self): """Simulate Hamiltonian dynamics using a numerical integrator. Correct for the integrator's discretization error using an acceptance ratio. #### Notes The updates assume each Empirical random variable is directly parameterized by `tf.Variable`s. """ old_sample = {z: tf.gather(qz.params, tf.maximum(self.t - 1, 0)) for z, qz in six.iteritems(self.latent_vars)} old_sample = OrderedDict(old_sample) # Sample momentum. old_r_sample = OrderedDict() for z, qz in six.iteritems(self.latent_vars): event_shape = qz.event_shape normal = Normal(loc=tf.zeros(event_shape), scale=tf.ones(event_shape)) old_r_sample[z] = normal.sample() # Simulate Hamiltonian dynamics. new_sample, new_r_sample = leapfrog(old_sample, old_r_sample, self.step_size, self._log_joint, self.n_steps) # Calculate acceptance ratio. ratio = tf.reduce_sum([0.5 * tf.reduce_sum(tf.square(r)) for r in six.itervalues(old_r_sample)]) ratio -= tf.reduce_sum([0.5 * tf.reduce_sum(tf.square(r)) for r in six.itervalues(new_r_sample)]) ratio += self._log_joint(new_sample) ratio -= self._log_joint(old_sample) # Accept or reject sample. u = Uniform().sample() accept = tf.log(u) < ratio sample_values = tf.cond(accept, lambda: list(six.itervalues(new_sample)), lambda: list(six.itervalues(old_sample))) if not isinstance(sample_values, list): # `tf.cond` returns tf.Tensor if output is a list of size 1. sample_values = [sample_values] sample = {z: sample_value for z, sample_value in zip(six.iterkeys(new_sample), sample_values)} # Update Empirical random variables. assign_ops = [] for z, qz in six.iteritems(self.latent_vars): variable = qz.get_variables()[0] assign_ops.append(tf.scatter_update(variable, self.t, sample[z])) # Increment n_accept (if accepted). assign_ops.append(self.n_accept.assign_add(tf.where(accept, 1, 0))) return tf.group(*assign_ops)
def generative_adversarial_network_example(): ed.set_seed(42) data_dir = '/tmp/data' out_dir = '/tmp/out' if not os.path.exists(out_dir): os.makedirs(out_dir) M = 128 # Batch size during training. d = 100 # Latent dimension. (x_train, _), (x_test, _) = mnist(data_dir) x_train_generator = generator(x_train, M) x_ph = tf.placeholder(tf.float32, [M, 784]) #-------------------- # GANs posit generative models using an implicit mechanism. # Given some random noise, the data is assumed to be generated by a deterministic function of that noise. with tf.variable_scope('Gen'): eps = Uniform(tf.zeros([M, d]) - 1.0, tf.ones([M, d])) x = generative_network(eps) #-------------------- # In Edward, the GAN algorithm (GANInference) simply takes the implicit density model on x as input, binded to its realizations x_ph. # In addition, a parameterized function discriminator is provided to distinguish their samples. inference = ed.GANInference(data={x: x_ph}, discriminator=discriminative_network) # We'll use ADAM as optimizers for both the generator and discriminator. # We'll run the algorithm for 15,000 iterations and print progress every 1,000 iterations. optimizer = tf.train.AdamOptimizer() optimizer_d = tf.train.AdamOptimizer() inference = ed.GANInference(data={x: x_ph}, discriminator=discriminative_network) inference.initialize(optimizer=optimizer, optimizer_d=optimizer_d, n_iter=15000, n_print=1000) # We now form the main loop which trains the GAN. # At each iteration, it takes a minibatch and updates the parameters according to the algorithm. sess = ed.get_session() tf.global_variables_initializer().run() idx = np.random.randint(M, size=16) i = 0 for t in range(inference.n_iter): if t % inference.n_print == 0: samples = sess.run(x) samples = samples[idx, ] fig = plot(samples) plt.savefig(os.path.join(out_dir, '{}.png').format(str(i).zfill(3)), bbox_inches='tight') plt.close(fig) i += 1 x_batch = next(x_train_generator) info_dict = inference.update(feed_dict={x_ph: x_batch}) inference.print_progress(info_dict)
def build_update(self): """ Simulate Hamiltonian dynamics using a numerical integrator. Correct for the integrator's discretization error using an acceptance ratio. """ old_sample = {z: tf.gather(qz.params, tf.maximum(self.t - 1, 0)) for z, qz in six.iteritems(self.latent_vars)} # Sample momentum. old_r_sample = {} for z, qz in six.iteritems(self.latent_vars): event_shape = qz.get_event_shape() normal = Normal(mu=tf.zeros(event_shape), sigma=tf.ones(event_shape)) old_r_sample[z] = normal.sample() # Simulate Hamiltonian dynamics. new_sample = old_sample new_r_sample = old_r_sample for _ in range(self.n_steps): new_sample, new_r_sample = leapfrog(old_sample, old_r_sample, self.step_size, self.log_joint) # Calculate acceptance ratio. ratio = tf.reduce_sum([0.5 * tf.square(r) for r in six.itervalues(old_r_sample)]) ratio -= tf.reduce_sum([0.5 * tf.square(r) for r in six.itervalues(new_r_sample)]) ratio += self.log_joint(new_sample) ratio -= self.log_joint(old_sample) # Accept or reject sample. u = Uniform().sample() accept = tf.log(u) < ratio sample_values = tf.cond(accept, lambda: list(six.itervalues(new_sample)), lambda: list(six.itervalues(old_sample))) if not isinstance(sample_values, list): # ``tf.cond`` returns tf.Tensor if output is a list of size 1. sample_values = [sample_values] sample = {z: sample_value for z, sample_value in zip(six.iterkeys(new_sample), sample_values)} # Update Empirical random variables. assign_ops = [] variables = {x.name: x for x in tf.get_default_graph().get_collection(tf.GraphKeys.VARIABLES)} for z, qz in six.iteritems(self.latent_vars): variable = variables[qz.params.op.inputs[0].op.inputs[0].name] assign_ops.append(tf.scatter_update(variable, self.t, sample[z])) # Increment n_accept (if accepted). assign_ops.append(self.n_accept.assign_add(tf.select(accept, 1, 0))) return tf.group(*assign_ops)
def main(_): ed.set_seed(42) # DATA. MNIST batches are fed at training time. (x_train, _), (x_test, _) = mnist(FLAGS.data_dir) x_train_generator = generator(x_train, FLAGS.M) x_ph = tf.placeholder(tf.float32, [FLAGS.M, 784]) # MODEL with tf.variable_scope("Gen"): eps = Uniform(low=tf.zeros([FLAGS.M, FLAGS.d]) - 1.0, high=tf.ones([FLAGS.M, FLAGS.d])) x = generative_network(eps) # INFERENCE optimizer = tf.train.RMSPropOptimizer(learning_rate=5e-5) optimizer_d = tf.train.RMSPropOptimizer(learning_rate=5e-5) inference = ed.WGANInference( data={x: x_ph}, discriminator=discriminative_network) inference.initialize( optimizer=optimizer, optimizer_d=optimizer_d, n_iter=15000, n_print=1000, clip=0.01, penalty=None) sess = ed.get_session() tf.global_variables_initializer().run() idx = np.random.randint(FLAGS.M, size=16) i = 0 for t in range(inference.n_iter): if t % inference.n_print == 0: samples = sess.run(x) samples = samples[idx, ] fig = plot(samples) plt.savefig(os.path.join(FLAGS.out_dir, '{}.png').format( str(i).zfill(3)), bbox_inches='tight') plt.close(fig) i += 1 x_batch = next(x_train_generator) for _ in range(5): inference.update(feed_dict={x_ph: x_batch}, variables="Disc") info_dict = inference.update(feed_dict={x_ph: x_batch}, variables="Gen") # note: not printing discriminative objective; `info_dict` above # does not store it since updating only "Gen" info_dict['t'] = info_dict['t'] // 6 # say set of 6 updates is 1 iteration inference.print_progress(info_dict)
def build_loss_and_gradients(self, var_list): x_true = list(six.itervalues(self.data))[0] x_fake = list(six.iterkeys(self.data))[0] with tf.variable_scope("Disc"): d_true = self.discriminator(x_true) with tf.variable_scope("Disc", reuse=True): d_fake = self.discriminator(x_fake) if self.penalty is None or self.penalty == 0: penalty = 0.0 else: eps = Uniform().sample(x_true.shape[0]) while eps.shape.ndims < x_true.shape.ndims: eps = tf.expand_dims(eps, -1) x_interpolated = eps * x_true + (1.0 - eps) * x_fake with tf.variable_scope("Disc", reuse=True): d_interpolated = self.discriminator(x_interpolated) gradients = tf.gradients(d_interpolated, [x_interpolated])[0] slopes = tf.sqrt( tf.reduce_sum(tf.square(gradients), list(range(1, gradients.shape.ndims)))) penalty = self.penalty * tf.reduce_mean(tf.square(slopes - 1.0)) reg_terms_d = tf.losses.get_regularization_losses(scope="Disc") reg_terms_all = tf.losses.get_regularization_losses() reg_terms = [r for r in reg_terms_all if r not in reg_terms_d] mean_true = tf.reduce_mean(d_true) mean_fake = tf.reduce_mean(d_fake) loss_d = mean_fake - mean_true + penalty + tf.reduce_sum(reg_terms_d) loss = -mean_fake + tf.reduce_sum(reg_terms) var_list_d = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope="Disc") if var_list is None: var_list = [ v for v in tf.trainable_variables() if v not in var_list_d ] grads_d = tf.gradients(loss_d, var_list_d) grads = tf.gradients(loss, var_list) grads_and_vars_d = list(zip(grads_d, var_list_d)) grads_and_vars = list(zip(grads, var_list)) return loss, grads_and_vars, loss_d, grads_and_vars_d
import edward as ed from edward.models import Bernoulli, Beta, Uniform import tensorflow as tf import matplotlib.pyplot as plt import numpy as np # D = np.array([1, 0, 0, 1, 0, 0, 0, 1, 0, 0]) D = np.concatenate([np.zeros(70), np.ones(30)]) p = Uniform(0., 1.) ed_beta_binomial = Bernoulli(probs=p, sample_shape=len(D)) qp = Beta(concentration1=tf.nn.softplus(tf.get_variable("alpha", [])), concentration0=tf.nn.softplus(tf.get_variable("beta", [])) ) inference = ed.KLqp({p: qp}, {ed_beta_binomial: D}) inference.run(n_iter=1000) plt.hist(qp.sample(10000).eval(), bins=200) plt.show()
DATA_DIR = "data/mnist" IMG_DIR = "img" if not os.path.exists(DATA_DIR): os.makedirs(DATA_DIR) if not os.path.exists(IMG_DIR): os.makedirs(IMG_DIR) # DATA. MNIST batches are fed at training time. mnist = input_data.read_data_sets(DATA_DIR, one_hot=True) x_ph = tf.placeholder(tf.float32, [M, 784]) # MODEL with tf.variable_scope("Gen"): eps = Uniform(a=tf.zeros([M, d]) - 1.0, b=tf.ones([M, d])) x = generative_network(eps) # INFERENCE optimizer = tf.train.AdamOptimizer() optimizer_d = tf.train.AdamOptimizer() inference = ed.GANInference(data={x: x_ph}, discriminator=discriminative_network) inference.initialize(optimizer=optimizer, optimizer_d=optimizer_d, n_iter=15000, n_print=1000) sess = ed.get_session() tf.global_variables_initializer().run()
plt.ylabel('estimated weigths') plt.text(plt.xlim()[0]+.05, plt.ylim()[1]-.05, r'$\rho$: ' + str(pearsonr(Cb.flatten(), C.flatten())[0])) #%% try VI with Edward import edward as ed import tensorflow as tf from edward.models import Normal, InverseGamma, PointMass, Uniform # simulate data d = 50 T = 300 X, C, S = MOU_sim(N=d, Sigma=None, mu=0, T=T, connectivity_strength=8.) # the model mu = Uniform(low=tf.ones([d])*-1, high=tf.ones([d])*1) # Normal(loc=tf.zeros([d]), scale=10.*tf.ones([d])) beta = Uniform(low=tf.ones([d, d])*-20, high=tf.ones([d, d])*20) # Normal(loc=tf.zeros([d, d]), scale=2.*tf.ones([d,d])) noise_proc = tf.constant(0.1) # InverseGamma(alpha=1.0, beta=1.0) noise_obs = tf.constant(0.1) # InverseGamma(alpha=1.0, beta=1.0) x = [0] * T x[0] = Normal(loc=mu, scale=10.*tf.ones([d])) for n in range(1, T): x[n] = Normal(loc=mu + tf.tensordot(beta, x[n-1], axes=[[1],[0]]), scale=noise_proc*tf.ones([d])) ## map inference #print("setting up distributions") #qmu = PointMass(params=tf.Variable(tf.zeros([d]))) #qbeta = PointMass(params=tf.Variable(tf.zeros([d,d]))) #print("constructing inference object")
import matplotlib as mpl mpl.use("Agg") # force Matplotlib backend to Agg # import edward and TensorFlow import edward as ed import tensorflow as tf from edward.models import Normal, Uniform, Empirical # import model and data from createdata import * # set the priors cmin = -10. # lower range of uniform distribution on c cmax = 10. # upper range of uniform distribution on c cp = Uniform(low=cmin, high=cmax) mmu = 0. # mean of Gaussian distribution on m msigma = 10. # standard deviation of Gaussian distribution on m mp = Normal(loc=mmu, scale=msigma) # set the likelihood containing the model y = Normal(loc=mp*x + cp, scale=sigma*tf.ones(len(data))) # set number of samples Nsamples = 2000 # final number of samples Ntune = 2000 # number of tuning samples # set parameters to infer qm = Empirical(params=tf.Variable(tf.zeros(Nsamples+Ntune))) qc = Empirical(params=tf.Variable(tf.zeros(Nsamples+Ntune)))
def _test(a, b, n): x = Uniform(a=a, b=b) val_est = get_dims(x.sample(n)) val_true = n + get_dims(a) assert val_est == val_true
matplotlib.use('TkAgg') from matplotlib import pyplot as plt from data import get_value, draw_sky import numpy as np import tensorflow as tf from edward.models import Normal, Uniform M = 300 # number of galaxies N = 3 # number of Dark Halos # (x, y) ~ Uniform([0, 0], [4200, 4200]) galaxies_pos = Uniform( a=np.full(shape=(M, 2), fill_value=0., dtype='float32'), b=np.full(shape=(M, 2), fill_value=4200., dtype='float32')) # (X, Y) ~ Uniform([0, 0], [4200, 4200]) halos_pos = Uniform( a=np.full(shape=(N, 2), fill_value=0., dtype='float32'), b=np.full(shape=(N, 2), fill_value=4200., dtype='float32')) # mass of the dark halos halos_mass = Uniform( a=np.full(shape=(N,), fill_value=40, dtype='float32'), b=np.full(shape=(N,), fill_value=180, dtype='float32') ) # ====== calculate the distance from galaxies to halos ====== # # tricky to calculate euclidean distance between 2 matrices but
def build_update(self): """Simulate Hamiltonian dynamics using a numerical integrator. Correct for the integrator's discretization error using an acceptance ratio. #### Notes The updates assume each Empirical random variable is directly parameterized by `tf.Variable`s. """ # Gather the initial state, transformed to unconstrained space. try: self.latent_vars_unconstrained except: raise ValueError( "This implementation of HMC requires that all " "variables have unconstrained support. Please " "initialize with auto_transform=True to ensure " "this. (if your variables already have unconstrained " "support then doing this is a no-op).") old_sample = { z_unconstrained: tf.gather(qz_unconstrained.params, tf.maximum(self.t - 1, 0)) for z_unconstrained, qz_unconstrained in six.iteritems( self.latent_vars_unconstrained) } old_sample = OrderedDict(old_sample) # Sample momentum. old_r_sample = OrderedDict() for z, qz in six.iteritems(self.latent_vars_unconstrained): event_shape = qz.event_shape normal = Normal(loc=tf.zeros(event_shape, dtype=qz.dtype), scale=tf.ones(event_shape, dtype=qz.dtype)) old_r_sample[z] = normal.sample() # Simulate Hamiltonian dynamics. new_sample, new_r_sample = leapfrog(old_sample, old_r_sample, self.step_size, self._log_joint_unconstrained, self.n_steps) # Calculate acceptance ratio. ratio = tf.reduce_sum([ 0.5 * tf.reduce_sum(tf.square(r)) for r in six.itervalues(old_r_sample) ]) ratio -= tf.reduce_sum([ 0.5 * tf.reduce_sum(tf.square(r)) for r in six.itervalues(new_r_sample) ]) ratio += self._log_joint_unconstrained(new_sample) ratio -= self._log_joint_unconstrained(old_sample) # Accept or reject sample. u = Uniform(low=tf.constant(0.0, dtype=ratio.dtype), high=tf.constant(1.0, dtype=ratio.dtype)).sample() accept = tf.log(u) < ratio sample_values = tf.cond(accept, lambda: list(six.itervalues(new_sample)), lambda: list(six.itervalues(old_sample))) if not isinstance(sample_values, list): # `tf.cond` returns tf.Tensor if output is a list of size 1. sample_values = [sample_values] sample = { z_unconstrained: sample_value for z_unconstrained, sample_value in zip(six.iterkeys(new_sample), sample_values) } # Update Empirical random variables. assign_ops = [] for z_unconstrained, qz_unconstrained in six.iteritems( self.latent_vars_unconstrained): variable = qz_unconstrained.get_variables()[0] assign_ops.append( tf.scatter_update(variable, self.t, sample[z_unconstrained])) # Increment n_accept (if accepted). assign_ops.append(self.n_accept.assign_add(tf.where(accept, 1, 0))) return tf.group(*assign_ops)
#グループ差無しの線形回帰 df = pd.read_csv("data-salary-2.txt") X_data = np.reshape(df.values[:, 0], (-1, 1)) Y_data = df.values[:, 1] N = X_data.shape[0] #データ数 ##モデル記述 #Y[n] ~ Y_base[n] + \epsilon #Y_base[n] ~ a + bX[n] #\epsilon ~ N(0,\sigma_Y) X = tf.placeholder(tf.float32, [N, 1]) a = Normal(mu=tf.zeros([1]), sigma=tf.ones([1]) * 500) b = Normal(mu=tf.zeros([1]), sigma=tf.ones([1]) * 500) sigma = Uniform(a=tf.ones([1]) * 1, b=tf.ones([1]) * 10) Y = Normal(mu=ed.dot(X, b) + a, sigma=sigma) #データ data = {X: X_data, Y: Y_data} ##推論(変分ベイズ) #qa = Normal(mu=tf.Variable(tf.random_normal([1])),\ # sigma=tf.nn.softplus(tf.Variable(tf.random_normal([1])))) #qb = Normal(mu=tf.Variable(tf.random_normal([1])),\ # sigma=tf.nn.softplus(tf.Variable(tf.random_normal([1])))) #qsigma = Normal(mu=tf.Variable(tf.random_normal([1])),\ # sigma=tf.nn.softplus(tf.Variable(tf.random_normal([1])))) #inference = ed.KLqp({a: qa, b: qb, sigma : qsigma}, data) #inference.run(n_samples=1, n_iter=10000)
DATA_DIR = "data/mnist" IMG_DIR = "img" if not os.path.exists(DATA_DIR): os.makedirs(DATA_DIR) if not os.path.exists(IMG_DIR): os.makedirs(IMG_DIR) # DATA. MNIST batches are fed at training time. mnist = input_data.read_data_sets(DATA_DIR) x_ph = tf.placeholder(tf.float32, [M, 784]) # MODEL with tf.variable_scope("Gen"): eps = Uniform(low=tf.zeros([M, d]) - 1.0, high=tf.ones([M, d])) x = generative_network(eps) # INFERENCE optimizer = tf.train.RMSPropOptimizer(learning_rate=5e-5) optimizer_d = tf.train.RMSPropOptimizer(learning_rate=5e-5) inference = ed.WGANInference(data={x: x_ph}, discriminator=discriminative_network) inference.initialize(optimizer=optimizer, optimizer_d=optimizer_d, n_iter=15000, n_print=1000, clip=0.01, penalty=None)
def build_update(self): """Draw sample from proposal conditional on last sample. Then accept or reject the sample based on the ratio, $\\text{ratio} = \log p(x, z^{\\text{new}}) - \log p(x, z^{\\text{old}}) + \log g(z^{\\text{new}} \mid z^{\\text{old}}) - \log g(z^{\\text{old}} \mid z^{\\text{new}})$ #### Notes The updates assume each Empirical random variable is directly parameterized by `tf.Variable`s. """ old_sample = {z: tf.gather(qz.params, tf.maximum(self.t - 1, 0)) for z, qz in six.iteritems(self.latent_vars)} old_sample = OrderedDict(old_sample) # Form dictionary in order to replace conditioning on prior or # observed variable with conditioning on a specific value. dict_swap = {} for x, qx in six.iteritems(self.data): if isinstance(x, RandomVariable): if isinstance(qx, RandomVariable): qx_copy = copy(qx, scope='conditional') dict_swap[x] = qx_copy.value() else: dict_swap[x] = qx dict_swap_old = dict_swap.copy() dict_swap_old.update(old_sample) base_scope = tf.get_default_graph().unique_name("inference") + '/' scope_old = base_scope + 'old' scope_new = base_scope + 'new' # Draw proposed sample and calculate acceptance ratio. new_sample = old_sample.copy() # copy to ensure same order ratio = 0.0 for z, proposal_z in six.iteritems(self.proposal_vars): # Build proposal g(znew | zold). proposal_znew = copy(proposal_z, dict_swap_old, scope=scope_old) # Sample znew ~ g(znew | zold). new_sample[z] = proposal_znew.value() # Increment ratio. ratio += tf.reduce_sum(proposal_znew.log_prob(new_sample[z])) dict_swap_new = dict_swap.copy() dict_swap_new.update(new_sample) for z, proposal_z in six.iteritems(self.proposal_vars): # Build proposal g(zold | znew). proposal_zold = copy(proposal_z, dict_swap_new, scope=scope_new) # Increment ratio. ratio -= tf.reduce_sum(proposal_zold.log_prob(dict_swap_old[z])) for z in six.iterkeys(self.latent_vars): # Build priors p(znew) and p(zold). znew = copy(z, dict_swap_new, scope=scope_new) zold = copy(z, dict_swap_old, scope=scope_old) # Increment ratio. ratio += tf.reduce_sum(znew.log_prob(dict_swap_new[z])) ratio -= tf.reduce_sum(zold.log_prob(dict_swap_old[z])) for x in six.iterkeys(self.data): if isinstance(x, RandomVariable): # Build likelihoods p(x | znew) and p(x | zold). x_znew = copy(x, dict_swap_new, scope=scope_new) x_zold = copy(x, dict_swap_old, scope=scope_old) # Increment ratio. ratio += tf.reduce_sum(x_znew.log_prob(dict_swap[x])) ratio -= tf.reduce_sum(x_zold.log_prob(dict_swap[x])) # Accept or reject sample. u = Uniform(low=tf.constant(0.0, dtype=ratio.dtype), high=tf.constant(1.0, dtype=ratio.dtype)).sample() accept = tf.log(u) < ratio sample_values = tf.cond(accept, lambda: list(six.itervalues(new_sample)), lambda: list(six.itervalues(old_sample))) if not isinstance(sample_values, list): # `tf.cond` returns tf.Tensor if output is a list of size 1. sample_values = [sample_values] sample = {z: sample_value for z, sample_value in zip(six.iterkeys(new_sample), sample_values)} # Update Empirical random variables. assign_ops = [] for z, qz in six.iteritems(self.latent_vars): variable = qz.get_variables()[0] assign_ops.append(tf.scatter_update(variable, self.t, sample[z])) # Increment n_accept (if accepted). assign_ops.append(self.n_accept.assign_add(tf.where(accept, 1, 0))) return tf.group(*assign_ops)
def build_update(self): """ Draw sample from proposal conditional on last sample. Then accept or reject the sample based on the ratio, ratio = log p(x, znew) - log p(x, zold) + log g(znew | zold) - log g(zold | znew) = sum_z [ log p(znew) - log p(zold) + log g(znew | zold) - log g(zold | znew) ] + sum_x [ log p(x | znew) - sum_x log p(x | zold) ] = sum_z [ log g(znew | zold) - log p(zold) ] + sum_z [ log p(znew) - log g(zold | znew) ] + sum_x [ log p(x | znew) - sum_x log p(x | zold) ] """ old_sample = {z: tf.gather(qz.params, tf.maximum(self.t - 1, 0)) for z, qz in six.iteritems(self.latent_vars)} # Draw proposed sample and calculate acceptance ratio. new_sample = {} ratio = 0.0 for z, proposal_z in six.iteritems(self.proposal_vars): # Build proposal g(znew | zold). proposal_znew = copy(proposal_z, old_sample, scope='proposal_znew') # Build prior p(zold). zold = copy(z, old_sample, scope='zold') # Sample znew ~ g(znew | zold). new_sample[z] = proposal_z.sample() # Increment ratio. ratio += tf.reduce_sum(proposal_znew.log_prob(new_sample[z])) if self.model_wrapper is None: ratio -= tf.reduce_sum(zold.log_prob(old_sample[z])) for z, proposal_z in six.iteritems(self.proposal_vars): # Build proposal p(zold | znew). proposal_zold = copy(proposal_z, new_sample, scope='proposal_zold') # Build prior p(znew). znew = copy(z, new_sample, scope='znew') # Increment ratio. ratio -= tf.reduce_sum(proposal_zold.log_prob(old_sample[z])) if self.model_wrapper is None: ratio += tf.reduce_sum(znew.log_prob(new_sample[z])) if self.model_wrapper is None: for x, obs in six.iteritems(self.data): if isinstance(x, RandomVariable): # Build likelihood p(x | znew). x_znew = copy(x, new_sample, scope='x_znew') # Build likelihood p(x | zold). x_zold = copy(x, old_sample, scope='x_zold') # Increment ratio. ratio += tf.reduce_sum(x_znew.log_prob(obs)) ratio -= tf.reduce_sum(x_zold.log_prob(obs)) else: x = self.data ratio += self.model_wrapper.log_prob(x, new_sample) ratio -= self.model_wrapper.log_prob(x, old_sample) # Accept or reject sample. u = Uniform().sample() accept = tf.log(u) < ratio sample_values = tf.cond(accept, lambda: list(six.itervalues(new_sample)), lambda: list(six.itervalues(old_sample))) if not isinstance(sample_values, list): # ``tf.cond`` returns tf.Tensor if output is a list of size 1. sample_values = [sample_values] sample = {z: sample_value for z, sample_value in zip(six.iterkeys(new_sample), sample_values)} # Update Empirical random variables. assign_ops = [] variables = {x.name: x for x in tf.get_default_graph().get_collection(tf.GraphKeys.VARIABLES)} for z, qz in six.iteritems(self.latent_vars): variable = variables[qz.params.op.inputs[0].op.inputs[0].name] assign_ops.append(tf.scatter_update(variable, self.t, sample[z])) # Increment n_accept (if accepted). assign_ops.append(self.n_accept.assign_add(tf.select(accept, 1, 0))) return tf.group(*assign_ops)
def build_update(self): """ Draw sample from proposal conditional on last sample. Then accept or reject the sample based on the ratio, ratio = log p(x, znew) - log p(x, zold) + log g(znew | zold) - log g(zold | znew) """ old_sample = { z: tf.gather(qz.params, tf.maximum(self.t - 1, 0)) for z, qz in six.iteritems(self.latent_vars) } # Form dictionary in order to replace conditioning on prior or # observed variable with conditioning on a specific value. dict_swap = {} for x, qx in six.iteritems(self.data): if isinstance(x, RandomVariable): if isinstance(qx, RandomVariable): qx_copy = copy(qx, scope='conditional') dict_swap[x] = qx_copy.value() else: dict_swap[x] = qx dict_swap_old = dict_swap.copy() dict_swap_old.update(old_sample) scope_old = 'inference_' + str(id(self)) + '/old' scope_new = 'inference_' + str(id(self)) + '/new' # Draw proposed sample and calculate acceptance ratio. new_sample = {} ratio = 0.0 for z, proposal_z in six.iteritems(self.proposal_vars): # Build proposal g(znew | zold). proposal_znew = copy(proposal_z, dict_swap_old, scope=scope_old) # Sample znew ~ g(znew | zold). new_sample[z] = proposal_znew.value() # Increment ratio. ratio += tf.reduce_sum(proposal_znew.log_prob(new_sample[z])) dict_swap_new = dict_swap.copy() dict_swap_new.update(new_sample) for z, proposal_z in six.iteritems(self.proposal_vars): # Build proposal g(zold | znew). proposal_zold = copy(proposal_z, dict_swap_new, scope=scope_new) # Increment ratio. ratio -= tf.reduce_sum(proposal_zold.log_prob(dict_swap_old[z])) if self.model_wrapper is None: for z in six.iterkeys(self.latent_vars): # Build priors p(znew) and p(zold). znew = copy(z, dict_swap_new, scope=scope_new) zold = copy(z, dict_swap_old, scope=scope_old) # Increment ratio. ratio += tf.reduce_sum(znew.log_prob(dict_swap_new[z])) ratio -= tf.reduce_sum(zold.log_prob(dict_swap_old[z])) for x in six.iterkeys(self.data): if isinstance(x, RandomVariable): # Build likelihoods p(x | znew) and p(x | zold). x_znew = copy(x, dict_swap_new, scope=scope_new) x_zold = copy(x, dict_swap_old, scope=scope_old) # Increment ratio. ratio += tf.reduce_sum(x_znew.log_prob(dict_swap[x])) ratio -= tf.reduce_sum(x_zold.log_prob(dict_swap[x])) else: x = self.data ratio += self.model_wrapper.log_prob(x, new_sample) ratio -= self.model_wrapper.log_prob(x, old_sample) # Accept or reject sample. u = Uniform().sample() accept = tf.log(u) < ratio sample_values = tf.cond(accept, lambda: list(six.itervalues(new_sample)), lambda: list(six.itervalues(old_sample))) if not isinstance(sample_values, list): # ``tf.cond`` returns tf.Tensor if output is a list of size 1. sample_values = [sample_values] sample = { z: sample_value for z, sample_value in zip(six.iterkeys(new_sample), sample_values) } # Update Empirical random variables. assign_ops = [] variables = { x.name: x for x in tf.get_default_graph().get_collection( tf.GraphKeys.VARIABLES) } for z, qz in six.iteritems(self.latent_vars): variable = variables[qz.params.op.inputs[0].op.inputs[0].name] assign_ops.append(tf.scatter_update(variable, self.t, sample[z])) # Increment n_accept (if accepted). assign_ops.append(self.n_accept.assign_add(tf.select(accept, 1, 0))) return tf.group(*assign_ops)
from edward.models import Normal, Poisson, PointMass, Exponential, Uniform, Empirical count_data = np.loadtxt("data/txtdata.csv") n_count_data = len(count_data) sess = tf.Session() alpha_f = 1.0 / count_data.mean() with tf.name_scope('model'): alpha = tf.Variable(alpha_f, name="alpha", dtype=tf.float32) # init lambda_1 = Exponential(alpha, name="lambda1") lambda_2 = Exponential(alpha, name="lambda2") tau = Uniform(low=0.0, high=float(n_count_data - 1), name="tau") idx = np.arange(n_count_data) lambda_ = tf.where( tau >= idx, tf.ones(shape=[ n_count_data, ], dtype=tf.float32) * lambda_1, tf.ones(shape=[ n_count_data, ], dtype=tf.float32) * lambda_2) # error z = Poisson(lambda_, value=tf.Variable(tf.ones(n_count_data)), name="poi") # model T = 5000 # number of posterior samples