Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/bnt/CPDs/@hhmmQ_CPD/hhmmQ_CPD.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function CPD = hhmmQ_CPD(bnet, self, varargin) | |
2 % HHMMQ_CPD Make the CPD for a Q node in a hierarchical HMM | |
3 % CPD = hhmmQ_CPD(bnet, self, ...) | |
4 % | |
5 % Fself(t-1) Qps(t) | |
6 % \ | | |
7 % \ v | |
8 % Qold(t-1) -> Q(t) | |
9 % / | |
10 % / | |
11 % Fbelow(t-1) | |
12 % | |
13 % Let ss = slice size = num. nodes per slice. | |
14 % This node is Q(t), and has mandatory parents Qold(t-1) (assumed to be numbered Q(t)-ss) | |
15 % and optional parents Fbelow, Fself, Qps. | |
16 % We require parents to be ordered (numbered) as follows: | |
17 % Qold, Fbelow, Fself, Qps, Q. | |
18 % | |
19 % If Fself=2, we use the transition matrix, else we use the prior matrix. | |
20 % If Fself node is omitted (eg. top level), we always use the transition matrix. | |
21 % If Fbelow=2, we may change state, otherwise we must stay in the same state. | |
22 % If Fbelow node is omitted (eg., bottom level), we may change state at every step. | |
23 % If Qps (Q parents) are specified, all parameters are conditioned on their joint value. | |
24 % We may choose any subset of nodes to condition on, as long as they as numbered lower than self. | |
25 % | |
26 % optional args [defaults] | |
27 % | |
28 % Fself - node number <= ss | |
29 % Fbelow - node number <= ss | |
30 % Qps - node numbers (all <= 2*ss) - uses 2TBN indexing | |
31 % transprob - transprob(i,k,j) = prob transition from i to j given Qps = k ['leftright'] | |
32 % selfprob - prob of a transition from i to i given Qps=k [0.1] | |
33 % startprob - startprob(k,j) = prob start in j given Qps = k ['leftstart'] | |
34 % startargs - other args to be passed to the sub tabular_CPD for learning startprob | |
35 % transargs - other args will be passed to the sub tabular_CPD for learning transprob | |
36 % fullstartprob - 1 means startprob depends on Q(t-1) [0] | |
37 % hhmmQ_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc. | |
38 % | |
39 % We create isolated tabular_CPDs with no F parents to learn transprob/startprob | |
40 % so we can avail of e.g., entropic or Dirichlet priors. | |
41 % In the future, we will be able to represent the transprob using a tree_CPD. | |
42 % | |
43 % For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01. | |
44 | |
45 | |
46 ss = bnet.nnodes_per_slice; | |
47 ns = bnet.node_sizes(:); | |
48 | |
49 % set default arguments | |
50 Fself = []; | |
51 Fbelow = []; | |
52 Qps = []; | |
53 startprob = 'leftstart'; | |
54 transprob = 'leftright'; | |
55 startargs = {}; | |
56 transargs = {}; | |
57 selfprob = 0.1; | |
58 fullstartprob = 0; | |
59 | |
60 for i=1:2:length(varargin) | |
61 switch varargin{i}, | |
62 case 'Fself', Fself = varargin{i+1}; | |
63 case 'Fbelow', Fbelow = varargin{i+1}; | |
64 case 'Qps', Qps = varargin{i+1}; | |
65 case 'transprob', transprob = varargin{i+1}; | |
66 case 'selfprob', selfprob = varargin{i+1}; | |
67 case 'startprob', startprob = varargin{i+1}; | |
68 case 'startargs', startargs = varargin{i+1}; | |
69 case 'transargs', transargs = varargin{i+1}; | |
70 case 'fullstartprob', fullstartprob = varargin{i+1}; | |
71 end | |
72 end | |
73 | |
74 CPD.fullstartprob = fullstartprob; | |
75 | |
76 ps = parents(bnet.dag, self); | |
77 ndsz = ns(:)'; | |
78 CPD.dom_sz = [ndsz(ps) ns(self)]; | |
79 CPD.Fself_ndx = find_equiv_posns(Fself, ps); | |
80 CPD.Fbelow_ndx = find_equiv_posns(Fbelow, ps); | |
81 %CPD.Qps_ndx = find_equiv_posns(Qps+ss, ps); | |
82 CPD.Qps_ndx = find_equiv_posns(Qps, ps); | |
83 old_self = self-ss; | |
84 CPD.old_self_ndx = find_equiv_posns(old_self, ps); | |
85 | |
86 Qps = ps(CPD.Qps_ndx); | |
87 CPD.Qsz = ns(self); | |
88 CPD.Qpsz = prod(ns(Qps)); | |
89 CPD.Qpsizes = ns(Qps); | |
90 Qsz = CPD.Qsz; | |
91 Qpsz = CPD.Qpsz; | |
92 | |
93 if strcmp(transprob, 'leftright') | |
94 LR = mk_leftright_transmat(Qsz, selfprob); | |
95 transprob = repmat(reshape(LR, [1 Qsz Qsz]), [Qpsz 1 1]); % transprob(k,i,j) | |
96 transprob = permute(transprob, [2 1 3]); % now transprob(i,k,j) | |
97 end | |
98 transargs{end+1} = 'CPT'; | |
99 transargs{end+1} = transprob; | |
100 CPD.sub_CPD_trans = mk_isolated_tabular_CPD(ns([old_self Qps self]), transargs); | |
101 S = struct(CPD.sub_CPD_trans); | |
102 %CPD.transprob = myreshape(S.CPT, [Qsz Qpsz Qsz]); | |
103 CPD.transprob = S.CPT; | |
104 | |
105 | |
106 if strcmp(startprob, 'leftstart') | |
107 startprob = zeros(Qpsz, Qsz); | |
108 startprob(:,1) = 1; | |
109 end | |
110 if isempty(CPD.Fself_ndx) | |
111 CPD.sub_CPD_start = []; | |
112 CPD.startprob = []; | |
113 else | |
114 startargs{end+1} = 'CPT'; | |
115 startargs{end+1} = startprob; | |
116 if CPD.fullstartprob | |
117 CPD.sub_CPD_start = mk_isolated_tabular_CPD(ns([self Qps self]), startargs); | |
118 S = struct(CPD.sub_CPD_start); | |
119 %CPD.startprob = myreshape(S.CPT, [Qsz Qpsz Qsz]); | |
120 CPD.startprob = S.CPT; | |
121 else | |
122 CPD.sub_CPD_start = mk_isolated_tabular_CPD(ns([Qps self]), startargs); | |
123 S = struct(CPD.sub_CPD_start); | |
124 %CPD.startprob = myreshape(S.CPT, [CPD.Qpsizes Qsz]); | |
125 CPD.startprob = S.CPT; | |
126 end | |
127 end | |
128 | |
129 CPD = class(CPD, 'hhmmQ_CPD', tabular_CPD(bnet, self)); | |
130 | |
131 CPD = update_CPT(CPD); | |
132 |