wolffd@0: % a multigram is a degenerate 2HHMM where the bottom level HMMs emit deterministic strings wolffd@0: % and the the top level abstract states are independent of each other wolffd@0: % cf. HSMM/test_mgram2 wolffd@0: wolffd@0: words = {'the', 't', 'h', 'e'}; wolffd@0: data = 'the'; wolffd@0: nwords = length(words); wolffd@0: word_len = zeros(1, nwords); wolffd@0: word_prob = normalise(ones(1,nwords)); wolffd@0: word_logprob = log(word_prob); wolffd@0: for wi=1:nwords wolffd@0: word_len(wi)=length(words{wi}); wolffd@0: end wolffd@0: D = max(word_len); wolffd@0: wolffd@0: alphasize = 26; wolffd@0: data = letter2num(data); wolffd@0: T = length(data); wolffd@0: wolffd@0: % node numbers wolffd@0: W = 1; % top level state = word id wolffd@0: L = 2; % bottom level state = letter position within word wolffd@0: F = 3; wolffd@0: O = 4; wolffd@0: wolffd@0: ss = 4; wolffd@0: intra = zeros(ss,ss); wolffd@0: intra(W,[F L O])=1; wolffd@0: intra(L,[O F])=1; wolffd@0: wolffd@0: inter = zeros(ss,ss); wolffd@0: inter(W,W)=1; wolffd@0: inter(L,L)=1; wolffd@0: inter(F,[W L])=1; wolffd@0: wolffd@0: % node sizes wolffd@0: ns = zeros(1,ss); wolffd@0: ns(W) = nwords; wolffd@0: ns(L) = D; wolffd@0: ns(F) = 2; wolffd@0: ns(O) = alphasize; wolffd@0: wolffd@0: wolffd@0: % Make the DBN wolffd@0: bnet = mk_dbn(intra, inter, ns, 'observed', O); wolffd@0: eclass = bnet.equiv_class; wolffd@0: wolffd@0: wolffd@0: wolffd@0: % uniform start distrib over words, uniform trans mat wolffd@0: Wstart = normalise(ones(1,nwords)); wolffd@0: Wtrans = mk_stochastic(ones(nwords,nwords)); wolffd@0: wolffd@0: % always start in state 1 for each bottom level HMM wolffd@0: delta1_start = zeros(1, D); wolffd@0: delta1_start(1) = 1; wolffd@0: Lstart = repmat(delta1_start, nwords, 1); wolffd@0: LRtrans = mk_leftright_transmat(D, 0); % 0 self loop prob wolffd@0: Ltrans = repmat(LRtrans, [1 1 nwords]); wolffd@0: wolffd@0: % Finish in the last letter of each word wolffd@0: Fprob = zeros(nwords, D, 2); wolffd@0: Fprob(:,:,1)=1; wolffd@0: for i=1:nwords wolffd@0: Fprob(i,length(words{i}),2)=1; wolffd@0: Fprob(i,length(words{i}),1)=0; wolffd@0: end wolffd@0: wolffd@0: % Each state uniquely emits a letter wolffd@0: Oprob = zeros(nwords, D, alphasize); wolffd@0: for i=1:nwords wolffd@0: for l=1:length(words{i}) wolffd@0: a = double(words{i}(l))-96; wolffd@0: Oprob(i,l,a)=1; wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: wolffd@0: % Define CPDs for slice wolffd@0: bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart); wolffd@0: bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart); wolffd@0: bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob); wolffd@0: bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob); wolffd@0: wolffd@0: % Define CPDs for slice 2 wolffd@0: bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart, 'transprob', Wtrans); wolffd@0: bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans); wolffd@0: wolffd@0: evidence = cell(ss,T); wolffd@0: evidence{W,1}=1; wolffd@0: sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence)); wolffd@0: str = lower(sample(4,:)) wolffd@0: wolffd@0: engine = jtree_dbn_inf_engine(bnet); wolffd@0: evidence = cell(ss,T); wolffd@0: evidence(O,:) = num2cell(data); wolffd@0: [engine, ll_dbn] = enter_evidence(engine, evidence); wolffd@0: wolffd@0: gamma = zeros(nwords, T); wolffd@0: for t=1:T wolffd@0: m = marginal_nodes(engine, [W F], t); wolffd@0: gamma(:,t) = m.T(:,2); wolffd@0: end wolffd@0: gamma wolffd@0: wolffd@0: xidbn = zeros(nwords, nwords); wolffd@0: for t=1:T-1 wolffd@0: m = marginal_nodes(engine, [W F W+ss], t); wolffd@0: xidbn = xidbn + squeeze(m.T(:,2,:)); wolffd@0: end wolffd@0: wolffd@0: % thee wolffd@0: % xidbn(1,4) = 0.9412 the->e wolffd@0: % (2,3)=0.0588 t->h wolffd@0: % (3,4)=0.0588 h-e wolffd@0: % (4,4)=0.0588 e-e