我想计算4维多元正态值的均值(mu)和方差(cov_mat)的后验分布。我正在使用tfp中的edward2。我无法弄清楚如何做下面的pymc3代码:
with pm.Model() as model:
sigma = pm.Lognormal('sigma', np.zeros(4), np.ones(4), shape=4)
nu = pm.Uniform('nu', 0, 4)
C_triu = pm.LKJCorr('C_triu', nu, 4)
with model:
C = pm.Deterministic('C', T.fill_diagonal(C_triu[np.zeros((4, 4), dtype=np.int64)], 1.))
sigma_diag = pm.Deterministic('sigma_mat', T.nlinalg.diag(sigma))
cov = pm.Deterministic('cov', T.nlinalg.matrix_dot(sigma_diag, C, sigma_diag))
tau = pm.Deterministic('tau', T.nlinalg.matrix_inverse(cov))
with model:
mu = pm.MvNormal('mu', 0, tau=tau, shape=4)
x_ = pm.MvNormal('x', mu, tau=tau, observed=X)
n_samples = 2000
n_burn = 2000
n_thin = 2
with model:
step = pm.Metropolis()
trace_ = pm.sample(n_samples, step, chains=4, cores=1)
在此模型中,我们了解到,给定观测矩阵X时,我们必须计算mu和tau的后验。
pm.Metropolis和pm.sample很简单。
这是我在tfp和edward2中无法完成的代码。
def mymodel():
nu = ed.Uniform(name="nu", low=0., high=4.)
corr_mat = ed.LKJ(name="corr", dimension=4, concentration=nu)
sigma = ed.LogNormal(name='sigma', loc=np.zeros(4, dtype=np.float32), scale=np.ones(4, dtype=np.float32))
sigma_mat = tf.diag(name="sigma_mat", diagonal=sigma)
cov_mat = sigma_mat.__matmul__(corr_mat).__matmul__(sigma_mat)
# L_tril = tf.cholesky(cov_mat)
# tau_mat = tf.linalg.inv(cov_mat)
mu = ed.MultivariateNormalFullCovariance(name="mu", loc=np.zeros(4, dtype=np.float32), covariance_matrix=sigma_mat)
x = ed.MultivariateNormalFullCovariance(name="x", loc=mu, covariance_matrix=sigma_mat)
return x
log_joint = ed.make_log_joint_fn(mymodel)
# HMC Settings
num_results = int(10e3) #number of hmc iterations
n_burnin = int(5e3) #number of burn-in steps
step_size = 0.01
num_leapfrog_steps = 10
# Parameter sizes
mu_size = [4,1]
cov_mat_dim = 4
# HMC transition kernel
kernel = tfp.mcmc.HamiltonianMonteCarlo(
target_log_prob_fn=log_joint,
step_size=step_size,
num_leapfrog_steps=num_leapfrog_steps)
# Define the chain states
states, kernel_results = tfp.mcmc.sample_chain(
num_results=num_results,
num_burnin_steps=n_burnin,
kernel=kernel,
current_state=[
tf.zeros(mu_size, name='init_mu'),
# tf.eye(cov_mat_dim, name='init_cov_mat'),
])
# Run the chain
with tf.Session() as sess:
[states_] = sess.run([states])
这就是我可以从互联网上收集到的所有信息。我无法弄清楚如何从后验中取样以及在哪里指定证据。 target_log_prob应该用于后验分布。我该怎么办?