我正试图在Tensorflow Probability中建立一个图形模型,其中我们首先从类别分布中采样许多正(1(和负(0(个例子(count_I(,然后根据(count_id(的值构造多项式分布(Y_I(。这些事件(Y_i(是互斥的:
Y_1~多项式([0.9,0.1,0.05,0.05,0.1],total_count=[tf.reduce_sum(tf.cast(count==1,tf.foat32((
Y_2~多项式([0.99,0.01,0.,0.,0.],total_count=[tf.reduce_sum(tf.cast(count==0,tf.foat32((
我读过这些教程,但我遇到了两个问题:
- 这段代码生成两个长度为500的数组,而我只需要一个500的数组。如果我们只从分类分布中得到1个样本,然后根据我们所依赖的值的总数,构造多项式,我应该改变什么
- 分类分布的样本只给出0的值,而它应该是0和1之间的混合。我在这里做错了什么
我的代码如下。你可以运行这些来复制行为:
def simplied_model():
return tfd.JointDistributionSequential([
tfd.Uniform(low=0., high = 1., name = 'e'), #e
lambda e: tfd.Sample(tfd.Categorical(probs = tf.stack([e, 1.-e], 0)), sample_shape =500), #count #should it be independent?
lambda count: tfd.Multinomial(probs = tf.constant([[.9, 0.1, 0.05, 0.05, 0.1], [0.99, 0.01, 0., 0., 0.]]), total_count = tf.cast(tf.stack([tf.reduce_sum(tf.cast(count==1, tf.float32)),tf.reduce_sum(tf.cast(count==0, tf.float32))], 0), dtype= tf.float32))
])
tt = simplied_model()
tt.resolve_graph()
tt.sample(1)
第一个数组是您的Y_{1}
,第二个数组是Y_{2}
。关键是你的输出总是(2, 5)
的形状,因为这是你传递给tfd.Multinomial
的概率的长度。
代码:
import tensorflow as tf
import tensorflow_probability as tfp
from tensorflow_probability import distributions as tfd
# helper function
def _get_counts(vec):
zeros = tf.reduce_sum(tf.cast(vec == 0, tf.float32))
ones = tf.reduce_sum(tf.cast(vec == 1, tf.float32))
return tf.stack([ones, zeros], 0)
joint = tfd.JointDistributionSequential([
tfd.Sample( # sample from uniform to make it 2D
tfd.Uniform(0., 1., name="e"), 1),
lambda e: tfd.Sample(
tfd.Categorical(probs=tf.stack([e, 1.-e], -1)), 500),
lambda c: tfd.Multinomial(
probs=[
[0.9, 0.1, 0.05, 0.05, 0.1],
[0.99, 0.01, 0., 0., 0.],
],
total_count=_get_counts(c),
)
])
joint.sample(5) # or however many you want to sample
输出:
# [<tf.Tensor: shape=(5, 1), dtype=float32, numpy=
# array([[0.5611458 ],
# [0.48223293],
# [0.6097224 ],
# [0.94013655],
# [0.14861858]], dtype=float32)>,
# <tf.Tensor: shape=(5, 1, 500), dtype=int32, numpy=
# array([[[1, 0, 0, ..., 1, 0, 1]],
#
# [[1, 1, 1, ..., 1, 0, 0]],
#
# [[0, 0, 0, ..., 1, 0, 0]],
#
# [[0, 0, 0, ..., 0, 0, 0]],
#
# [[1, 0, 1, ..., 1, 0, 1]]], dtype=int32)>,
# <tf.Tensor: shape=(2, 5), dtype=float32, numpy=
# array([[ 968., 109., 0., 0., 0.],
# [1414., 9., 0., 0., 0.]], dtype=float32)>]