|
| 1 | +using StatsFuns: logsumexp |
| 2 | + |
| 3 | +# Set up hyperparameters |
| 4 | +K, v, T, T_unsup = 5, 20, 100, 200 |
| 5 | +alpha = fill(1.0, K) |
| 6 | +beta = fill(0.1, v) |
| 7 | +theta = rand(Dirichlet(alpha), K) |
| 8 | +phi = rand(Dirichlet(beta), K) |
| 9 | + |
| 10 | +# Simulate data (supervised) |
| 11 | +w = Vector{Int}(undef, T) |
| 12 | +z = Vector{Int}(undef, T) |
| 13 | +z[1] = rand(1:K) |
| 14 | +w[1] = rand(Categorical(phi[:, z[1]])) |
| 15 | +for t in 2:T |
| 16 | + z[t] = rand(Categorical(theta[:, z[t - 1]])) |
| 17 | + w[t] = rand(Categorical(phi[:, z[t]])) |
| 18 | +end |
| 19 | + |
| 20 | +# Unsupervised |
| 21 | +u = Vector{Int}(undef, T_unsup) |
| 22 | +y = Vector{Int}(undef, T_unsup) |
| 23 | +y[1] = rand(1:K) |
| 24 | +u[1] = rand(Categorical(phi[:, y[1]])) |
| 25 | +for t in 2:T_unsup |
| 26 | + y[t] = rand(Categorical(theta[:, y[t - 1]])) |
| 27 | + u[t] = rand(Categorical(phi[:, y[t]])) |
| 28 | +end |
| 29 | + |
| 30 | +@model function dppl_hmm_semisup(K, T, T_unsup, w, z, u, alpha, beta) |
| 31 | + theta ~ filldist(Dirichlet(alpha), K) |
| 32 | + phi ~ filldist(Dirichlet(beta), K) |
| 33 | + for t in 1:T |
| 34 | + w[t] ~ Categorical(phi[:, z[t]]); |
| 35 | + end |
| 36 | + for t in 2:T |
| 37 | + z[t] ~ Categorical(theta[:, z[t - 1]]); |
| 38 | + end |
| 39 | + |
| 40 | + TF = eltype(theta) |
| 41 | + acc = similar(alpha, TF, K) |
| 42 | + gamma = similar(alpha, TF, K) |
| 43 | + temp_gamma = similar(alpha, TF, K) |
| 44 | + for k in 1:K |
| 45 | + gamma[k] = log(phi[u[1],k]) |
| 46 | + end |
| 47 | + for t in 2:T_unsup |
| 48 | + for k in 1:K |
| 49 | + for j in 1:K |
| 50 | + acc[j] = gamma[j] + log(theta[k, j]) + log(phi[u[t], k]) |
| 51 | + end |
| 52 | + temp_gamma[k] = logsumexp(acc) |
| 53 | + end |
| 54 | + gamma .= temp_gamma |
| 55 | + end |
| 56 | + @addlogprob! logsumexp(gamma) |
| 57 | +end |
| 58 | + |
| 59 | +model = dppl_hmm_semisup(K, T, T_unsup, w, z, u, alpha, beta) |
0 commit comments