]> Creatis software - CreaPhase.git/blob - octave_packages/nnet-0.1.13/newff.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / nnet-0.1.13 / newff.m
1 ## Copyright (C) 2005 Michel D. Schmid  <michaelschmid@users.sourceforge.net>
2 ##
3 ##
4 ## This program is free software; you can redistribute it and/or modify it
5 ## under the terms of the GNU General Public License as published by
6 ## the Free Software Foundation; either version 2, or (at your option)
7 ## any later version.
8 ##
9 ## This program  is distributed in the hope that it will be useful, but
10 ## WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 ## General Public License for more details.
13 ##
14 ## You should have received a copy of the GNU General Public License
15 ## along with this program; see the file COPYING.  If not, see
16 ## <http://www.gnu.org/licenses/>.
17
18 ## -*- texinfo -*-
19 ## @deftypefn {Function File} {@var{net}} = newff (@var{Pr},@var{ss},@var{trf},@var{btf},@var{blf},@var{pf})
20 ## @code{newff} create a feed-forward backpropagation network
21 ##
22 ## @example
23 ## Pr - R x 2 matrix of min and max values for R input elements
24 ## Ss - 1 x Ni row vector with size of ith layer, for N layers
25 ## trf - 1 x Ni list with transfer function of ith layer,
26 ##       default = "tansig"
27 ## btf - Batch network training function,
28 ##       default = "trainlm"
29 ## blf - Batch weight/bias learning function,
30 ##       default = "learngdm"
31 ## pf  - Performance function,
32 ##       default = "mse".
33 ## @end example
34 ##
35 ## @example
36 ## EXAMPLE 1
37 ## Pr = [0.1 0.8; 0.1 0.75; 0.01 0.8];
38 ##      it's a 3 x 2 matrix, this means 3 input neurons
39 ##
40 ## net = newff(Pr, [4 1], @{"tansig","purelin"@}, "trainlm", "learngdm", "mse");
41 ## @end example
42 ##
43 ## @end deftypefn
44
45 ## @seealso{sim, init, train}
46
47 ## Author: Michel D. Schmid
48
49 function net = newff(Pr,ss,transFunc,trainFunc,notUsed,performFunc)
50
51   ## initial descriptipn
52   ##  newff(Pr,ss,transfunc,trainFunc,notUsed,performFunc)
53   ##  * Pr is a nx2 matrix with min and max values of standardized inputs
54   ##    Pr means: p-range
55   ##  * ss is a row vector, the first element describes the number
56   ##    of hidden neurons, the second element describes the number
57   ##    of output neurons
58   ##  * transFunc is a cell array of transfer function, standard is "tansig"
59   ##  * trainFunc is the training algorithm
60   ##  * notUsed exist only because we have only one train algorithm which doesn't
61   ##    need a weight learning function
62   ##  * performFunc is written for the performance function, standard is "mse"
63
64   ## check range of input arguments
65   error(nargchk(2,6,nargin))
66
67   ## get number of layers (without input layer)
68   nLayers = length(ss);
69
70   ## set defaults
71   if (nargin <3)
72     # the number of transfer functions depends on the number of
73     # hidden layers, so we have to create a loop here 30.09.09 (dd.mm.yy)
74         for i=1:nLayers
75           if (i==nLayers)
76             transFunc{i,1} = "purelin";
77           else
78         transFunc{i,1}= "tansig";
79       endif
80     endfor
81   endif
82   if (nargin <4)
83     trainFunc = "trainlm";
84   endif
85   if (nargin <5)
86     notUsed = "noSense";
87   endif
88   if (nargin==5)
89     ## it doesn't matter what nargin 5 is ...!
90     ## it won't be used ... it's only for matlab compatibility
91     notUsed = "noSense"
92   endif
93   if (nargin <6)
94     performFunc = "mse";
95   endif
96
97   ## check input args
98   checkInputArgs(Pr,ss);
99
100   ## Standard architecture of neural network
101   net = __newnetwork(1,nLayers,1,"newff");
102   ## description:
103   ##    first argument: number of inputs, nothing else allowed till now
104   ## it's not the same like the number of neurons in this input
105   ## second argument: number of layers, including output layer
106   ## third argument: number of outputs, nothing else allowed till now
107   ## it's not the same like the number of neurons in this output
108
109   ## set inputs with limit of only ONE input
110   net.inputs{1}.range = Pr;
111   [nRows, nColumns] = size(Pr);
112   net.inputs{1}.size = nRows;
113
114   ## set size of IW
115   net.IW{1,1} = zeros(1,nRows);
116   ## set more needed empty cells
117   for iLayers = 2:nLayers
118     net.IW{iLayers,1} = [];
119     #  net.IW{2:nLayers,1} = [];    # old code
120   endfor
121   ## set number of bias, one per layer
122   for iBiases = 1:nLayers
123     net.b{iBiases,1} = 0;
124   endfor
125
126   ## set rest of layers
127
128   ## set size of LayerWeights LW
129   ## the numbers of rows and columns depends on the
130   ## number of hidden neurons and output neurons...
131   ## 2 hidden neurons match 2 columns ...
132   ## 2 output neurons match 2 rows ...
133   for i=2:nLayers
134     net.LW{i,i-1} = zeros(ss(i),ss(i-1));
135   endfor
136   for iLayers = 1:nLayers
137     net.layers{iLayers}.size = ss(iLayers);
138     net.layers{iLayers}.transferFcn = transFunc{iLayers};
139   endfor
140
141   ## define everything with "targets"
142   net.numTargets = ss(end);
143   net.targets = cell(1,nLayers);
144   for i=1:nLayers
145     if (i==nLayers)
146       net.targets{i}.size = ss(end);
147       ## next row of code is only for MATLAB(TM) compatibility
148       ## I never used this the last 4 years ...
149       net.targets{i}.userdata = "Put your custom informations here!";
150     else
151       net.targets{i} = [];
152     endif
153   endfor
154
155   ## Performance
156   net.performFcn = performFunc;
157
158   ## Adaption
159   for i=1:nLayers
160 #    net.biases{i}.learnFcn = blf;
161 #    net.layerWeights{i,:}.learnFcn = blf;
162     net.biases{i}.size = ss(i);
163   endfor
164
165   ## Training
166   net.trainFcn = trainFunc; # actually, only trainlm will exist
167   net = setTrainParam(net);
168   ## Initialization
169   net = __init(net);
170
171 # ======================================================
172 #
173 # additional check functions...
174 #
175 # ======================================================
176   function checkInputArgs(Pr,ss)
177     
178     ## check if Pr has correct format
179     if !isreal(Pr) || (size(Pr,2)!=2)
180       error("Input ranges must be a two column matrix!")
181     endif
182     if any(Pr(:,1) > Pr(:,2)) # check if numbers in the second column are larger as in the first one
183       error("Input ranges has values in the second column larger as in the same row of the first column.")
184     endif
185
186     ## check if ss has correct format, must be 1xR row vector
187     if (size(ss,1)!=1)
188       error("Layer sizes is not a row vector.")
189     endif
190     if (size(ss,2)<2)
191       error("There must be at least one hidden layer and one output layer!")
192     endif
193     for k=1:length(ss)
194       sk = ss(k);
195       if !isreal(sk) || any(sk<1) || any(round(sk)!=sk)
196         error("Layer sizes is not a row vector of positive integers.")
197       endif
198     endfor
199
200   endfunction
201 # ======================================================
202 #
203 # additional set functions...
204 #
205 # ======================================================
206   function net = setTrainParam(net)
207
208     trainFunc = net.trainFcn;
209     switch(trainFunc)
210
211     case "trainlm"
212       net.trainParam.epochs = 100;
213       net.trainParam.goal = 0;
214       net.trainParam.max_fail = 5;
215       net.trainParam.mem_reduc = 1;
216       net.trainParam.min_grad = 1.0000e-010;
217       net.trainParam.mu = 0.0010;
218       net.trainParam.mu_dec = 0.1;
219       net.trainParam.mu_inc = 10;
220       net.trainParam.mu_max = 1.0000e+010;
221       net.trainParam.show = 50;
222       net.trainParam.time = Inf;
223     otherwise
224       error("newff:setTrainParam: this train algorithm isn't available till now!")
225     endswitch
226
227   endfunction
228 # ========================================================  
229
230
231 endfunction
232
233 %!shared
234 %! disp("testing newff")
235
236 # if input range Pr has only one column
237 %!test
238 %! Pr = [1;2];
239 %! fail("newff(Pr,[1 1],{'tansig','purelin'},'trainlm','unused','mse')","Input ranges must be a two column matrix!")
240
241 # if input range Pr has two columns
242 %!test
243 %! Pr = [1 2 ; 4  6];
244 %! assert(__checknetstruct(newff(Pr,[1 1],{'tansig','purelin'},'trainlm','unused','mse')))
245   ## __checknetstruct returns TRUE is input arg is a network structure ...
246
247 # if input range Pr has three columns
248 %!test
249 %! Pr = [1 2 3; 4 5 6];
250 %! fail("newff(Pr,[1 1],{'tansig','purelin'},'trainlm','unused','mse')","Input ranges must be a two column matrix!")
251
252 # if input range has in the second col greater values as in the first col ...
253 %!test
254 %! Pr = [5 3; 4 5];
255 %! fail("newff(Pr,[1 1],{'tansig','purelin'},'trainlm','unused','mse')",\
256 %!  "Input ranges has values in the second column larger as in the same row of the first column.")
257
258 # check if ss has correct format
259 %!test
260 %! Pr = [1 2 ; 4 6];
261 %! fail("newff(Pr,[1 1; 2 3],{'tansig','purelin'},'trainlm','unused','mse')",\
262 %!  "Layer sizes is not a row vector.")
263
264 # check if ss has correct format
265 %!test
266 %! Pr = [1 2 ; 4 6];
267 %! assert(__checknetstruct(newff(Pr,[ 2 3],{'tansig','purelin'},'trainlm','unused','mse')))
268
269 # check if ss has correct format
270 %!test
271 %! Pr = [1 2 ; 4 6];
272 %! fail("newff(Pr,[1],{'tansig','purelin'},'trainlm','unused','mse')",\
273 %!  "There must be at least one hidden layer and one output layer!")
274
275 # check if ss has correct format
276 %!test
277 %! Pr = [1 2 ; 4 6];
278 %! fail("newff(Pr,[-1 1],{'tansig','purelin'},'trainlm','unused','mse')",\
279 %!  "Layer sizes is not a row vector of positive integers.")