我正在尝试将Beta分布拟合到具有离散分数(1,2,3,4,5)
的调查结果中。
为此,我需要TensorFlow概率中Beta的有效log_prob。但是,在Beta中如何处理批处理存在问题。
这是给我一个错误的最小示例:
InvalidArgumentError:a和x的形状不一致:[3]与[1000,1] [Op:Betainc]
相同代码似乎可以在正态分布下正常工作...
我在这里做什么错了?
import numpy as np
import tensorflow_probability as tfp
tfd = tfp.distributions
#Generate fake data
np.random.seed(2)
data = np.random.beta(2.,2.,1000)*5.0
data = np.ceil(data)
data = data[:,None]
# Create a batch of three Beta distributions.
alpha = np.array([1.,3.]).astype(np.float32)
beta = np.array([1.,3.]).astype(np.float32)
bt = tfd.Beta(alpha,beta)
#bt = tfd.Normal(loc=alpha,scale=beta)
#Scale beta to 0-5
scbt = tfd.TransformedDistribution(
distribution=bt,bijector=tfp.bijectors.Affinescalar(
shift=0.,scale=5.))
# quantize beta to (1,5)
qdist = tfd.QuantizedDistribution(distribution=scbt,low=1,high=5)
#calc log_prob for 3 distributions
print(np.sum(qdist.log_prob(data),axis=0))
print(qdist.log_prob(data).shape)
TensorFlow 2.0.0 tensorflow_probability 0.8.0
编辑: 正如克里斯·苏特(Chris Suter)所建议的那样。这是手工广播解决方案:
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
from matplotlib import pyplot as plt
#Generate fake data
numdata = 100
numbeta = 3
np.random.seed(2)
data = np.random.beta(2.,numdata)
data *= 5.0
data = np.ceil(data)
data = data[:,None].astype(np.float32)
#alpha and beta [[1.,3.]]
alpha = np.expand_dims(np.arange(1,4),0).astype(np.float32)
beta = np.expand_dims(np.arange(1,0).astype(np.float32)
#tile to compensate for betainc
alpha = tf.tile(alpha,[numdata,1])
beta = tf.tile(beta,1])
data = tf.tile(data,[1,numbeta])
bt = tfd.Beta(concentration1=alpha,concentration0=beta)
scbt = tfd.TransformedDistribution(
distribution=bt,high=5)
#calc log_prob for numbeta number of distributions
print(np.sum(qdist.log_prob(data),axis=0))
EDIT2:当我尝试将其应用于MCMC采样时,以上解决方案不起作用。 新代码如下所示:
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
from time import time
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
import numpy as np
#Generate fake data
numdata = 100
np.random.seed(2)
data = np.random.beta(2.,None].astype(np.float32)
@tf.function
def sample_chain():
#Parameters of MCMC
num_burnin_steps = 300
num_results = 200
num_chains = 50
step_size = 0.01
#data tensor
outcomes = tf.convert_to_tensor(data,dtype=tf.float32)
def modeldist(alpha,beta):
bt = tfd.Beta(concentration1=alpha,concentration0=beta)
scbt = tfd.TransformedDistribution(
distribution=bt,scale=5.))
# quantize beta to (1,5)
qdist = tfd.QuantizedDistribution(distribution=scbt,high=5)
return qdist
def joint_log_prob(con1,con0):
#manual broadcast
tcon1 = tf.tile(con1[None,:],1])
tcon0 = tf.tile(con0[None,1])
toutcomes = tf.tile(outcomes,num_chains])
#model distribution with manual broadcast
dist = modeldist(tcon1,tcon0)
#joint log prob
return tf.reduce_sum(dist.log_prob(toutcomes),axis=0)
kernel = tfp.mcmc.HamiltonianmonteCarlo(
target_log_prob_fn=joint_log_prob,num_leapfrog_steps=5,step_size=step_size)
kernel = tfp.mcmc.SimpleStepSizeAdaptation(
inner_kernel=kernel,num_adaptation_steps=int(num_burnin_steps * 0.8))
init_state = [tf.identity(tf.random.uniform([num_chains])*10.0,name='init_alpha'),tf.identity(tf.random.uniform([num_chains])*10.0,name='init_beta')]
samples,[step_size,is_accepted] = tfp.mcmc.sample_chain(
num_results=num_results,num_burnin_steps=num_burnin_steps,current_state=init_state,kernel=kernel,trace_fn=lambda _,pkr: [pkr.inner_results.accepted_results.step_size,pkr.inner_results.is_accepted])
return samples
samples = sample_chain()
这最终会显示一条错误消息:
ValueError:遇到
None
渐变。 fn_arg_list:[tf.Tensor'init_alpha:0'shape =(50,)dtype = float32,tf.Tensor'init_beta:0'shape =(50,)dtype = float32]等级:[无,无]