具有Bernoulli分布的TensorFlow概率MCMC

时间:2018-11-02 16:46:50

标签: python tensorflow

我需要使用TensorFlow概率来实现马尔可夫链蒙特卡洛,并从伯努利分布中进行采样。 但是,我的尝试显示出的结果与伯努利分布所期望的结果不一致。

我修改了tfp.mcmc.sample_chain(从对角方差高斯抽样)example here文档中给出的示例,以从伯努利分布中提取。由于伯努利分布是离散的,因此我使用RandomWalkMetropolis过渡内核而不是 哈密​​顿蒙特卡洛核,我希望它不能工作,因为它可以计算梯度。

代码如下:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions

def make_likelihood(event_prob):
    return tfd.Bernoulli(probs=event_prob,dtype=tf.float32)


dims=1
event_prob = 0.3
num_results = 30000
likelihood = make_likelihood(event_prob)


states, kernel_results = tfp.mcmc.sample_chain(
    num_results=num_results,
    current_state=tf.zeros(dims),
    kernel = tfp.mcmc.RandomWalkMetropolis(
              target_log_prob_fn=likelihood.log_prob,
              new_state_fn=tfp.mcmc.random_walk_normal_fn(scale=1.0),
              seed=124
             ),
    num_burnin_steps=5000)

chain_vals = states

# Compute sample stats.
sample_mean = tf.reduce_mean(states, axis=0)
sample_var = tf.reduce_mean(
    tf.squared_difference(states, sample_mean),
    axis=0)

#initialize the variable
init_op = tf.global_variables_initializer()

#run the graph
with tf.Session() as sess:
    sess.run(init_op) 
    [sample_mean_, sample_var_, chain_vals_] = sess.run([sample_mean,sample_var,chain_vals])

chain_samples = (chain_vals_[:] )   
print ('Sample mean = {}'.format(sample_mean_))
print ('Sample var = {}'.format(sample_var_))
fig, axes = plt.subplots(2, 1)
fig.set_size_inches(12, 10)

axes[0].plot(chain_samples[:])
axes[0].title.set_text("values sample chain tfd.Bernoulli")
sns.kdeplot(chain_samples[:,0], ax=axes[1], shade=True)
axes[1].title.set_text("chain tfd.Bernoulli distribution")
fig.tight_layout()
plt.show()

我希望看到间隔[0,1]中的马尔可夫链状态值。

马尔可夫链值的结果看起来与伯努利分布的期望值不一样,KDE图也没有,如图所示 在此图中:

enter image description here

我的示例在概念上存在缺陷,还是在使用TensorFlow Probability API时出现错误?

或者TF.Markov Chain Monte Carlo的概率实现可能存在问题 使用离散分布,例如伯努利分布?

1 个答案:

答案 0 :(得分:3)

我认为,您令人困惑的经历的根源在于,您在RandomWalkMetropolis过渡中仍在使用连续的提案分配。 TensorFlow概率中的整数分布(包括Bernoulli)中的约定是默认情况下实现连续松弛。 IIRC,对于伯努利来说,是pdf(x) ~ p ** x * (1 - p) ** (1 - x);正如您观察到的那样,一旦x变为负值,这将稳定地推动您的随机行走马尔可夫链向-inf方向移动。

您可以为此做几件事:

  1. 使用通行证validate_args=TrueBernoulli构造函数。如果x不为0或1,则会崩溃,从而可以帮助您检测到问题(但如果希望间隔[0,1]为非整数,则不会)。
  2. 使用其他提议功能,例如0到1之间的独立统一。编写自己的代码并不难-这实际上是您所使用的高斯漂移提议功能的代码:https://github.com/tensorflow/probability/blob/master/tensorflow_probability/python/mcmc/random_walk_metropolis.py#L97-L107。请注意,该提案必须是对称的,才能与RandomWalkMetropolis一起正常使用。
  3. 完全使用其他MCMC过渡运算符。

我还提交了有关为独立性建议制作TransitionKernel(例如我想您可能需要的东西)的罚单:https://github.com/tensorflow/probability/issues/218