JointDistribution 的 Tensorflow-概率变换事件形状
Tensorflow-probability transform event shape of JointDistribution
我想为事件形状为 n 的 n 个分类变量 C_1,.., C_n 创建一个分布。使用 JointDistributionSequentialAutoBatched,事件维度是一个列表 [[],..,[]]。例如 n=2
import tensorflow_probability.python.distributions as tfd
probs = [
[0.8, 0.2], # C_1 in {0,1}
[0.3, 0.3, 0.4] # C_2 in {0,1,2}
]
D = tfd.JointDistributionSequentialAutoBatched([tfd.Categorical(probs=p) for p in probs])
>>> D
<tfp.distributions.JointDistributionSequentialAutoBatched 'JointDistributionSequentialAutoBatched' batch_shape=[] event_shape=[[], []] dtype=[int32, int32]>
如何重塑它以获得事件形状 [2]?
这里可以使用一些不同的方法:
- 创建一批分类分布,然后使用
tfd.Independent
将批次维度重新解释为事件:
vector_dist = tfd.Independent(
tfd.Categorical(
probs=[
[0.8, 0.2, 0.0], # C_1 in {0,1}
[0.3, 0.3, 0.4] # C_2 in {0,1,2}
]),
reinterpreted_batch_ndims=1)
这里我添加了一个额外的零来填充 probs
以便两个分布都可以由单个分类对象表示。
- 使用
Blockwise
分布,它将其分量分布填充到单个向量中(与 JointDistribution 类 相对,return 它们作为单独的值):
vector_dist = tfd.Blockwise([tfd.Categorical(probs=p) for p in probs])
- 最接近直接回答您问题的方法是将
Split
双射子应用于联合分布:
tfb = tfp.bijectors
D = tfd.JointDistributionSequentialAutoBatched(
[tfd.Categorical(probs=[p] for p in probs])
vector_dist = tfb.Invert(tfb.Split(2))(D)
请注意,我不得不笨拙地写 probs=[p]
而不是 probs=p
。这是因为 Concat
双射子,像 tf.concat
,不能改变其参数的张量等级---它可以将小向量连接成一个大向量,但不能将标量连接成一个向量---所以我们必须确保它的输入本身就是向量。如果 TFP 具有类似于 tf.stack
/ tf.unstack
的 Stack
双射器,则可以避免这种情况(目前没有,但没有理由不存在)。
我想为事件形状为 n 的 n 个分类变量 C_1,.., C_n 创建一个分布。使用 JointDistributionSequentialAutoBatched,事件维度是一个列表 [[],..,[]]。例如 n=2
import tensorflow_probability.python.distributions as tfd
probs = [
[0.8, 0.2], # C_1 in {0,1}
[0.3, 0.3, 0.4] # C_2 in {0,1,2}
]
D = tfd.JointDistributionSequentialAutoBatched([tfd.Categorical(probs=p) for p in probs])
>>> D
<tfp.distributions.JointDistributionSequentialAutoBatched 'JointDistributionSequentialAutoBatched' batch_shape=[] event_shape=[[], []] dtype=[int32, int32]>
如何重塑它以获得事件形状 [2]?
这里可以使用一些不同的方法:
- 创建一批分类分布,然后使用
tfd.Independent
将批次维度重新解释为事件:
vector_dist = tfd.Independent(
tfd.Categorical(
probs=[
[0.8, 0.2, 0.0], # C_1 in {0,1}
[0.3, 0.3, 0.4] # C_2 in {0,1,2}
]),
reinterpreted_batch_ndims=1)
这里我添加了一个额外的零来填充 probs
以便两个分布都可以由单个分类对象表示。
- 使用
Blockwise
分布,它将其分量分布填充到单个向量中(与 JointDistribution 类 相对,return 它们作为单独的值):
vector_dist = tfd.Blockwise([tfd.Categorical(probs=p) for p in probs])
- 最接近直接回答您问题的方法是将
Split
双射子应用于联合分布:
tfb = tfp.bijectors
D = tfd.JointDistributionSequentialAutoBatched(
[tfd.Categorical(probs=[p] for p in probs])
vector_dist = tfb.Invert(tfb.Split(2))(D)
请注意,我不得不笨拙地写 probs=[p]
而不是 probs=p
。这是因为 Concat
双射子,像 tf.concat
,不能改变其参数的张量等级---它可以将小向量连接成一个大向量,但不能将标量连接成一个向量---所以我们必须确保它的输入本身就是向量。如果 TFP 具有类似于 tf.stack
/ tf.unstack
的 Stack
双射器,则可以避免这种情况(目前没有,但没有理由不存在)。