diff toolboxes/FullBNT-1.0.7/netlab3.3/rbftrain.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/rbftrain.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,203 @@
+function [net, options] = rbftrain(net, options, x, t)
+%RBFTRAIN Two stage training of RBF network.
+%
+%	Description
+%	NET = RBFTRAIN(NET, OPTIONS, X, T) uses a  two stage training
+%	algorithm to set the weights in the RBF model structure NET. Each row
+%	of X corresponds to one input vector and each row of T contains the
+%	corresponding target vector. The centres are determined by fitting a
+%	Gaussian mixture model with circular covariances using the EM
+%	algorithm through a call to RBFSETBF.  (The mixture model is
+%	initialised using a small number of iterations of the K-means
+%	algorithm.) If the activation functions are Gaussians, then the basis
+%	function widths are then set to the maximum inter-centre squared
+%	distance.
+%
+%	For linear outputs,  the hidden to output weights that give rise to
+%	the least squares solution can then be determined using the pseudo-
+%	inverse. For neuroscale outputs, the hidden to output weights are
+%	determined using the iterative shadow targets algorithm.  Although
+%	this two stage procedure may not give solutions with as low an error
+%	as using general  purpose non-linear optimisers, it is much faster.
+%
+%	The options vector may have two rows: if this is the case, then the
+%	second row is passed to RBFSETBF, which allows the user to specify a
+%	different number iterations for RBF and GMM training. The optional
+%	parameters to RBFTRAIN have the following interpretations.
+%
+%	OPTIONS(1) is set to 1 to display error values during EM training.
+%
+%	OPTIONS(2) is a measure of the precision required for the value of
+%	the weights W at the solution.
+%
+%	OPTIONS(3) is a measure of the precision required of the objective
+%	function at the solution.  Both this and the previous condition must
+%	be satisfied for termination.
+%
+%	OPTIONS(5) is set to 1 if the basis functions parameters should
+%	remain unchanged; default 0.
+%
+%	OPTIONS(6) is set to 1 if the output layer weights should be should
+%	set using PCA. This is only relevant for Neuroscale outputs; default
+%	0.
+%
+%	OPTIONS(14) is the maximum number of iterations for the shadow
+%	targets algorithm;  default 100.
+%
+%	See also
+%	RBF, RBFERR, RBFFWD, RBFGRAD, RBFPAK, RBFUNPAK, RBFSETBF
+%
+
+%	Copyright (c) Ian T Nabney (1996-2001)
+
+% Check arguments for consistency
+switch net.outfn
+case 'linear'
+  errstring = consist(net, 'rbf', x, t);
+case 'neuroscale'
+  errstring = consist(net, 'rbf', x);
+otherwise
+ error(['Unknown output function ', net.outfn]);
+end
+if ~isempty(errstring)
+  error(errstring);
+end
+
+% Allow options to have two rows: if this is the case, then the second row
+% is passed to rbfsetbf
+if size(options, 1) == 2
+  setbfoptions = options(2, :);
+  options = options(1, :);
+else
+  setbfoptions = options;
+end
+
+if(~options(14))
+  options(14) = 100;
+end
+% Do we need to test for termination?
+test = (options(2) | options(3));
+
+% Set up the basis function parameters to model the input data density
+% unless options(5) is set.
+if ~(logical(options(5)))
+  net = rbfsetbf(net, setbfoptions, x);
+end
+
+% Compute the design (or activations) matrix
+[y, act] = rbffwd(net, x);
+ndata = size(x, 1);
+
+if strcmp(net.outfn, 'neuroscale') & options(6)
+  % Initialise output layer weights by projecting data with PCA
+  mu = mean(x);
+  [pcvals, pcvecs] = pca(x, net.nout);
+  xproj = (x - ones(ndata, 1)*mu)*pcvecs;
+  % Now use projected data as targets to compute output layer weights
+  temp = pinv([act ones(ndata, 1)]) * xproj;
+  net.w2 = temp(1:net.nhidden, :);
+  net.b2 = temp(net.nhidden+1, :);
+  % Propagate again to compute revised outputs
+  [y, act] = rbffwd(net, x);
+end
+
+switch net.outfn
+case 'linear'
+  % Sum of squares error function in regression model
+  % Solve for the weights and biases using pseudo-inverse from activations
+  Phi = [act ones(ndata, 1)];
+  if ~isfield(net, 'alpha')
+    % Solve for the weights and biases using left matrix divide
+    temp = pinv(Phi)*t;
+  elseif size(net.alpha == [1 1])
+    % Use normal form equation
+    hessian = Phi'*Phi + net.alpha*eye(net.nhidden+1);
+    temp = pinv(hessian)*(Phi'*t);  
+  else
+    error('Only scalar alpha allowed');
+  end
+  net.w2 = temp(1:net.nhidden, :);
+  net.b2 = temp(net.nhidden+1, :);
+
+case 'neuroscale'
+  % Use the shadow targets training algorithm
+  if nargin < 4
+    % If optional input distances not passed in, then use
+    % Euclidean distance
+    x_dist = sqrt(dist2(x, x));
+  else
+    x_dist = t;
+  end
+  Phi = [act, ones(ndata, 1)];
+  % Compute the pseudo-inverse of Phi
+  PhiDag = pinv(Phi);
+  % Compute y_dist, distances between image points
+  y_dist = sqrt(dist2(y, y));
+
+  % Save old weights so that we can check the termination criterion
+  wold = netpak(net);
+  % Compute initial error (stress) value
+  errold = 0.5*(sum(sum((x_dist - y_dist).^2)));
+
+  % Initial value for eta
+  eta = 0.1;
+  k_up = 1.2;
+  k_down = 0.1;
+  success = 1;  % Force initial gradient calculation
+
+  for j = 1:options(14)
+    if success
+      % Compute the negative error gradient with respect to network outputs
+      D = (x_dist - y_dist)./(y_dist+(y_dist==0));
+      temp = y';
+      neg_gradient = -2.*sum(kron(D, ones(1, net.nout)) .* ...
+	(repmat(y, 1, ndata) - repmat((temp(:))', ndata, 1)), 1);
+      neg_gradient = (reshape(neg_gradient, net.nout, ndata))';
+    end
+    % Compute the shadow targets
+    t = y + eta*neg_gradient;
+    % Solve for the weights and biases
+    temp = PhiDag * t;
+    net.w2 = temp(1:net.nhidden, :);
+    net.b2 = temp(net.nhidden+1, :);
+   
+    % Do housekeeping and test for convergence
+    ynew = rbffwd(net, x);
+    y_distnew = sqrt(dist2(ynew, ynew));
+    err = 0.5.*(sum(sum((x_dist-y_distnew).^2)));
+    if err > errold
+      success = 0;
+      % Restore previous weights
+      net = netunpak(net, wold);
+      err = errold;
+      eta = eta * k_down;
+    else
+      success = 1;
+      eta = eta * k_up;
+      errold = err;
+      y = ynew;
+      y_dist = y_distnew;
+      if test & j > 1
+	w = netpak(net);
+	if (max(abs(w - wold)) < options(2) & abs(err-errold) < options(3))
+	  options(8) = err;
+	  return;
+	end
+      end
+      wold = netpak(net);
+    end
+    if options(1)
+      fprintf(1, 'Cycle %4d Error %11.6f\n', j, err)
+    end
+    if nargout >= 3
+      errlog(j) = err;
+    end
+  end
+  options(8) = errold;
+  if (options(1) >= 0)
+    disp('Warning: Maximum number of iterations has been exceeded');
+  end
+otherwise
+   error(['Unknown output function ', net.outfn]);
+
+end