<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Probabilistic Programming
Probabilistic programming involves constructing generative models of data and using inference to determine the parameters of these models.
Simple 'hello world' example
Step1:  Point estimate of model parameters
Step2:  Posterior estimate of model parameters
<ASSISTANT_TASK:>
Python Code:
# Generative model
mu_x = 10.0
sigma_x = 2.0
x_s = edm.Normal(mu_x, sigma_x)
# Sample data produced by model
n_samples = 100
samples = np.zeros(n_samples)
with tf.Session() as sess:
    for i in range(n_samples):
        samples[i] = sess.run(x_s)
# Descriptive statistics
print('Mean: {}'.format(np.mean(samples)))
print('StDev: {}'.format(np.std(samples)))
# Tear down model and work off observations only
tf.reset_default_graph()
# Model for data
N = 100
theta_mu = tf.Variable(0.0)
theta_sigma = tf.Variable(1.0)
x = edm.Normal(loc=tf.ones(N)*theta_mu, scale=tf.ones(N)*theta_sigma)
x_train = samples[:N]
# Descriptive statistics for observed data
print('Mean: {}'.format(np.mean(x_train)))
print('StDev: {}'.format(np.std(x_train)))
Explanation: Probabilistic Programming
Probabilistic programming involves constructing generative models of data and using inference to determine the parameters of these models.
Simple 'hello world' example: assume our data is noisy measurement of a constant value.  How can we infer the value and the uncertainty?
End of explanation
mle = edi.MAP({}, {x: x_train})
mle.run()
sess = ed.get_session()
sess.run([theta_mu, theta_sigma])
Explanation: Point estimate of model parameters
End of explanation
tf.reset_default_graph()
theta_mu_d = edm.Normal(0.0, 1.0)
theta_sigma_d = edm.InverseGamma(0.01, 0.01)
x_d = edm.Normal(loc=tf.ones(N)*theta_mu_d, scale=tf.ones(N)*theta_sigma_d)
q_mu = edm.Normal(tf.Variable(0.0), 1.0)
q_sigma =  edm.InverseGamma(tf.nn.softplus(tf.Variable(0.01)), tf.nn.softplus(tf.Variable(0.01)))
infer = edi.KLqp({theta_mu_d: q_mu, theta_sigma_d: q_sigma}, {x_d: x_train})
infer.run()
sess = ed.get_session()
sess.run([q_mu, q_sigma])
_ = plt.hist([sess.run(q_mu) for _ in range(10000)], bins=20)
_ = plt.hist([sess.run(q_sigma) for _ in range(10000)], bins=20)
Explanation: Posterior estimate of model parameters
End of explanation
<END_TASK>