Скрытая марковская модель TensorFlow с более сложной структурой

Используя отличную библиотеку TensorFlow, это просто для моделирования следующей динамической байесовской сети:

введите описание изображения здесь

где H i - вероятностная переменная, представляющая HMM, а S i - вероятностная переменная, представляющая наблюдения.

Что, если бы я хотел, чтобы H зависел от еще одного HMM (Hierarchical HMM) или просто другой вероятностной переменной вроде этой:

введите описание изображения здесь

Определение HiddenMarkovModel в TensorFlow выглядит следующим образом:

tfp.distributions.HiddenMarkovModel(
    initial_distribution, transition_distribution, observation_distribution,
    num_steps, validate_args=False, allow_nan_stats=True,
    time_varying_transition_distribution=False,
    time_varying_observation_distribution=False, name='HiddenMarkovModel'
)

Он принимает только начальные, переходные и наблюдательные распределения.

Как я мог смоделировать вышеупомянутое и передать дополнительное распределение вероятностных переменных в HiddenMarkovModel? Возможно ли это, каким-то образом включив C в параметр transition_distribution? Может быть, C тоже следует рассматривать как наблюдение? (Я не уверен, что это будет полный эквивалент структуры, которую я хотел бы смоделировать)

Было бы здорово иметь простой пример / объяснение.

ОБНОВЛЕНИЕ

Я попытался построить простое совместное распределение двух зависимых переменных и передать его как transition_distribution в HMM:

def mydist(y):
  samples_length = 1 if tf.rank(y) == 0 else y.shape[0]
  b = tf.ones([samples_length], dtype=tf.int32) - y
  a = tf.reshape(y, [samples_length,1])
  b = tf.reshape(b, [samples_length,1])
  c = tf.concat([a, b], axis=1)

  condprobs = tf.constant([ [0.1, 0.9], [0.5, 0.5] ])
  d = tf.matmul(tf.cast(c, tf.float32), condprobs)
  return tfd.Categorical(d, dtype=tf.int32)

jd = tfd.JointDistributionSequential([
            tfd.Categorical(probs=[0.9, 0.1]),
  lambda y: mydist(y)
], validate_args=True)


initial_distribution = tfd.Categorical(probs=[0.8, 0.2])

transition_distribution = tfd.Categorical(probs=[[0.7, 0.3],
                                                 [0.2, 0.8]])

observation_distribution = tfd.Normal(loc=[0., 15.], scale=[5., 10.])

model = tfd.HiddenMarkovModel(
    initial_distribution=initial_distribution,
    transition_distribution=jd,
    observation_distribution=observation_distribution,
    num_steps=7)

temps = [-2., 0., 2., 4., 6., 8., 10.]

model.posterior_mode(temps)

Это дает ошибку:

ValueError: если две фигуры не могут быть переданы. AttributeError: объект 'list' не имеет атрибута 'ndims'

В руководстве HMM упоминается:

Эта модель предполагает, что матрицы переходов фиксируются во времени.

И это transition_distribution должно быть

Категорически-подобный экземпляр. Крайнее правое пакетное измерение индексирует распределение вероятностей каждого скрытого состояния, обусловленного предыдущим скрытым состоянием.

который tfd.JointDistributionSequential, вероятно, не является.

Все еще ищу способы построения иерархических HMM с помощью TensorFlow.


person Sergey Shcherbakov    schedule 07.02.2021    source источник


Ответы (1)


TFP HiddenMarkovModel реализует алгоритмы передачи сообщений для графов с цепочкой, поэтому он не может изначально обрабатывать граф, в котором Cs являются дополнительными скрытыми переменными. Я могу придумать несколько подходов:

  1. Сверните C в скрытое состояние H, увеличив размер состояния. (то есть, если H принимает значения в 1, ..., N, а C принимает значения в 1, ..., M, новое комбинированное состояние будет принимать значения в 1, ..., NM).

  2. Смоделируйте цепочку обусловленную значениями для C, которые установлены некоторым приблизительным алгоритмом вывода. Например, если C являются непрерывными, вы можете подогнать их с помощью градиентного VI или MCMC:

@tfd.JointDistributionCoroutineAutoBatched
def model():
  Cs = yield tfd.Sample(SomePrior, num_timesteps)
  Ss = yield tfd.HiddenMarkovModel(
    ..., 
    transition_distribution=SomeDistribution(Cs), 
    time_varying_transition_distribution=True)


# Fit Cs using gradient-based VI (could also use HMC). 
pinned = tfp.experimental.distributions.JointDistributionPinned(model, Ss=observations)
surrogate_posterior = tfp.experimental.vi.build_factored_surrogate_posterior(
  event_shape=pinned.event_shape,
  bijector=pinned.experimental_default_event_space_bijector())
losses = tfp.vi.fit_surrogate_posterior(
  target_log_prob_fn=pinned.unnormalized_log_prob,
  surrogate_posterior=surrogate_posterior,
  optimizer=tf.optimizers.Adam(0.1),
  num_steps=200)
  1. Используйте фильтр частиц, который может обрабатывать произвольные совместные распределения и зависимости в моделях перехода и наблюдения:
[ 
  trajectories,
  incremental_log_marginal_likelihoods
] = tfp.experimental.mcmc.infer_trajectories(
    observations=observations,
    initial_state_prior=tfd.JointDistributionSequential(
      [PriorOnC(),
       lambda c: mydist(c, previous_state=None)]),
    transition_fn=lambda step, state: tfd.JointDistributionSequential(
      [PriorOnC(),
       lambda c: mydist(c, previous_state=state)]),
    observation_fn=lambda step, state: observation_distribution[state[1]],
    num_particles=4096)

Это отказывается от точного вывода по дискретной цепочке, но, вероятно, это наиболее гибкий подход для работы с динамическими байесовскими сетями в целом.

person Dave Moore    schedule 21.02.2021
comment
Спасибо, Дэйв! Это очень полезно. Немного подумав, я понял, что Иерархический HMM отличается от нарисованного мной изображения (переменная C). Печально, что нет доступных бесплатных инструментов для создания моделей HHMM (например, для распознавания речи, я знаю о Google API для этого). Но многоуровневые HMM en.wikipedia.org/wiki/Layered_hidden_Markov_model, похоже, очень близки к моей picture, и для этого должно быть просто связать HMM TensorFlow. - person Sergey Shcherbakov; 23.02.2021