如何在Tensorflow中使HMM适用于实数值数据

我正在处理一个包含物联网设备数据的数据集,我发现隐藏马尔可夫模型对我的用例非常有效。因此,我试图修改我在Tensorflow教程中找到的一些代码,教程链接在这里。与教程中显示的计数数据相比,该数据集包含观测变量的实数值。

特别是,我认为需要进行以下更改,以便HMM具有正态分布的发射。不幸的是,我找不到任何代码来改变模型以使用除泊松分布之外的其他发射分布。

我应该如何更改代码以发出正态分布的值?

# 定义表示未知对数率的变量trainable_log_rates = tf.Variable(  np.log(np.mean(observed_counts)) + tf.random.normal([num_states]),  name='log_rates')hmm = tfd.HiddenMarkovModel(  initial_distribution=tfd.Categorical(      logits=initial_state_logits),  transition_distribution=tfd.Categorical(probs=transition_probs),  observation_distribution=tfd.Poisson(log_rate=trainable_log_rates),  num_steps=len(observed_counts))rate_prior = tfd.LogNormal(5, 5)def log_prob(): return (tf.reduce_sum(rate_prior.log_prob(tf.math.exp(trainable_log_rates))) +         hmm.log_prob(observed_counts))optimizer = tf.keras.optimizers.Adam(learning_rate=0.1)@tf.function(autograph=False)def train_op():  with tf.GradientTape() as tape:    neg_log_prob = -log_prob()  grads = tape.gradient(neg_log_prob, [trainable_log_rates])[0]  optimizer.apply_gradients([(grads, trainable_log_rates)])  return neg_log_prob, tf.math.exp(trainable_log_rates)

回答:

@的回答是正确的,在Tensorflow发布的示例中,你有一个隐藏马尔可夫模型,具有均匀的零分布([0.,0.,0.,0.]),一个重对角线的转移矩阵,以及泊松分布的发射概率。

为了适应你的“正态”示例,你只需要将这些概率更改为正态分布。作为一个起点,假设你的发射概率是具有以下参数的正态分布:

training_loc =  tf.Variable([0.,0.,0.,0.])training_scale = tf.Variable([1.,1.,1.,1.])

那么你的observation_distribution将是:

observation_distribution = tfp.distributions.Normal(loc= training_loc, scale=training_scale )

最后,你还需要更改关于这些参数的先验知识,设置prior_locprior_scale。你可能希望考虑使用非信息性/弱信息性的先验,因为我看到你随后会对模型进行拟合。

所以你的代码应该类似于:

# 定义发射概率training_loc =  tf.Variable([0.,0.,0.])training_scale = tf.Variable([1.,1.,1.])observation_distribution = tfp.distributions.Normal(loc= training_loc, scale=training_scale ) #更改为你想要的分布hmm = tfd.HiddenMarkovModel(  initial_distribution=tfd.Categorical(      logits=initial_state_logits),  transition_distribution=tfd.Categorical(probs=transition_probs),  observation_distribution=observation_distribution,  num_steps=len(observed_counts))# 先验分布prior_loc = tfd.Normal(loc=0., scale=1.)prior_scale = tfd.HalfNormal(scale=1.)def log_prob():  log_probability = hmm.log_prob(data)#在这里使用你的训练数据  # 计算观测分布的均值和标准差的先验的对数概率  log_probability += tf.reduce_sum(prior_mean.log_prob(observation_distribution.loc))  log_probability += tf.reduce_sum(prior_scale.log_prob(observation_distribution.scale))  # 返回负对数概率,因为我们希望最小化这个量  return log_probability optimizer = tf.keras.optimizers.Adam(learning_rate=0.1)# 最后像示例中那样训练模型losses = tfp.math.minimize(    lambda: -log_prob(),    optimizer=tf.optimizers.Adam(learning_rate=0.1),    num_steps=100)

所以现在,如果你查看你的参数training_loctraining_scale,它们应该已经拟合了值。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注