I'm playing around with a toy discrete HMM model in PyMC3 and I'm running into some issues.
My initial code look like this:
# Known transition and emission
with pymc3.Model() as hmm1:
T = tt.as_tensor_variable(Tr)
E = tt.as_tensor_variable(Er)
# State models
p0 = np.ones(num_states) / num_states
# No shape, so each state is a scalar tensor
states = [pymc3.Categorical('s0', p=p0)]
emissions = [pymc3.Categorical('z0', p=E[:,states[0]], observed=Zr[:,0])]
for i in range(1, num_times):
states.append(pymc3.Categorical('s{0}'.format(i), p=T[:,states[i-1]]))
emissions.append(pymc3.Categorical('z{0}'.format(i), p=E[:,states[i]], observed=Zr[:,i]))
Here Tr
and Er
are the real transition and emission matrices.
My issues are:
This model does not seems to explore the full values for the states, and it stays on a single value for each state (see notebook).
I haven't found a way to define
states
andemissions
in a more pymc-tonic way, e.g. usingshape=...
.Furthermore, when I extend the model to account for unknown an transition or emission matrix, I ran into an indexing problem, and I'm forced to used
theano.tensor.clip
, as in the next code:# Unknown transitions and emissions with pymc3.Model() as hmm3: # Transition "matrix" a_t = np.ones((num_states,num_states)) T = pymc3.Dirichlet('T', a=a_t, shape=(num_states,num_states)) # Emission "matrix" a_e = np.ones((num_emissions, num_states)) E = pymc3.Dirichlet('E', a=a_e, shape=(num_emissions, num_states)) # State models p0 = np.ones(num_states) / num_states # No shape, so each state is a scalar tensor states = [pymc3.Categorical('s0', p=p0)] clp_state = tt.clip(states[0], 0, num_states-1) emissions = [pymc3.Categorical('z0', p=E[:,clp_state], observed=Zr[0])] for i in range(1, num_times): clp_prev_state = tt.clip(states[i-1], 0, num_states-1) states.append(pymc3.Categorical('s{0}'.format(i), p=T[:,clp_prev_state])) clp_state = tt.clip(states[i], 0, num_states-1) emissions.append(pymc3.Categorical('z{0}'.format(i), p=E[:,clp_state], observed=Zr[i]))
See the following notebook with a complete code.