结构更复杂的 TensorFlow 隐马尔可夫模型

TensorFlow Hidden Markov Model with more complex structure

使用强大的 TensorFlow 隐马尔可夫模型 library,可以直接对以下动态贝叶斯网络进行建模:

其中Hi是表示HMM的概率变量,Si是表示观测值的概率变量。

如果我想让 H 依赖于另一个 HMM(分层 HMM)或像这样的其他概率变量怎么办:

TensorFlow 中的 HiddenMarkovModel 定义如下所示:

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: If the two shapes can not be broadcasted. AttributeError: 'list' object has no attribute 'ndims'

HMM手册提到:

This model assumes that the transition matrices are fixed over time.

而且 transition_distribution 必须是

A Categorical-like instance. The rightmost batch dimension indexes the probability distribution of each hidden state conditioned on the previous hidden state.

其中 tfd.JointDistributionSequential 可能不是。

仍在寻找使用 TensorFlow 构建分层 HMM 的方法。

TFP HiddenMarkovModel 实现了链式结构图的消息传递算法,因此它无法原生处理 C 是附加潜在变量的图。我可以想到一些方法:

  1. C折叠成隐藏状态H,炸大状态大小。 (也就是说,如果 H1, ..., N 中取值并且 C1, ..., 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)

这放弃了对离散链的精确推理,但它可能是处理一般动态贝叶斯网络的最灵活的方法。