Daniel@0: function [time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, T, varargin) Daniel@0: % CMP_LEARNING_DBN Compare a bunch of inference engines by learning a DBN Daniel@0: % function [time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, exact, T, ncases, max_iter) Daniel@0: % Daniel@0: % engine{i} is the i'th inference engine. Daniel@0: % time(e) = elapsed time for doing inference with engine e Daniel@0: % CPD{e,c} is the learned CPD for eclass c in engine e Daniel@0: % LL{e} is the learning curve for engine e Daniel@0: % cases{i} is the i'th training case Daniel@0: % Daniel@0: % The list below gives optional arguments [default value in brackets]. Daniel@0: % Daniel@0: % exact - specifies which engines do exact inference [ 1:length(engine) ] Daniel@0: % check_ll - 1 means we check that the log-likelihoods are correct [1] Daniel@0: % ncases - num. random training cases [2] Daniel@0: % max_iter - max. num EM iterations [2] Daniel@0: Daniel@0: % set default params Daniel@0: exact = 1:length(engine); Daniel@0: check_ll = 1; Daniel@0: ncases = 2; Daniel@0: max_iter = 2; Daniel@0: Daniel@0: args = varargin; Daniel@0: nargs = length(args); Daniel@0: for i=1:2:nargs Daniel@0: switch args{i}, Daniel@0: case 'exact', exact = args{i+1}; Daniel@0: case 'check_ll', check_ll = args{i+1}; Daniel@0: case 'ncases', ncases = args{i+1}; Daniel@0: case 'max_iter', max_iter = args{i+1}; Daniel@0: otherwise, Daniel@0: error(['unrecognized argument ' args{i}]) Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: E = length(engine); Daniel@0: ss = length(bnet.intra); Daniel@0: onodes = bnet.observed; Daniel@0: Daniel@0: cases = cell(1, ncases); Daniel@0: for i=1:ncases Daniel@0: ev = sample_dbn(bnet, 'length', T); Daniel@0: cases{i} = cell(ss,T); Daniel@0: cases{i}(onodes,:) = ev(onodes, :); Daniel@0: end Daniel@0: Daniel@0: LL = cell(1,E); Daniel@0: time = zeros(1,E); Daniel@0: for i=1:E Daniel@0: tic Daniel@0: [bnet2{i}, LL{i}] = learn_params_dbn_em(engine{i}, cases, 'max_iter', max_iter); Daniel@0: time(i) = toc; Daniel@0: fprintf('engine %d took %6.4f seconds\n', i, time(i)); Daniel@0: end Daniel@0: Daniel@0: ref = exact(1); % reference Daniel@0: cmp = mysetdiff(exact, ref); Daniel@0: if check_ll Daniel@0: for i=cmp(:)' Daniel@0: if ~approxeq(LL{ref}, LL{i}) Daniel@0: error(['engine ' num2str(i) ' has wrong ll']) Daniel@0: end Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: nCPDs = length(bnet.CPD); Daniel@0: CPD = cell(E, nCPDs); Daniel@0: tabular = zeros(1, nCPDs); Daniel@0: for i=1:E Daniel@0: temp = bnet2{i}; Daniel@0: for c=1:nCPDs Daniel@0: tabular(c) = isa(temp.CPD{c}, 'tabular_CPD'); Daniel@0: CPD{i,c} = struct(temp.CPD{c}); Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: for i=cmp(:)' Daniel@0: for c=1:nCPDs Daniel@0: if tabular(c) Daniel@0: assert(approxeq(CPD{i,c}.CPT, CPD{ref,c}.CPT)); Daniel@0: else Daniel@0: assert(approxeq(CPD{i,c}.mean, CPD{ref,c}.mean)); Daniel@0: assert(approxeq(CPD{i,c}.cov, CPD{ref,c}.cov)); Daniel@0: assert(approxeq(CPD{i,c}.weights, CPD{ref,c}.weights)); Daniel@0: end Daniel@0: end Daniel@0: end Daniel@0: