wolffd@0
|
1 function net = gtminit(net, options, data, samp_type, varargin)
|
wolffd@0
|
2 %GTMINIT Initialise the weights and latent sample in a GTM.
|
wolffd@0
|
3 %
|
wolffd@0
|
4 % Description
|
wolffd@0
|
5 % NET = GTMINIT(NET, OPTIONS, DATA, SAMPTYPE) takes a GTM NET and
|
wolffd@0
|
6 % generates a sample of latent data points and sets the centres (and
|
wolffd@0
|
7 % widths if appropriate) of NET.RBFNET.
|
wolffd@0
|
8 %
|
wolffd@0
|
9 % If the SAMPTYPE is 'REGULAR', then regular grids of latent data
|
wolffd@0
|
10 % points and RBF centres are created. The dimension of the latent data
|
wolffd@0
|
11 % space must be 1 or 2. For one-dimensional latent space, the
|
wolffd@0
|
12 % LSAMPSIZE parameter gives the number of latent points and the
|
wolffd@0
|
13 % RBFSAMPSIZE parameter gives the number of RBF centres. For a two-
|
wolffd@0
|
14 % dimensional latent space, these parameters must be vectors of length
|
wolffd@0
|
15 % 2 with the number of points in each of the x and y directions to
|
wolffd@0
|
16 % create a rectangular grid. The widths of the RBF basis functions are
|
wolffd@0
|
17 % set by a call to RBFSETFW passing OPTIONS(7) as the scaling
|
wolffd@0
|
18 % parameter.
|
wolffd@0
|
19 %
|
wolffd@0
|
20 % If the SAMPTYPE is 'UNIFORM' or 'GAUSSIAN' then the latent data is
|
wolffd@0
|
21 % found by sampling from a uniform or Gaussian distribution
|
wolffd@0
|
22 % correspondingly. The RBF basis function parameters are set by a call
|
wolffd@0
|
23 % to RBFSETBF with the DATA parameter as dataset and the OPTIONS
|
wolffd@0
|
24 % vector.
|
wolffd@0
|
25 %
|
wolffd@0
|
26 % Finally, the output layer weights of the RBF are initialised by
|
wolffd@0
|
27 % mapping the mean of the latent variable to the mean of the target
|
wolffd@0
|
28 % variable, and the L-dimensional latent variale variance to the
|
wolffd@0
|
29 % variance of the targets along the first L principal components.
|
wolffd@0
|
30 %
|
wolffd@0
|
31 % See also
|
wolffd@0
|
32 % GTM, GTMEM, PCA, RBFSETBF, RBFSETFW
|
wolffd@0
|
33 %
|
wolffd@0
|
34
|
wolffd@0
|
35 % Copyright (c) Ian T Nabney (1996-2001)
|
wolffd@0
|
36
|
wolffd@0
|
37 % Check for consistency
|
wolffd@0
|
38 errstring = consist(net, 'gtm', data);
|
wolffd@0
|
39 if ~isempty(errstring)
|
wolffd@0
|
40 error(errstring);
|
wolffd@0
|
41 end
|
wolffd@0
|
42
|
wolffd@0
|
43 % Check type of sample
|
wolffd@0
|
44 stypes = {'regular', 'uniform', 'gaussian'};
|
wolffd@0
|
45 if (strcmp(samp_type, stypes)) == 0
|
wolffd@0
|
46 error('Undefined sample type.')
|
wolffd@0
|
47 end
|
wolffd@0
|
48
|
wolffd@0
|
49 if net.dim_latent > size(data, 2)
|
wolffd@0
|
50 error('Latent space dimension must not be greater than data dimension')
|
wolffd@0
|
51 end
|
wolffd@0
|
52 nlatent = net.gmmnet.ncentres;
|
wolffd@0
|
53 nhidden = net.rbfnet.nhidden;
|
wolffd@0
|
54
|
wolffd@0
|
55 % Create latent data sample and set RBF centres
|
wolffd@0
|
56
|
wolffd@0
|
57 switch samp_type
|
wolffd@0
|
58 case 'regular'
|
wolffd@0
|
59 if nargin ~= 6
|
wolffd@0
|
60 error('Regular type must specify latent and RBF shapes');
|
wolffd@0
|
61 end
|
wolffd@0
|
62 l_samp_size = varargin{1};
|
wolffd@0
|
63 rbf_samp_size = varargin{2};
|
wolffd@0
|
64 if round(l_samp_size) ~= l_samp_size
|
wolffd@0
|
65 error('Latent sample specification must contain integers')
|
wolffd@0
|
66 end
|
wolffd@0
|
67 % Check existence and size of rbf specification
|
wolffd@0
|
68 if any(size(rbf_samp_size) ~= [1 net.dim_latent]) | ...
|
wolffd@0
|
69 prod(rbf_samp_size) ~= nhidden
|
wolffd@0
|
70 error('Incorrect specification of RBF centres')
|
wolffd@0
|
71 end
|
wolffd@0
|
72 % Check dimension and type of latent data specification
|
wolffd@0
|
73 if any(size(l_samp_size) ~= [1 net.dim_latent]) | ...
|
wolffd@0
|
74 prod(l_samp_size) ~= nlatent
|
wolffd@0
|
75 error('Incorrect dimension of latent sample spec.')
|
wolffd@0
|
76 end
|
wolffd@0
|
77 if net.dim_latent == 1
|
wolffd@0
|
78 net.X = [-1:2/(l_samp_size-1):1]';
|
wolffd@0
|
79 net.rbfnet.c = [-1:2/(rbf_samp_size-1):1]';
|
wolffd@0
|
80 net.rbfnet = rbfsetfw(net.rbfnet, options(7));
|
wolffd@0
|
81 elseif net.dim_latent == 2
|
wolffd@0
|
82 net.X = gtm_rctg(l_samp_size);
|
wolffd@0
|
83 net.rbfnet.c = gtm_rctg(rbf_samp_size);
|
wolffd@0
|
84 net.rbfnet = rbfsetfw(net.rbfnet, options(7));
|
wolffd@0
|
85 else
|
wolffd@0
|
86 error('For regular sample, input dimension must be 1 or 2.')
|
wolffd@0
|
87 end
|
wolffd@0
|
88
|
wolffd@0
|
89
|
wolffd@0
|
90 case {'uniform', 'gaussian'}
|
wolffd@0
|
91 if strcmp(samp_type, 'uniform')
|
wolffd@0
|
92 net.X = 2 * (rand(nlatent, net.dim_latent) - 0.5);
|
wolffd@0
|
93 else
|
wolffd@0
|
94 % Sample from N(0, 0.25) distribution to ensure most latent
|
wolffd@0
|
95 % data is inside square
|
wolffd@0
|
96 net.X = randn(nlatent, net.dim_latent)/2;
|
wolffd@0
|
97 end
|
wolffd@0
|
98 net.rbfnet = rbfsetbf(net.rbfnet, options, net.X);
|
wolffd@0
|
99 otherwise
|
wolffd@0
|
100 % Shouldn't get here
|
wolffd@0
|
101 error('Invalid sample type');
|
wolffd@0
|
102
|
wolffd@0
|
103 end
|
wolffd@0
|
104
|
wolffd@0
|
105 % Latent data sample and basis function parameters chosen.
|
wolffd@0
|
106 % Now set output weights
|
wolffd@0
|
107 [PCcoeff, PCvec] = pca(data);
|
wolffd@0
|
108
|
wolffd@0
|
109 % Scale PCs by eigenvalues
|
wolffd@0
|
110 A = PCvec(:, 1:net.dim_latent)*diag(sqrt(PCcoeff(1:net.dim_latent)));
|
wolffd@0
|
111
|
wolffd@0
|
112 [temp, Phi] = rbffwd(net.rbfnet, net.X);
|
wolffd@0
|
113 % Normalise X to ensure 1:1 mapping of variances and calculate weights
|
wolffd@0
|
114 % as solution of Phi*W = normX*A'
|
wolffd@0
|
115 normX = (net.X - ones(size(net.X))*diag(mean(net.X)))*diag(1./std(net.X));
|
wolffd@0
|
116 net.rbfnet.w2 = Phi \ (normX*A');
|
wolffd@0
|
117 % Bias is mean of target data
|
wolffd@0
|
118 net.rbfnet.b2 = mean(data);
|
wolffd@0
|
119
|
wolffd@0
|
120 % Must also set initial value of variance
|
wolffd@0
|
121 % Find average distance between nearest centres
|
wolffd@0
|
122 % Ensure that distance of centre to itself is excluded by setting diagonal
|
wolffd@0
|
123 % entries to realmax
|
wolffd@0
|
124 net.gmmnet.centres = rbffwd(net.rbfnet, net.X);
|
wolffd@0
|
125 d = dist2(net.gmmnet.centres, net.gmmnet.centres) + ...
|
wolffd@0
|
126 diag(ones(net.gmmnet.ncentres, 1)*realmax);
|
wolffd@0
|
127 sigma = mean(min(d))/2;
|
wolffd@0
|
128
|
wolffd@0
|
129 % Now set covariance to minimum of this and next largest eigenvalue
|
wolffd@0
|
130 if net.dim_latent < size(data, 2)
|
wolffd@0
|
131 sigma = min(sigma, PCcoeff(net.dim_latent+1));
|
wolffd@0
|
132 end
|
wolffd@0
|
133 net.gmmnet.covars = sigma*ones(1, net.gmmnet.ncentres);
|
wolffd@0
|
134
|
wolffd@0
|
135 % Sub-function to create the sample data in 2d
|
wolffd@0
|
136 function sample = gtm_rctg(samp_size)
|
wolffd@0
|
137
|
wolffd@0
|
138 xDim = samp_size(1);
|
wolffd@0
|
139 yDim = samp_size(2);
|
wolffd@0
|
140 % Produce a grid with the right number of rows and columns
|
wolffd@0
|
141 [X, Y] = meshgrid([0:1:(xDim-1)], [(yDim-1):-1:0]);
|
wolffd@0
|
142
|
wolffd@0
|
143 % Change grid representation
|
wolffd@0
|
144 sample = [X(:), Y(:)];
|
wolffd@0
|
145
|
wolffd@0
|
146 % Shift grid to correct position and scale it
|
wolffd@0
|
147 maxXY= max(sample);
|
wolffd@0
|
148 sample(:,1) = 2*(sample(:,1) - maxXY(1)/2)./maxXY(1);
|
wolffd@0
|
149 sample(:,2) = 2*(sample(:,2) - maxXY(2)/2)./maxXY(2);
|
wolffd@0
|
150 return;
|
wolffd@0
|
151
|
wolffd@0
|
152
|
wolffd@0
|
153
|