wolffd@0
|
1 % make a factor graph corresponding to an HMM, where we absorb the evidence up front,
|
wolffd@0
|
2 % and then eliminate the observed nodes.
|
wolffd@0
|
3 % Compare this with not absorbing the evidence.
|
wolffd@0
|
4
|
wolffd@0
|
5 seed = 1;
|
wolffd@0
|
6 rand('state', seed);
|
wolffd@0
|
7 randn('state', seed);
|
wolffd@0
|
8
|
wolffd@0
|
9 T = 3;
|
wolffd@0
|
10 Q = 3;
|
wolffd@0
|
11 O = 2;
|
wolffd@0
|
12 cts_obs = 0;
|
wolffd@0
|
13 param_tying = 1;
|
wolffd@0
|
14 bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying);
|
wolffd@0
|
15 N = 2*T;
|
wolffd@0
|
16 onodes = bnet.observed;
|
wolffd@0
|
17 hnodes = mysetdiff(1:N, onodes);
|
wolffd@0
|
18
|
wolffd@0
|
19 data = sample_bnet(bnet);
|
wolffd@0
|
20
|
wolffd@0
|
21 init_factor = bnet.CPD{1};
|
wolffd@0
|
22 obs_factor = bnet.CPD{3};
|
wolffd@0
|
23 edge_factor = bnet.CPD{2}; % trans matrix
|
wolffd@0
|
24
|
wolffd@0
|
25 nfactors = T;
|
wolffd@0
|
26 nvars = T; % hidden only
|
wolffd@0
|
27 G = zeros(nvars, nfactors);
|
wolffd@0
|
28 G(1,1) = 1;
|
wolffd@0
|
29 for t=1:T-1
|
wolffd@0
|
30 G(t:t+1, t+1)=1;
|
wolffd@0
|
31 end
|
wolffd@0
|
32
|
wolffd@0
|
33 node_sizes = Q*ones(1,T);
|
wolffd@0
|
34
|
wolffd@0
|
35 % We tie params as follows:
|
wolffd@0
|
36 % the first hidden node use init_factor (number 1)
|
wolffd@0
|
37 % all hidden nodes on the backbone use edge_factor (number 2)
|
wolffd@0
|
38 % all observed nodes use the same factor, namely obs_factor
|
wolffd@0
|
39
|
wolffd@0
|
40 small_fg = mk_fgraph_given_ev(G, node_sizes, {init_factor, edge_factor}, {obs_factor}, data(onodes), ...
|
wolffd@0
|
41 'equiv_class', [1 2*ones(1,T-1)], 'ev_equiv_class', ones(1,T));
|
wolffd@0
|
42
|
wolffd@0
|
43 small_bnet = fgraph_to_bnet(small_fg);
|
wolffd@0
|
44
|
wolffd@0
|
45 % don't pre-process evidence
|
wolffd@0
|
46 big_fg = bnet_to_fgraph(bnet);
|
wolffd@0
|
47 big_bnet = fgraph_to_bnet(big_fg);
|
wolffd@0
|
48
|
wolffd@0
|
49
|
wolffd@0
|
50
|
wolffd@0
|
51 engine = {};
|
wolffd@0
|
52 engine{1} = jtree_inf_engine(bnet);
|
wolffd@0
|
53 engine{2} = belprop_fg_inf_engine(small_fg, 'max_iter', 2*T);
|
wolffd@0
|
54 engine{3} = jtree_inf_engine(small_bnet);
|
wolffd@0
|
55 engine{4} = belprop_fg_inf_engine(big_fg, 'max_iter', 3*T);
|
wolffd@0
|
56 engine{5} = jtree_inf_engine(big_bnet);
|
wolffd@0
|
57 nengines = length(engine);
|
wolffd@0
|
58
|
wolffd@0
|
59
|
wolffd@0
|
60 % on BN, use the original evidence
|
wolffd@0
|
61 evidence = cell(1, 2*T);
|
wolffd@0
|
62 evidence(onodes) = data(onodes);
|
wolffd@0
|
63 tic; [engine{1}, ll(1)] = enter_evidence(engine{1}, evidence); toc
|
wolffd@0
|
64
|
wolffd@0
|
65
|
wolffd@0
|
66 % on small_fg, we have already included the evidence
|
wolffd@0
|
67 evidence = cell(1,T);
|
wolffd@0
|
68 tic; [engine{2}, ll(2)] = enter_evidence(engine{2}, evidence); toc
|
wolffd@0
|
69
|
wolffd@0
|
70
|
wolffd@0
|
71 % on small_bnet, we must add evidence to the dummy nodes
|
wolffd@0
|
72 V = small_fg.nvars;
|
wolffd@0
|
73 dummy = V+1:V+small_fg.nfactors;
|
wolffd@0
|
74 N = max(dummy);
|
wolffd@0
|
75 evidence = cell(1, N);
|
wolffd@0
|
76 evidence(dummy) = {1};
|
wolffd@0
|
77 tic; [engine{3}, ll(3)] = enter_evidence(engine{3}, evidence); toc
|
wolffd@0
|
78
|
wolffd@0
|
79
|
wolffd@0
|
80 % on big_fg, use the original evidence
|
wolffd@0
|
81 evidence = cell(1, 2*T);
|
wolffd@0
|
82 evidence(onodes) = data(onodes);
|
wolffd@0
|
83 tic; [engine{4}, ll(4)] = enter_evidence(engine{4}, evidence); toc
|
wolffd@0
|
84
|
wolffd@0
|
85
|
wolffd@0
|
86 % on big_bnet, we must add evidence to the dummy nodes
|
wolffd@0
|
87 V = big_fg.nvars;
|
wolffd@0
|
88 assert(V == 2*T);
|
wolffd@0
|
89 dummy = V+1:V+big_fg.nfactors;
|
wolffd@0
|
90 N = max(dummy);
|
wolffd@0
|
91 evidence = cell(1, N);
|
wolffd@0
|
92 evidence(onodes) = data(onodes);
|
wolffd@0
|
93 evidence(dummy) = {1};
|
wolffd@0
|
94 tic; [engine{5}, ll(5)] = enter_evidence(engine{5}, evidence); toc
|
wolffd@0
|
95
|
wolffd@0
|
96
|
wolffd@0
|
97 marg = zeros(T, nengines, Q); % marg(t,e,:)
|
wolffd@0
|
98 for t=1:T
|
wolffd@0
|
99 for e=1:nengines
|
wolffd@0
|
100 m = marginal_nodes(engine{e}, t);
|
wolffd@0
|
101 marg(t,e,:) = m.T;
|
wolffd@0
|
102 end
|
wolffd@0
|
103 end
|
wolffd@0
|
104 marg(:,:,1)
|