【问题标题】:Hierarchical model in Tensorflow probability using JointDistributionSequential使用 JointDistributionSequential 的 Tensorflow 概率分层模型
【发布时间】:2020-03-08 15:01:43
【问题描述】:

我正在尝试了解如何在 Tensorflow 概率中实现以下模型。

  1. 角度theta[-pi / 2, +pi / 2]范围内具有一致的先验概率;
  2. 方向翻转概率beta[0, 1]范围内具有统一的先验概率;
  3. theta' 设置为:
    • theta' = theta + pi 概率为beta;或
    • theta' = theta 概率为(1 - beta);
  4. 浓度c具有HalfCauchy先验概率;和
  5. 观察,alpha 来自von Mises distribution,以theta' 为中心,专注于c

到目前为止,我尝试过的是

import tensorflow_probability as tfp
import numpy as np
tfd = tfp.distributions

model = tfd.JointDistributionSequential(
    [
        tfd.Uniform(-np.pi / 2, +np.pi / 2, name='theta'), # theta
        tfd.Uniform(0.0, 1.0, name='beta'), # beta
        tfd.HalfCauchy(loc=0, scale=1), # c
        lambda c, beta, theta: tfd.VonMises(
            loc=theta + np.pi * tfd.Binomial(probs=beta),
            concentration=c,
            name='observed'
        ), # Observation, alpha
    ]
)

调用它会在二项式部分出现错误:TypeError: __init__() missing 1 required positional argument: 'total_count'。我做错了什么?

2020 年 3 月 17 日更新

最新代码如下。我仍在尝试找出如何实现模型的第 (3) 部分,即通过添加pi 和概率beta 来翻转我的角度方向theta。对此的任何帮助将不胜感激!到目前为止我所拥有的不起作用,因为我无法将伯努利对象乘以浮点数。

model = tfd.JointDistributionSequential(
    [
        tfd.Uniform(-np.pi / 2, +np.pi / 2, name='theta'), # theta
        tfd.Uniform(0.0, 1.0, name='beta'), # beta
        tfd.HalfCauchy(loc=0, scale=1), # c
        lambda c, beta, theta: tfd.VonMises(
            loc=theta + np.pi * tfd.Bernoulli(probs=beta, dtype=tf.float32),
            concentration=c,
            name='observed'
        ), # Observation, alpha
    ]
)

【问题讨论】:

  • 我想你可能想使用MixtureSameFamily?

标签: tensorflow tensorflow-probability hierarchical-bayesian


【解决方案1】:

loc参数计算中将一个数字乘以一个分布的问题可以通过从伯努利分布中采样来解决,即

...
loc=theta + np.pi*tfd.Bernoulli(probs=beta, dtype=tf.float32).sample(),
...

这允许从联合分布中抽样,但我不确定它是否正确。

另一种方法是提取flip 随机变量并使用双射器进行缩放,即

tpb = tfp.bijectors
model = tfd.JointDistributionSequential(
[
    tfd.Uniform(-np.pi / 2, +np.pi / 2, name='theta'), # theta
    tfd.Uniform(0.0, 1.0, name='beta'), # beta
    lambda beta, theta: tfb.Scale(np.pi)(tfd.Bernoulli(probs=beta, dtype=tf.float32)), #flip
    tfd.HalfCauchy(loc=0, scale=1), # c
    lambda c, flip, beta, theta: tfd.VonMises(
        loc=theta + flip ,
        concentration=c,
        name='observed'
    ), # Observation, alpha
]

)

这还允许从联合分布中进行采样,并具有能够看到何时发生翻转的优势。

【讨论】:

  • 我认为第二种方法可能更好,但现在请注意您有一个离散值,这会使采样变得困难。您可以尝试使用 RelaxedBernoulli 来获得连续的 0-1 值,浓度在 0 和 1 左右。
【解决方案2】:

将伯努利换成二项式。二项式是total_count 伯努利抽奖次数的总和。

【讨论】:

  • 顺便说一句,如果您使用的是tfp-nightly,我建议您查看一些JointDistribution*AutoBatched 类。文档在这里tensorflow.org/probability/api_docs/python/tfp/…
  • 谢谢 - 明白我需要使用伯努利而不是二项式。如何在我的模型中实现步骤 (3)(根据伯努利图将 theta' 设置为 theta + pi)。我所做的不对,因为它引发了unsupported operand type(s) for *: 'float' and 'Bernoulli'
  • 将 dtype=tf.float32 传递给构造函数。 tensorflow.org/probability/api_docs/python/tfp/distributions/…
  • 抱歉我还是不太明白。我现在使用theta + np.pi * tfd.Bernoulli(probs=beta, dtype=tf.float32) 设置VonMises 的loc,但仍然得到同样的错误。
  • [见马特麦克唐纳的回答。]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
相关资源
最近更新 更多