Description
Minimal working example
using Turing, HiddenMarkovModels, LinearAlgebra
init = [1.0, 0.0]
trans = [0.8 0.2; 0.0 1.0]
emiss = [0.9 0.1; 0.0 1.0]
dists = [Categorical(emiss[i, :]) for i in axes(emiss, 1)]
hmm = HMM(init, trans, dists)
obs_seqs = [last(rand(hmm, 15)) for _ in 1:20]
seq_ends = cumsum(length.(obs_seqs))
obs_seqs_concat = reduce(vcat, obs_seqs)
# Calling `logdensityof` doesn't error
logdensityof(hmm, obs_seqs_concat; seq_ends)
# Model disallowing transitions from state 2 to state 1
@model function hmm_trans_fixed(K, obs_seqs, seq_ends)
# Initialization probabilities
init ~ Dirichlet(ones(K))
# Emission probabilities
Φ ~ filldist(Dirichlet(ones(K)), K)
# Transition probabilities, never from state 2 to 1
Θ₁ ~ Dirichlet(ones(K))
Θ = Matrix(Diagonal(ones(eltype(Θ₁), K)))
Θ[:, 1] = Θ₁
# Set up HMM object
dists = [Categorical(Φ[:, i]) for i in axes(Φ, 2)]
hmm = HMM(init, permutedims(Θ), dists)
# Forward algorithm
Turing.@addlogprob! logdensityof(hmm, obs_seqs; seq_ends)
return (; hmm)
end
# This model runs and infers parameters correctly
model1 = hmm_trans_fixed(2, obs_seqs_concat, seq_ends)
chn1 = sample(model1, NUTS(), 500)
# Model where state 2 always emits the same observation
@model function hmm_trans_emiss_fixed(K, obs_seqs, seq_ends)
# Initialization probabilities
init ~ Dirichlet(ones(K))
# Emission probabilities, state 2 always emits 2
Φ₁ ~ Dirichlet(ones(K))
Φ = Matrix(Diagonal(ones(eltype(Φ₁), K)))
Φ[:, 1] = Φ₁
# Transition probabilities, never from state 2 to 1
Θ₁ ~ Dirichlet(ones(K))
Θ = Matrix(Diagonal(ones(eltype(Θ₁), K)))
Θ[:, 1] = Θ₁
# Set up HMM object
dists = [Categorical(Φ[:, i]) for i in axes(Φ, 2)]
hmm = HMM(init, permutedims(Θ), dists)
# Forward algorithm
Turing.@addlogprob! logdensityof(hmm, obs_seqs; seq_ends)
return (; hmm)
end
# This model fails with "failed to find valid initial parameters in 1000 tries. [...]"
model2 = hmm_trans_emiss_fixed(2, obs_seqs_concat, seq_ends)
chn2 = sample(model2, NUTS(), 500)
Description
Hi Turing.jl team!
I'm sorry to be back with another HMM-related issue. 🥲
In the example above, I am trying to build an HMM where specific transitions are forbidden. The scenario in the real data involves a sequence of problem solving behaviours which always end with either a success or a failure. Transitions out of these terminal states are impossible, and if a participant is in this state, it will always emit the observation corresponding to the terminal state.
In my simplified example above, I first only restrict the transition matrix to disallow transitions out of the terminal state. The second row is the terminal state, so I've set this to [0.0, 1.0]
.
This model runs and also picks up that the emission probabilities from the terminal state are effectively [0.0, 1.0]
.
If I try to set the emission probabilities of the terminal state to [0.0, 1.0]
, the model fails with failed to find valid initial parameters in 1000 tries. [...]
.
Thanks a lot for any help or tips!
PS: @gdalle already encountered this issue in a discourse post I made a little while back and did not know where this error came from. So I thought it's best to post it here.
Julia version info
versioninfo()
Julia Version 1.11.4
Commit 8561cc3d68d (2025-03-10 11:36 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: macOS (arm64-apple-darwin24.0.0)
CPU: 8 × Apple M1 Pro
WORD_SIZE: 64
LLVM: libLLVM-16.0.6 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 6 virtual cores)
Manifest
]st --manifest
Ran in a Pluto notebook with
Turing v0.37.0
HiddenMarkovModels v0.6.2