-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
There appears to be an error in the HiddenMarkovModel distribution log_prob implementation. The probability of the first hidden state in the sequence is computed as matmul(initial_distribution, transition_distribution)
rather than as initial_distribution
.
Code to reproduce problem:
import tensorflow.compat.v2 as tf
import tensorflow_probability as tfp
import numpy as np
x = tf.convert_to_tensor(np.array([0]), dtype=tf.int32)
a0 = tfp.distributions.Categorical(probs=[0.99, 0.01])
a = tfp.distributions.Categorical(probs=[[0.01, 0.99], [0.01, 0.99]])
e = tfp.distributions.Categorical(probs=[[0.99, 0.01], [0.01, 0.99]])
model = tfp.distributions.HiddenMarkovModel(a0, a, e, 1)
logp = model.log_prob(x)
expected_logp = tf.math.log(tf.reduce_sum(a0.probs[None, :]*e.probs[:, 0]))
computed_logp = tf.math.log(tf.reduce_sum(tf.matmul(a0.probs[None, :], a.probs)*e.probs[:, 0]))
print('tfp result: ', tf.exp(logp)) # Output: 0.0198
print('Expected behavior: ', tf.exp(expected_logp)) # Output: 0.9802
print('Match tfp calculation: ', tf.exp(computed_logp)) # Output: 0.0198
The problem can be found in lines 437-441 of the source code:
probability/tensorflow_probability/python/distributions/hidden_markov_model.py
Lines 437 to 441 in f051e03
def forward_step(log_prev_step, log_prob_observation): | |
return _log_vector_matrix(log_prev_step, | |
log_transition) + log_prob_observation | |
fwd_prob = tf.foldl(forward_step, observation_probs, initializer=log_init) |
foldl computes
_log_vector_matrix(log_prev_step, log_transition) + log_prob_observation
in the first step of the iteration, as well as in the later iterations where it is appropriate.
This convention would in theory be ok if used consistently, but it does not match the documentation, does not match the sampling function,
print('samples', model._sample_n(10)) # Output: [[0],[0],[0],[0],[0],[0],[0],[0],[0],[0]]
and does not match the posterior mode calculation,
e2 = tfp.distributions.Categorical(probs=[[0.5, 0.5], [0.5, 0.5]])
model = tfp.distributions.HiddenMarkovModel(a0, a, e2, 1)
print('posterior mode', model.posterior_mode(x)) # Output: [0]
print('marginal hidden probs', model._marginal_hidden_probs()) # Output: [[0.99000007 0.01 ]]
Tensorflow version: 2.2.0
Tensorflow Probability version: 0.10.0
Metadata
Metadata
Assignees
Labels
No labels