annotate toolboxes/FullBNT-1.0.7/netlab3.3/evidence.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 [net, gamma, logev] = evidence(net, x, t, num)
Daniel@0 2 %EVIDENCE Re-estimate hyperparameters using evidence approximation.
Daniel@0 3 %
Daniel@0 4 % Description
Daniel@0 5 % [NET] = EVIDENCE(NET, X, T) re-estimates the hyperparameters ALPHA
Daniel@0 6 % and BETA by applying Bayesian re-estimation formulae for NUM
Daniel@0 7 % iterations. The hyperparameter ALPHA can be a simple scalar
Daniel@0 8 % associated with an isotropic prior on the weights, or can be a vector
Daniel@0 9 % in which each component is associated with a group of weights as
Daniel@0 10 % defined by the INDEX matrix in the NET data structure. These more
Daniel@0 11 % complex priors can be set up for an MLP using MLPPRIOR. Initial
Daniel@0 12 % values for the iterative re-estimation are taken from the network
Daniel@0 13 % data structure NET passed as an input argument, while the return
Daniel@0 14 % argument NET contains the re-estimated values.
Daniel@0 15 %
Daniel@0 16 % [NET, GAMMA, LOGEV] = EVIDENCE(NET, X, T, NUM) allows the re-
Daniel@0 17 % estimation formula to be applied for NUM cycles in which the re-
Daniel@0 18 % estimated values for the hyperparameters from each cycle are used to
Daniel@0 19 % re-evaluate the Hessian matrix for the next cycle. The return value
Daniel@0 20 % GAMMA is the number of well-determined parameters and LOGEV is the
Daniel@0 21 % log of the evidence.
Daniel@0 22 %
Daniel@0 23 % See also
Daniel@0 24 % MLPPRIOR, NETGRAD, NETHESS, DEMEV1, DEMARD
Daniel@0 25 %
Daniel@0 26
Daniel@0 27 % Copyright (c) Ian T Nabney (1996-2001)
Daniel@0 28
Daniel@0 29 errstring = consist(net, '', x, t);
Daniel@0 30 if ~isempty(errstring)
Daniel@0 31 error(errstring);
Daniel@0 32 end
Daniel@0 33
Daniel@0 34 ndata = size(x, 1);
Daniel@0 35 if nargin == 3
Daniel@0 36 num = 1;
Daniel@0 37 end
Daniel@0 38
Daniel@0 39 % Extract weights from network
Daniel@0 40 w = netpak(net);
Daniel@0 41
Daniel@0 42 % Evaluate data-dependent contribution to the Hessian matrix.
Daniel@0 43 [h, dh] = nethess(w, net, x, t);
Daniel@0 44 clear h; % To save memory when Hessian is large
Daniel@0 45 if (~isfield(net, 'beta'))
Daniel@0 46 local_beta = 1;
Daniel@0 47 end
Daniel@0 48
Daniel@0 49 [evec, evl] = eig(dh);
Daniel@0 50 % Now set the negative eigenvalues to zero.
Daniel@0 51 evl = evl.*(evl > 0);
Daniel@0 52 % safe_evl is used to avoid taking log of zero
Daniel@0 53 safe_evl = evl + eps.*(evl <= 0);
Daniel@0 54
Daniel@0 55 [e, edata, eprior] = neterr(w, net, x, t);
Daniel@0 56
Daniel@0 57 if size(net.alpha) == [1 1]
Daniel@0 58 % Form vector of eigenvalues
Daniel@0 59 evl = diag(evl);
Daniel@0 60 safe_evl = diag(safe_evl);
Daniel@0 61 else
Daniel@0 62 ngroups = size(net.alpha, 1);
Daniel@0 63 gams = zeros(1, ngroups);
Daniel@0 64 logas = zeros(1, ngroups);
Daniel@0 65 % Reconstruct data hessian with negative eigenvalues set to zero.
Daniel@0 66 dh = evec*evl*evec';
Daniel@0 67 end
Daniel@0 68
Daniel@0 69 % Do the re-estimation.
Daniel@0 70 for k = 1 : num
Daniel@0 71 % Re-estimate alpha.
Daniel@0 72 if size(net.alpha) == [1 1]
Daniel@0 73 % Evaluate number of well-determined parameters.
Daniel@0 74 L = evl;
Daniel@0 75 if isfield(net, 'beta')
Daniel@0 76 L = net.beta*L;
Daniel@0 77 end
Daniel@0 78 gamma = sum(L./(L + net.alpha));
Daniel@0 79 net.alpha = 0.5*gamma/eprior;
Daniel@0 80 % Partially evaluate log evidence: only include unmasked weights
Daniel@0 81 logev = 0.5*length(w)*log(net.alpha);
Daniel@0 82 else
Daniel@0 83 hinv = inv(hbayes(net, dh));
Daniel@0 84 for m = 1 : ngroups
Daniel@0 85 group_nweights = sum(net.index(:, m));
Daniel@0 86 gams(m) = group_nweights - ...
Daniel@0 87 net.alpha(m)*sum(diag(hinv).*net.index(:,m));
Daniel@0 88 net.alpha(m) = real(gams(m)/(2*eprior(m)));
Daniel@0 89 % Weight alphas by number of weights in group
Daniel@0 90 logas(m) = 0.5*group_nweights*log(net.alpha(m));
Daniel@0 91 end
Daniel@0 92 gamma = sum(gams, 2);
Daniel@0 93 logev = sum(logas);
Daniel@0 94 end
Daniel@0 95 % Re-estimate beta.
Daniel@0 96 if isfield(net, 'beta')
Daniel@0 97 net.beta = 0.5*(net.nout*ndata - gamma)/edata;
Daniel@0 98 logev = logev + 0.5*ndata*log(net.beta) - 0.5*ndata*log(2*pi);
Daniel@0 99 local_beta = net.beta;
Daniel@0 100 end
Daniel@0 101
Daniel@0 102 % Evaluate new log evidence
Daniel@0 103 e = errbayes(net, edata);
Daniel@0 104 if size(net.alpha) == [1 1]
Daniel@0 105 logev = logev - e - 0.5*sum(log(local_beta*safe_evl+net.alpha));
Daniel@0 106 else
Daniel@0 107 for m = 1:ngroups
Daniel@0 108 logev = logev - e - ...
Daniel@0 109 0.5*sum(log(local_beta*(safe_evl*net.index(:, m))+...
Daniel@0 110 net.alpha(m)));
Daniel@0 111 end
Daniel@0 112 end
Daniel@0 113 end
Daniel@0 114