blei-lab / edward

A probabilistic programming language in TensorFlow. Deep generative models, variational inference.
http://edwardlib.org
Other
4.84k stars 759 forks source link

HMC: How to convert target parameter's posterior distribution back to the constrained scale? #839

Open cheng-w-liu opened 6 years ago

cheng-w-liu commented 6 years ago

I'm using Edward to run a simple Bayesian linear regression, which has three parameters: intercept, slope, and sigma (the standard deviation of the y-value). The intercept and slope are modeled as normal distributions, and sigma is modeled as Chi-squared distribution as it should be positive:

def generateData(intercept=1, slope=3, noise=1, n_points=20):
    X = np.reshape(np.random.uniform(-3, 3, n_points), (n_points, 1))
    X.sort()
    y = intercept + slope * X
    y = y.ravel()
    return X, y

intercept = 1
slope = 3
noise = 1
n_points = 20
np.random.seed(99)
X, y = generateData(intercept, slope, noise, n_points)

# Bayesian linear regression
N = 20
D = 1
X_holder = tf.placeholder(tf.float32, [N, D]) 
s = ed.models.Chi2(df=3.0)
w = Normal(loc=tf.zeros(D), scale=tf.ones(D)*10.0)
b = Normal(loc=tf.zeros(1), scale=tf.ones(1)*10.0)
y_holder = Normal(loc=ed.dot(X_holder, w) + b, scale=tf.ones(N)*s)
T = 50000
qs = Empirical(params=tf.Variable(tf.zeros(T)))
qw = Empirical(params=tf.Variable(tf.zeros((T, D) )))
qb = Empirical(params=tf.Variable(tf.zeros((T, 1) )))

inference = ed.HMC(latent_vars={s: qs, w: qw, b: qb}, data={X_holder: X, y_holder: y})
inference.run(step_size=5e-3)

# plot
ax.hist(qs.params.eval(), normed=True)
posterior_of_sigma

However, Edward's HMC sampling shows a lot of negative values in sigma's posterior distribution, as the above plot shows. Is that because the current version of HMC will transform the latent variables to unconstrained space? Is there a way to convert the posterior values back to the original scale after the sampling is done? Happy to help but just wanted to know the difficulty level and need some guidance.

dustinvtran commented 6 years ago

Is there a way to convert the posterior values back to the original scale after the sampling is done?

Yes! See http://edwardlib.org/tutorials/automated-transformations.

cheng-w-liu commented 6 years ago

Thanks @dustinvtran for the info!

Actually, looking at the code more closely, https://github.com/blei-lab/edward/blob/master/edward/inferences/inference.py#L247-L253 it seems that qz_constrained is transformed and put back to self.latent_vars[z] . Shouldn't that make the samples stored in qz in the original scale?