wolffd@0
|
1 % like mgram2, except we unroll the DBN so we can use smaller
|
wolffd@0
|
2 % state spaces for the early duration nodes:
|
wolffd@0
|
3 % the state spaces are D1 in {1}, D2 in {1,2}
|
wolffd@0
|
4
|
wolffd@0
|
5 past = 1;
|
wolffd@0
|
6
|
wolffd@0
|
7 words = {'the', 't', 'h', 'e'};
|
wolffd@0
|
8 data = 'the';
|
wolffd@0
|
9 nwords = length(words);
|
wolffd@0
|
10 word_len = zeros(1, nwords);
|
wolffd@0
|
11 word_prob = normalise(ones(1,nwords));
|
wolffd@0
|
12 word_logprob = log(word_prob);
|
wolffd@0
|
13 for wi=1:nwords
|
wolffd@0
|
14 word_len(wi)=length(words{wi});
|
wolffd@0
|
15 end
|
wolffd@0
|
16 D = max(word_len);
|
wolffd@0
|
17
|
wolffd@0
|
18
|
wolffd@0
|
19 alphasize = 26*2;
|
wolffd@0
|
20 data = letter2num(data);
|
wolffd@0
|
21 T = length(data);
|
wolffd@0
|
22
|
wolffd@0
|
23 % node numbers
|
wolffd@0
|
24 W = 1; % top level state = word id
|
wolffd@0
|
25 L = 2; % bottom level state = letter position within word
|
wolffd@0
|
26 F = 3;
|
wolffd@0
|
27 O = 4;
|
wolffd@0
|
28
|
wolffd@0
|
29 ss = 4;
|
wolffd@0
|
30 intra = zeros(ss,ss);
|
wolffd@0
|
31 intra(W,[F L O])=1;
|
wolffd@0
|
32 intra(L,[O F])=1;
|
wolffd@0
|
33
|
wolffd@0
|
34 inter = zeros(ss,ss);
|
wolffd@0
|
35 inter(W,W)=1;
|
wolffd@0
|
36 inter(L,L)=1;
|
wolffd@0
|
37 inter(F,[W L O])=1;
|
wolffd@0
|
38
|
wolffd@0
|
39 T = 3;
|
wolffd@0
|
40 dag = unroll_dbn_topology(intra, inter, T);
|
wolffd@0
|
41
|
wolffd@0
|
42 % node sizes
|
wolffd@0
|
43 ns = zeros(1,ss);
|
wolffd@0
|
44 ns(W) = nwords;
|
wolffd@0
|
45 ns(L) = D;
|
wolffd@0
|
46 ns(F) = 2;
|
wolffd@0
|
47 ns(O) = alphasize;
|
wolffd@0
|
48 ns = repmat(ns(:), [1 T]);
|
wolffd@0
|
49 for d=1:D
|
wolffd@0
|
50 ns(d,L)=d; % max duration
|
wolffd@0
|
51 end
|
wolffd@0
|
52 ns = ns(:);
|
wolffd@0
|
53
|
wolffd@0
|
54 % Equiv class in brackets for D=3
|
wolffd@0
|
55 % The Lt's are not tied until t>=D, since they have different sizes.
|
wolffd@0
|
56 % W1 and W2 are not tied since they have different parent sets.
|
wolffd@0
|
57
|
wolffd@0
|
58 % W1 (1) W2 (5) W3 (5) W4 (5)
|
wolffd@0
|
59 % L1 (2) L2 (6) L3 (7) L4 (7)
|
wolffd@0
|
60 % F1 (3) F2 (3) F3 (4) F3 (4)
|
wolffd@0
|
61 % O1 (4) O2 (4) O2 (4) O4 (4)
|
wolffd@0
|
62
|
wolffd@0
|
63 % Since we are not learning, we can dispense with tying
|
wolffd@0
|
64
|
wolffd@0
|
65 % Make the bnet
|
wolffd@0
|
66 Wnodes = unroll_set(W, ss, T);
|
wolffd@0
|
67 Lnodes = unroll_set(L, ss, T);
|
wolffd@0
|
68 Fnodes = unroll_set(F, ss, T);
|
wolffd@0
|
69 Onodes = unroll_set(O, ss, T);
|
wolffd@0
|
70
|
wolffd@0
|
71 bnet = mk_bnet(dag, ns);
|
wolffd@0
|
72 eclass = bnet.equiv_class;
|
wolffd@0
|
73
|
wolffd@0
|
74 % uniform start distrib over words, uniform trans mat
|
wolffd@0
|
75 Wstart = normalise(ones(1,nwords));
|
wolffd@0
|
76 Wtrans = mk_stochastic(ones(nwords,nwords));
|
wolffd@0
|
77 bnet.CPD{eclass(Wnodes(1))} = tabular_CPD(bnet, Wnodes(1), 'CPT', Wstart);
|
wolffd@0
|
78 for t=2:T
|
wolffd@0
|
79 bnet.CPD{eclass(Wnodes(t))} = hhmmQ_CPD(bnet, Wnodes(t), 'Fbelow', Fnodes(t-1), ...
|
wolffd@0
|
80 'startprob', Wstart, 'transprob', Wtrans);
|
wolffd@0
|
81 end
|
wolffd@0
|
82
|
wolffd@0
|
83 % always start in state d = length(word) for each bottom level HMM
|
wolffd@0
|
84 % and then count down
|
wolffd@0
|
85 % make downcounters
|
wolffd@0
|
86 RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
|
wolffd@0
|
87 Ltrans = repmat(RLtrans, [1 1 nwords]);
|
wolffd@0
|
88
|
wolffd@0
|
89 for t=1:T
|
wolffd@0
|
90 Lstart = zeros(nwords, min(t,D));
|
wolffd@0
|
91 for i=1:nwords
|
wolffd@0
|
92 l = length(words{i});
|
wolffd@0
|
93 Lstart(i,l)=1;
|
wolffd@0
|
94 if d==1
|
wolffd@0
|
95 bnet.CPD{eclass(Lnodes(1))} = tabular_CPD(bnet, Lnodes(1), 'CPT', Lstart);
|
wolffd@0
|
96 else
|
wolffd@0
|
97 bnet.CPD{eclass(Lnodes(t))} = hhmmQ_CPD(bnet, Lnodes(t), 'Fself', Fnodes(t-1), 'Qps', Wnodes(t), ...
|
wolffd@0
|
98 'startprob', Lstart, 'transprob', Ltrans);
|
wolffd@0
|
99 end
|
wolffd@0
|
100 end
|
wolffd@0
|
101 end
|
wolffd@0
|
102
|
wolffd@0
|
103
|
wolffd@0
|
104 % Finish when downcoutner = 1
|
wolffd@0
|
105 Fprob = zeros(nwords, D, 2);
|
wolffd@0
|
106 Fprob(:,1,2)=1;
|
wolffd@0
|
107 Fprob(:,2:end,1)=1;
|
wolffd@0
|
108
|
wolffd@0
|
109
|
wolffd@0
|
110 % Define CPDs for slice
|
wolffd@0
|
111 bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
|
wolffd@0
|
112 bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
|
wolffd@0
|
113 bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
|
wolffd@0
|
114
|
wolffd@0
|
115
|
wolffd@0
|
116 % Define CPDs for slice 2
|
wolffd@0
|
117 bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart, 'transprob', Wtrans);
|
wolffd@0
|
118 bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
|
wolffd@0
|
119
|
wolffd@0
|
120
|
wolffd@0
|
121 if 0
|
wolffd@0
|
122 % To test it is generating correctly, we create an artificial
|
wolffd@0
|
123 % observation process that capitalizes at the start of a new segment
|
wolffd@0
|
124 % Oprob(Ft-1,Qt,Dt,Yt)
|
wolffd@0
|
125 Oprob = zeros(2,nwords,D,alphasize);
|
wolffd@0
|
126 Oprob(1,1,3,letter2num('t'),1)=1;
|
wolffd@0
|
127 Oprob(1,1,2,letter2num('h'),1)=1;
|
wolffd@0
|
128 Oprob(1,1,1,letter2num('e'),1)=1;
|
wolffd@0
|
129 Oprob(2,1,3,letter2num('T'),1)=1;
|
wolffd@0
|
130 Oprob(2,1,2,letter2num('H'),1)=1;
|
wolffd@0
|
131 Oprob(2,1,1,letter2num('E'),1)=1;
|
wolffd@0
|
132 Oprob(1,2,1,letter2num('a'),1)=1;
|
wolffd@0
|
133 Oprob(2,2,1,letter2num('A'),1)=1;
|
wolffd@0
|
134 Oprob(1,3,1,letter2num('b'),1)=1;
|
wolffd@0
|
135 Oprob(2,3,1,letter2num('B'),1)=1;
|
wolffd@0
|
136 Oprob(1,4,1,letter2num('c'),1)=1;
|
wolffd@0
|
137 Oprob(2,4,1,letter2num('C'),1)=1;
|
wolffd@0
|
138
|
wolffd@0
|
139 % Oprob1(Qt,Dt,Yt)
|
wolffd@0
|
140 Oprob1 = zeros(nwords,D,alphasize);
|
wolffd@0
|
141 Oprob1(1,3,letter2num('t'),1)=1;
|
wolffd@0
|
142 Oprob1(1,2,letter2num('h'),1)=1;
|
wolffd@0
|
143 Oprob1(1,1,letter2num('e'),1)=1;
|
wolffd@0
|
144 Oprob1(2,1,letter2num('a'),1)=1;
|
wolffd@0
|
145 Oprob1(3,1,letter2num('b'),1)=1;
|
wolffd@0
|
146 Oprob1(4,1,letter2num('c'),1)=1;
|
wolffd@0
|
147
|
wolffd@0
|
148 bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
|
wolffd@0
|
149 bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
|
wolffd@0
|
150
|
wolffd@0
|
151 evidence = cell(ss,T);
|
wolffd@0
|
152 %evidence{W,1}=1;
|
wolffd@0
|
153 sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
|
wolffd@0
|
154 str = num2letter(sample(4,:))
|
wolffd@0
|
155 end
|
wolffd@0
|
156
|
wolffd@0
|
157
|
wolffd@0
|
158
|
wolffd@0
|
159
|
wolffd@0
|
160 [log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
|
wolffd@0
|
161 % obslik(j,t,d)
|
wolffd@0
|
162 softCPDpot = cell(ss,T);
|
wolffd@0
|
163 ens = ns;
|
wolffd@0
|
164 ens(O)=1;
|
wolffd@0
|
165 ens2 = [ens ens];
|
wolffd@0
|
166 for t=2:T
|
wolffd@0
|
167 dom = [F W+ss L+ss O+ss];
|
wolffd@0
|
168 % tab(Ft-1, Q2, Dt)
|
wolffd@0
|
169 tab = ones(2, nwords, D);
|
wolffd@0
|
170 if past
|
wolffd@0
|
171 tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
|
wolffd@0
|
172 %tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
|
wolffd@0
|
173 for d=1:min(t,D)
|
wolffd@0
|
174 tab(2,:,d) = squeeze(obslik(:,t,d));
|
wolffd@0
|
175 end
|
wolffd@0
|
176 else
|
wolffd@0
|
177 for d=1:max(1,min(D,T+1-t))
|
wolffd@0
|
178 tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
|
wolffd@0
|
179 end
|
wolffd@0
|
180 end
|
wolffd@0
|
181 softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
|
wolffd@0
|
182 end
|
wolffd@0
|
183 t = 1;
|
wolffd@0
|
184 dom = [W L O];
|
wolffd@0
|
185 % tab(Q2, Dt)
|
wolffd@0
|
186 tab = ones(nwords, D);
|
wolffd@0
|
187 if past
|
wolffd@0
|
188 %tab = squeeze(obslik(:,t,:));
|
wolffd@0
|
189 tab(:,1) = squeeze(obslik(:,t,1));
|
wolffd@0
|
190 else
|
wolffd@0
|
191 for d=1:min(D,T-t)
|
wolffd@0
|
192 tab(:,d) = squeeze(obslik(:,t+d-1,d));
|
wolffd@0
|
193 end
|
wolffd@0
|
194 end
|
wolffd@0
|
195 softCPDpot{O,t} = dpot(dom, ens(dom), tab);
|
wolffd@0
|
196
|
wolffd@0
|
197
|
wolffd@0
|
198 %bnet.observed = [];
|
wolffd@0
|
199 % uniformative observations
|
wolffd@0
|
200 %bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
|
wolffd@0
|
201 %bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
|
wolffd@0
|
202
|
wolffd@0
|
203 engine = jtree_dbn_inf_engine(bnet);
|
wolffd@0
|
204 evidence = cell(ss,T);
|
wolffd@0
|
205 % we add dummy data to O to force its effective size to be 1.
|
wolffd@0
|
206 % The actual values have already been incorporated into softCPDpot
|
wolffd@0
|
207 evidence(O,:) = num2cell(ones(1,T));
|
wolffd@0
|
208 [engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
|
wolffd@0
|
209
|
wolffd@0
|
210
|
wolffd@0
|
211 %evidence(F,:) = num2cell(2*ones(1,T));
|
wolffd@0
|
212 %[engine, ll_dbn] = enter_evidence(engine, evidence);
|
wolffd@0
|
213
|
wolffd@0
|
214
|
wolffd@0
|
215 gamma = zeros(nwords, T);
|
wolffd@0
|
216 for t=1:T
|
wolffd@0
|
217 m = marginal_nodes(engine, [W F], t);
|
wolffd@0
|
218 gamma(:,t) = m.T(:,2);
|
wolffd@0
|
219 end
|
wolffd@0
|
220
|
wolffd@0
|
221 gamma
|
wolffd@0
|
222
|
wolffd@0
|
223 xidbn = zeros(nwords, nwords);
|
wolffd@0
|
224 for t=1:T-1
|
wolffd@0
|
225 m = marginal_nodes(engine, [W F W+ss], t);
|
wolffd@0
|
226 xidbn = xidbn + squeeze(m.T(:,2,:));
|
wolffd@0
|
227 end
|
wolffd@0
|
228
|
wolffd@0
|
229 % thee
|
wolffd@0
|
230 % xidbn(1,4) = 0.9412 the->e
|
wolffd@0
|
231 % (2,3)=0.0588 t->h
|
wolffd@0
|
232 % (3,4)=0.0588 h-e
|
wolffd@0
|
233 % (4,4)=0.0588 e-e
|
wolffd@0
|
234
|
wolffd@0
|
235
|