Иерархическая модель в вероятности тензорного потока с использованием JointDistributionSequential - PullRequest
1 голос
/ 08 марта 2020

Я пытаюсь понять, как реализовать следующую модель в вероятности 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 взято из распределения фон Мизеса с центром в 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-03-17

Последний код выглядит следующим образом. Я все еще пытаюсь выяснить, как реализовать часть (3) моей модели, то есть изменить направление моего угла, theta, добавив pi с вероятностью beta. Любая помощь в этом будет оценена! То, что у меня есть, не работает, потому что я не могу умножить объект Бернулли на число с плавающей точкой.

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
    ]
)

Ответы [ 2 ]

2 голосов
/ 05 апреля 2020

Проблема умножения числа на распределение в расчете параметра 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
]

)

. Это также позволяет производить выборку из совместное диктатура и преимущество в том, что он может видеть, когда происходят сальто.

1 голос
/ 10 марта 2020

Поменяйте Бернулли на Бином. Бином является сумма total_count числа Бернулли др aws.

...