diff toolboxes/FullBNT-1.0.7/netlab3.3/evidence.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/FullBNT-1.0.7/netlab3.3/evidence.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,114 @@
+function [net, gamma, logev] = evidence(net, x, t, num)
+%EVIDENCE Re-estimate hyperparameters using evidence approximation.
+%
+%	Description
+%	[NET] = EVIDENCE(NET, X, T) re-estimates the hyperparameters ALPHA
+%	and BETA by applying Bayesian re-estimation formulae for NUM
+%	iterations. The hyperparameter ALPHA can be a simple scalar
+%	associated with an isotropic prior on the weights, or can be a vector
+%	in which each component is associated with a group of weights as
+%	defined by the INDEX matrix in the NET data structure. These more
+%	complex priors can be set up for an MLP using MLPPRIOR. Initial
+%	values for the iterative re-estimation are taken from the network
+%	data structure NET passed as an input argument, while the return
+%	argument NET contains the re-estimated values.
+%
+%	[NET, GAMMA, LOGEV] = EVIDENCE(NET, X, T, NUM) allows the re-
+%	estimation  formula to be applied for NUM cycles in which the re-
+%	estimated values for the hyperparameters from each cycle are used to
+%	re-evaluate the Hessian matrix for the next cycle.  The return value
+%	GAMMA is the number of well-determined parameters and LOGEV is the
+%	log of the evidence.
+%
+%	See also
+%	MLPPRIOR, NETGRAD, NETHESS, DEMEV1, DEMARD
+%
+
+%	Copyright (c) Ian T Nabney (1996-2001)
+
+errstring = consist(net, '', x, t);
+if ~isempty(errstring)
+  error(errstring);
+end
+
+ndata = size(x, 1);
+if nargin == 3
+  num = 1;
+end
+
+% Extract weights from network
+w = netpak(net);
+
+% Evaluate data-dependent contribution to the Hessian matrix.
+[h, dh] = nethess(w, net, x, t); 
+clear h;  % To save memory when Hessian is large
+if (~isfield(net, 'beta'))
+  local_beta = 1;
+end
+
+[evec, evl] = eig(dh);
+% Now set the negative eigenvalues to zero.
+evl = evl.*(evl > 0);
+% safe_evl is used to avoid taking log of zero
+safe_evl = evl + eps.*(evl <= 0);
+
+[e, edata, eprior] = neterr(w, net, x, t);
+
+if size(net.alpha) == [1 1]
+  % Form vector of eigenvalues
+  evl = diag(evl);
+  safe_evl = diag(safe_evl);
+else
+  ngroups = size(net.alpha, 1);
+  gams = zeros(1, ngroups);
+  logas = zeros(1, ngroups);
+  % Reconstruct data hessian with negative eigenvalues set to zero.
+  dh = evec*evl*evec';
+end
+
+% Do the re-estimation. 
+for k = 1 : num
+  % Re-estimate alpha.
+  if size(net.alpha) == [1 1]
+    % Evaluate number of well-determined parameters.
+    L = evl;
+    if isfield(net, 'beta')
+      L = net.beta*L;
+    end
+    gamma = sum(L./(L + net.alpha));
+    net.alpha = 0.5*gamma/eprior;
+    % Partially evaluate log evidence: only include unmasked weights
+    logev = 0.5*length(w)*log(net.alpha);
+  else
+    hinv = inv(hbayes(net, dh));
+    for m = 1 : ngroups
+      group_nweights = sum(net.index(:, m));
+      gams(m) = group_nweights - ...
+	        net.alpha(m)*sum(diag(hinv).*net.index(:,m));
+      net.alpha(m) = real(gams(m)/(2*eprior(m)));
+      % Weight alphas by number of weights in group
+      logas(m) = 0.5*group_nweights*log(net.alpha(m));
+    end 
+    gamma = sum(gams, 2);
+    logev = sum(logas);
+  end
+  % Re-estimate beta.
+  if isfield(net, 'beta')
+      net.beta = 0.5*(net.nout*ndata - gamma)/edata;
+      logev = logev + 0.5*ndata*log(net.beta) - 0.5*ndata*log(2*pi);
+      local_beta = net.beta;
+  end
+  
+  % Evaluate new log evidence
+  e = errbayes(net, edata);
+  if size(net.alpha) == [1 1]
+    logev = logev - e - 0.5*sum(log(local_beta*safe_evl+net.alpha));
+  else
+    for m = 1:ngroups  
+      logev = logev - e - ...
+	  0.5*sum(log(local_beta*(safe_evl*net.index(:, m))+...
+	  net.alpha(m)));
+    end
+  end
+end
+