annotate toolboxes/FullBNT-1.0.7/bnt/CPDs/@mlp_CPD/mlp_CPD.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2, clamped, max_iter, verbose, wthresh, llthresh)
Daniel@0 2 % MLP_CPD Make a CPD from a Multi Layer Perceptron (i.e., feedforward neural network)
Daniel@0 3 %
Daniel@0 4 % We use a different MLP for each discrete parent combination (if there are any discrete parents).
Daniel@0 5 % We currently assume this node (the child) is discrete.
Daniel@0 6 %
Daniel@0 7 % CPD = mlp_CPD(bnet, self, nhidden)
Daniel@0 8 % will create a CPD with random parameters, where self is the number of this node and nhidden the number of the hidden nodes.
Daniel@0 9 % The params are drawn from N(0, s*I), where s = 1/sqrt(n+1), n = length(X).
Daniel@0 10 %
Daniel@0 11 % CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2) allows you to specify the params, where
Daniel@0 12 % w1 = first-layer weight matrix
Daniel@0 13 % b1 = first-layer bias vector
Daniel@0 14 % w2 = second-layer weight matrix
Daniel@0 15 % b2 = second-layer bias vector
Daniel@0 16 % These are assumed to be the same for each discrete parent combination.
Daniel@0 17 % If any of these are [], random values will be created.
Daniel@0 18 %
Daniel@0 19 % CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2, clamped) allows you to prevent the params from being
Daniel@0 20 % updated during learning (if clamped = 1). Default: clamped = 0.
Daniel@0 21 %
Daniel@0 22 % CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2, clamped, max_iter, verbose, wthresh, llthresh)
Daniel@0 23 % alllows you to specify params that control the M step:
Daniel@0 24 % max_iter - the maximum number of steps to take (default: 10)
Daniel@0 25 % verbose - controls whether to print (default: 0 means silent).
Daniel@0 26 % wthresh - a measure of the precision required for the value of
Daniel@0 27 % the weights W at the solution. Default: 1e-2.
Daniel@0 28 % llthresh - a measure of the precision required of the objective
Daniel@0 29 % function (log-likelihood) at the solution. Both this and the previous condition must
Daniel@0 30 % be satisfied for termination. Default: 1e-2.
Daniel@0 31 %
Daniel@0 32 % For learning, we use a weighted version of scaled conjugated gradient in the M step.
Daniel@0 33
Daniel@0 34 if nargin==0
Daniel@0 35 % This occurs if we are trying to load an object from a file.
Daniel@0 36 CPD = init_fields;
Daniel@0 37 CPD = class(CPD, 'mlp_CPD', discrete_CPD(0,[]));
Daniel@0 38 return;
Daniel@0 39 elseif isa(bnet, 'mlp_CPD')
Daniel@0 40 % This might occur if we are copying an object.
Daniel@0 41 CPD = bnet;
Daniel@0 42 return;
Daniel@0 43 end
Daniel@0 44 CPD = init_fields;
Daniel@0 45
Daniel@0 46 assert(myismember(self, bnet.dnodes));
Daniel@0 47 ns = bnet.node_sizes;
Daniel@0 48
Daniel@0 49 ps = parents(bnet.dag, self);
Daniel@0 50 dnodes = mysetdiff(1:length(bnet.dag), bnet.cnodes);
Daniel@0 51 dps = myintersect(ps, dnodes);
Daniel@0 52 cps = myintersect(ps, bnet.cnodes);
Daniel@0 53 dpsz = prod(ns(dps));
Daniel@0 54 cpsz = sum(ns(cps));
Daniel@0 55 self_size = ns(self);
Daniel@0 56
Daniel@0 57 % discrete/cts parent index - which ones of my parents are discrete/cts?
Daniel@0 58 CPD.dpndx = find_equiv_posns(dps, ps);
Daniel@0 59 CPD.cpndx = find_equiv_posns(cps, ps);
Daniel@0 60
Daniel@0 61 CPD.mlp = cell(1,dpsz);
Daniel@0 62 for i=1:dpsz
Daniel@0 63 CPD.mlp{i} = mlp(cpsz, nhidden, self_size, 'softmax');
Daniel@0 64 if nargin >=4 & ~isempty(w1)
Daniel@0 65 CPD.mlp{i}.w1 = w1;
Daniel@0 66 end
Daniel@0 67 if nargin >=5 & ~isempty(b1)
Daniel@0 68 CPD.mlp{i}.b1 = b1;
Daniel@0 69 end
Daniel@0 70 if nargin >=6 & ~isempty(w2)
Daniel@0 71 CPD.mlp{i}.w2 = w2;
Daniel@0 72 end
Daniel@0 73 if nargin >=7 & ~isempty(b2)
Daniel@0 74 CPD.mlp{i}.b2 = b2;
Daniel@0 75 end
Daniel@0 76 W1app(:,:,i)=CPD.mlp{i}.w1;
Daniel@0 77 W2app(:,:,i)=CPD.mlp{i}.w2;
Daniel@0 78 b1app(i,:)=CPD.mlp{i}.b1;
Daniel@0 79 b2app(i,:)=CPD.mlp{i}.b2;
Daniel@0 80 end
Daniel@0 81 if nargin < 8, clamped = 0; end
Daniel@0 82 if nargin < 9, max_iter = 10; end
Daniel@0 83 if nargin < 10, verbose = 0; end
Daniel@0 84 if nargin < 11, wthresh = 1e-2; end
Daniel@0 85 if nargin < 12, llthresh = 1e-2; end
Daniel@0 86
Daniel@0 87 CPD.self = self;
Daniel@0 88 CPD.max_iter = max_iter;
Daniel@0 89 CPD.verbose = verbose;
Daniel@0 90 CPD.wthresh = wthresh;
Daniel@0 91 CPD.llthresh = llthresh;
Daniel@0 92
Daniel@0 93 % sufficient statistics
Daniel@0 94 % Since MLP is not in the exponential family, we must store all the raw data.
Daniel@0 95 %
Daniel@0 96 CPD.W1=W1app; % Extract all the parameters of the node for handling discrete obs parents
Daniel@0 97 CPD.W2=W2app; %
Daniel@0 98 nparaW=[size(W1app) size(W2app)]; %
Daniel@0 99 CPD.b1=b1app; %
Daniel@0 100 CPD.b2=b2app; %
Daniel@0 101 nparab=[size(b1app) size(b2app)]; %
Daniel@0 102
Daniel@0 103 CPD.sizes=bnet.node_sizes(:); % used in CPD_to_table to pump up the node sizes
Daniel@0 104
Daniel@0 105 CPD.parent_vals = []; % X(l,:) = value of cts parents in l'th example
Daniel@0 106
Daniel@0 107 CPD.eso_weights=[]; % weights used by the SCG algorithm
Daniel@0 108
Daniel@0 109 CPD.self_vals = []; % Y(l,:) = value of self in l'th example
Daniel@0 110
Daniel@0 111 % For BIC
Daniel@0 112 CPD.nsamples = 0;
Daniel@0 113 CPD.nparams=prod(nparaW)+prod(nparab);
Daniel@0 114 CPD = class(CPD, 'mlp_CPD', discrete_CPD(clamped, ns([ps self])));
Daniel@0 115
Daniel@0 116 %%%%%%%%%%%
Daniel@0 117
Daniel@0 118 function CPD = init_fields()
Daniel@0 119 % This ensures we define the fields in the same order
Daniel@0 120 % no matter whether we load an object from a file,
Daniel@0 121 % or create it from scratch. (Matlab requires this.)
Daniel@0 122
Daniel@0 123 CPD.mlp = {};
Daniel@0 124 CPD.self = [];
Daniel@0 125 CPD.max_iter = [];
Daniel@0 126 CPD.verbose = [];
Daniel@0 127 CPD.wthresh = [];
Daniel@0 128 CPD.llthresh = [];
Daniel@0 129 CPD.approx_hess = [];
Daniel@0 130 CPD.W1 = [];
Daniel@0 131 CPD.W2 = [];
Daniel@0 132 CPD.b1 = [];
Daniel@0 133 CPD.b2 = [];
Daniel@0 134 CPD.sizes = [];
Daniel@0 135 CPD.parent_vals = [];
Daniel@0 136 CPD.eso_weights=[];
Daniel@0 137 CPD.self_vals = [];
Daniel@0 138 CPD.nsamples = [];
Daniel@0 139 CPD.nparams = [];