Skip to content

Commit

Permalink
Merge 209c32e into 071a4ba
Browse files Browse the repository at this point in the history
  • Loading branch information
dustinvtran committed Jan 8, 2018
2 parents 071a4ba + 209c32e commit 364e038
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 19 deletions.
14 changes: 7 additions & 7 deletions edward/inferences/hmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def build_update(self):
# Update Empirical random variables.
assign_ops = []
for z_unconstrained, qz_unconstrained in six.iteritems(
self.latent_vars_unconstrained):
self.latent_vars_unconstrained):
variable = qz_unconstrained.get_variables()[0]
assign_ops.append(tf.scatter_update(
variable, self.t, sample[z_unconstrained]))
Expand All @@ -139,7 +139,7 @@ def build_update(self):

def _log_joint_unconstrained(self, z_sample):
"""
Given a sample in unconstrained latent space, transform it back into
Given a sample in unconstrained latent space, transform it back into
the original space, and compute the log joint density with appropriate
Jacobian correction.
"""
Expand All @@ -151,17 +151,17 @@ def _log_joint_unconstrained(self, z_sample):
z_sample_transformed = {}
log_det_jacobian = 0.0
for z_unconstrained, qz_unconstrained in z_sample.items():
z = (unconstrained_to_z[z_unconstrained]
if z_unconstrained in unconstrained_to_z
z = (unconstrained_to_z[z_unconstrained]
if z_unconstrained in unconstrained_to_z
else z_unconstrained)

try:
bij = self.transformations[z].bijector
z_sample_transformed[z] = bij.inverse(qz_unconstrained)
log_det_jacobian += tf.reduce_sum(
bij.inverse_log_det_jacobian(qz_unconstrained))
except: # if z not in self.transformations,
# or is not a TransformedDist w/ bijector
bij.inverse_log_det_jacobian(qz_unconstrained))
except: # if z not in self.transformations,
# or is not a TransformedDist w/ bijector
z_sample_transformed[z] = qz_unconstrained

return self._log_joint(z_sample_transformed) + log_det_jacobian
Expand Down
17 changes: 10 additions & 7 deletions edward/inferences/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from tensorflow.contrib.distributions import bijectors


@six.add_metaclass(abc.ABCMeta)
class Inference(object):
"""Abstract base class for inference. All inference algorithms in
Expand Down Expand Up @@ -222,11 +223,13 @@ def initialize(self, n_iter=1000, n_print=None, scale=None,
self.transformations = {}
if auto_transform:
latent_vars = self.latent_vars.copy()
self.latent_vars = {} # maps original latent vars to constrained Q's
self.latent_vars_unconstrained = {} # maps unconstrained vars to unconstrained Q's
# latent_vars maps original latent vars to constrained Q's.
# latent_vars_unconstrained maps unconstrained vars to unconstrained Q's.
self.latent_vars = {}
self.latent_vars_unconstrained = {}
for z, qz in six.iteritems(latent_vars):
if hasattr(z, 'support') and hasattr(qz, 'support') and \
z.support != qz.support and qz.support != 'point':
z.support != qz.support and qz.support != 'point':

# transform z to an unconstrained space
z_unconstrained = transform(z)
Expand All @@ -243,12 +246,12 @@ def initialize(self, n_iter=1000, n_print=None, scale=None,
# back into the original constrained space
if z_unconstrained != z:
qz_constrained = transform(
qz_unconstrained, bijectors.Invert(z_unconstrained.bijector))
qz_unconstrained, bijectors.Invert(z_unconstrained.bijector))

try: # attempt to pushforward the params of Empirical distributions
try: # attempt to pushforward the params of Empirical distributions
qz_constrained.params = z_unconstrained.bijector.inverse(
qz_unconstrained.params)
except: # qz_unconstrained is not an Empirical distribution
qz_unconstrained.params)
except: # qz_unconstrained is not an Empirical distribution
pass

else:
Expand Down
13 changes: 8 additions & 5 deletions tests/inferences/test_inference_auto_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def test_hmc_betabernoulli(self):
qz_constrained = z_unconstrained.bijector.inverse(qz_samples)
qz_mean, qz_var = sess.run(tf.nn.moments(qz_constrained, 0))

true_posterior = Beta(1. + np.sum(x_obs), 1. + np.sum(1-x_obs))
true_posterior = Beta(1. + np.sum(x_obs), 1. + np.sum(1 - x_obs))
pz_mean, pz_var = sess.run((true_posterior.mean(),
true_posterior.variance()))
self.assertAllClose(qz_mean, pz_mean, rtol=5e-2, atol=5e-2)
Expand All @@ -199,16 +199,19 @@ def test_klqp_betabernoulli(self):
initializer=tf.random_normal(()))
qz_std = tf.nn.softplus(tf.get_variable(name="qz_prestd",
initializer=tf.random_normal(())))
qz_unconstrained = ed.models.Normal(loc=qz_mean, scale=qz_std, name="z_posterior")
qz_unconstrained = ed.models.Normal(
loc=qz_mean, scale=qz_std, name="z_posterior")

inference_klqp = ed.inferences.KLqp({z: qz_unconstrained}, data={xs: x_obs})
inference_klqp = ed.inferences.KLqp(
{z: qz_unconstrained}, data={xs: x_obs})
inference_klqp.run(n_iter=500, auto_transform=True)

z_unconstrained = inference_klqp.transformations[z]
qz_constrained = z_unconstrained.bijector.inverse(qz_unconstrained.sample(1000))
qz_constrained = z_unconstrained.bijector.inverse(
qz_unconstrained.sample(1000))
qz_mean, qz_var = sess.run(tf.nn.moments(qz_constrained, 0))

true_posterior = Beta(np.sum(x_obs) + 1., np.sum(1-x_obs) + 1.)
true_posterior = Beta(np.sum(x_obs) + 1., np.sum(1 - x_obs) + 1.)
pz_mean, pz_var = sess.run((true_posterior.mean(),
true_posterior.variance()))
self.assertAllClose(qz_mean, pz_mean, rtol=5e-2, atol=5e-2)
Expand Down

0 comments on commit 364e038

Please sign in to comment.