微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

结构更复杂的TensorFlow Hidden Markov Model

如何解决结构更复杂的TensorFlow Hidden Markov Model

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

enter image description here

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

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

enter image description here

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,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 必须是

一个类似于 Categorical 的实例。最右边的批次维度索引 每个隐藏状态的概率分布以 之前的隐藏状态。

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(),previous_state=state)]),observation_fn=lambda step,state: observation_distribution[state[1]],num_particles=4096)

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。