/*
File name: mlp.h
Created by: Ljubomir Buturovic
Created: 03/11/2001
Purpose: structure and function declarations for multi-layer
perceptron (MLP) learning.
*/
/*
Copyright 2004 Ljubomir J. Buturovic
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _MLP_H_
#define _MLP_H_
/*
Target values for MLP learning.
*/
#define MLP_TARGET_HIGH 0.9
#define MLP_TARGET_LOW 0.1
/*
Characteristic string in .mlp files.
*/
#define MLP_SIGNATURE_STRING "iterations:"
/*
Write/append MLP file constants.
*/
#define MLP_MODE_WRITE 0
#define MLP_MODE_APPEND 1
/*
Supported MLP optimization methods. The methods are simplex
(Nelder-Mead), Gilbert & Nocedal cgfam() (CG+), gradient descent,
WNLIB and NR.
*/
#define MLP_OPT_CGPLUS 1
#define MLP_OPT_GRADIENT_DESCENT 2
#define MLP_OPT_WNLIB 3
#define MLP_OPT_SIMPLEX 5
/*
User-friendly names of the above.
*/
#define MLP_STR_CGPLUS "CG+ conjugate gradient"
#define MLP_STR_GRADIENT_DESCENT "gradient descent"
#define MLP_STR_WNLIB "WNLIB gradient descent"
#define MLP_STR_UNSPECIFIED "unspecified"
#include <stdio.h>
#include "pcp.h"
/*
Struct mlp describes a multi-layer perceptron neural network with
'd' inputs, 'nlayers' layers and 'npl[i]' nodes in layer i, and
weights 'w'. 'nlayers' counts hidden layers and output layer, so for
a network with two hidden layers 'nlayers' is 3. 'wlen' is total
number of weights in the network. 'nodes' is total number of
nodes. It counts hidden nodes and output nodes. 'a' is vector of
node activations. 'z' is vector of node outputs. 'delta' is vector
of errors as defined in Bishop, equation (4.32). The length of 'a',
'z' and 'delta' equals 'nodes'. 'noff' is offset of the first
(left-most) output node in the arrays.
'seed' is seed for pseudo-random number generator rand() used to
initialize the neural network weights. 'range' is amplitude of
initial pseudo-random weights (i.e., the initial weights are
assigned pseudo-randomly within [-range, range]). 'iterations' is
the number of iterations so far in the current training
session. 'p_iter' is the number of iterations previously applied to
this perceptron. 'itmax' is maximum number of iterations allowed in
the current training session. 'error' is average output deviation
per node and per input sample (MSE). 'mce' is number of
misclassified samples. 'fname' is network output file name.
The nodes are numbered from 0, starting from left. So, for a
two-layer network the nodes in first hidden layer are numbered 0 to
npl[0]-1. Output nodes are numbered npl[0] to npl[0]+npl[1]-1. In
general, the number of output nodes equals npl[nl-1], where nl is
the number of layers.
Weights numbered 0 to d go from bias value (w[0]) and the d inputs
(w[1] to w[d]) to node 0. Weights numbered d+1 to 2*d-1 go from the
bias value to node 1, etc. Thus, weights going into a node are
sequentially numbered.
'method' is optimization method.
*/
struct mlp
{
int d;
int nlayers;
int *npl;
float *w;
int nodes;
int wlen;
float *a;
float *z;
float *delta;
int noff;
int method;
float range;
int iterations;
int p_iter;
int itmax;
float error;
int mce;
char *fname;
unsigned int seed;
};
/*
This structure is used to pass MLP-specific parameters to adaboost()
and bagging().
*/
struct mlp_options
{
int nlayers;
int *npl;
int itmax;
float range;
float opt_method;
float eta;
float mu;
float alpha;
};
/*
Free mlp struct. Returns (struct mlp *) 0.
*/
struct mlp *mlp_free(struct mlp *perceptron);
/*
Return deep copy of 'perceptron'.
*/
struct mlp *mlp_clone(struct mlp *perceptron);
/*
Calculate outputs for MLP defined in 'perceptron' for a given input
'x'. The function allocates space for the returned vector - it is
the caller's responsiblity to free() it.
*/
float *mlp_output(struct mlp *perceptron, float *x);
/*
Generate target outputs for MLP, given input categorized in 'nc'
classes with 'nd[i]' samples in class i.
In case of malloc() failure, return NULL and set errno.
*/
float **mlp_target(int nc, int *nd);
/*
The function calculates the value of error function for the
perceptron described by 'perceptron' at weight vector
'w[1..wlen]'. 'w' is 1-based, as prescribed by Numerical Recipes
optimization routines API. 'nsamples' is the number of input samples
in 'x', 't' are target output values. 'nd[i]' is cardinality of
class 'i'.
The function is specific to NR optimizer. The other optimizers use
mlp_function().
*/
float mlp_criterion(float *w, struct mlp *perceptron, float **x, int nsamples,
int *nd, float **t, int *errc, FILE *outdev, FILE *fdbg);
/*
The function sets the derivative vector 'dw' of MLP criterion
function for MLP defined by 'perceptron' and 'w'.
*/
void mlp_derivative(float *w, float *dw, struct mlp *perceptron, float **x,
int nsamples, float **t, int *errc, FILE *outdev,
FILE *fdbg);
/*
Optimize weights of an MLP neural network using up to 'itmax'
iterations of 'opt_method' optimization method. 'x' are 'nsamples'
input vectors of length 'd' with 'nd[i]' samples per class 'i'. 't'
are 'nsamples' target output vectors. 'eta' and 'mu' are the step
size and momentum parameters for gradient descent optimization
(therefore used only if 'opt_method' is
MLP_OPT_GRADIENT_DESCENT). 'mlp_continue' is 0 to begin learning, 1
to continue starting with network in 'fname'. The function
calculates the set of weights which optimize the square error and
stores them in 'fname'. It periodically reports results on 'outdev'.
The possible values for opt_method are defined in mlp.h.
In case of success, the function returns 'mlp' structure which
contains the trained neural network and sets 'errc' to 0. In case of
error, return NULL and set 'errc', except for LERR_LNSEARCH (line
search failure in optimization routine) and LERR_DESCENT
(optimization procedure unable to find descent direction) errors. In
those cases, the function returns the trained network, but sets
'errc' to LERR_LNSEARCH or LERR_DESCENT. This is done because
optimization function often reports these errors, and yet finds a
decent minimum. The caller may choose to ignore these two error
codes.
*/
struct mlp *mlp_learn(int opt_method, float **x, int nsamples, int *nd, int d,
float **t, int nlayers, int *npl, int itmax, float range,
float eta, float mu, FILE *outdev, int mlp_continue,
char *fname, unsigned int seed, int *errc, FILE *fdbg);
/*
Optimize weights of an MLP neural network using modified
Polak-Ribiere conjugate gradient method. 't' are 'dset->nv' target
output vectors. The function calculates the set of weights which
optimize the square error and stores them in mlp->w, and saves them
in mlp->fname. It periodically reports results on 'outdev'.
In case of success, return 0, otherwise return -1 and set error code
in 'errc'.
*/
int mlp_optimize(struct dataset *dset, float **t, struct mlp *perceptron,
FILE *outdev, int *errc, FILE *fdbg);
/*
Optimize weights of an MLP neural network using gradient descent
algorithm defined by step size 'eta' and using momentum term defined
by 'mu'. 't' are 'dset->nv' target output vectors. The function
calculates the set of weights which optimize the square error and
stores them in mlp->w, and saves them in mlp->fname. It periodically
reports results on 'outdev'.
In case of success, return 0, otherwise return -1 and set error code
in 'errc'.
*/
int mlp_optimize_gradient_descent(struct dataset *dset, float **t, struct mlp *perceptron,
float eta, float mu, FILE *outdev, int *errc, FILE *fdbg);
/*
Optimize weights of an MLP neural network using modified
Polak-Ribiere conjugate gradient method. 't' are 'dset->nv' target
output vectors. The function calculates the set of weights which
optimize the square error and stores them in mlp->w, and saves them
in mlp->fname. It periodically reports results on 'outdev'.
In case of success, return 0, otherwise return -1 and set error code
in 'errc'.
*/
int mlp_optimize(struct dataset *dset, float **t, struct mlp *perceptron,
FILE *outdev, int *errc, FILE *fdbg);
/*
Save multi-layer perceptron model described by 'perceptron' in
perceptron->fname. The model is written (mode == MLP_MODE_WRITE) or
appended (mode == MLP_MODE_APPEND) to the perceptron->fname file.
If mode == MLP_MODE_APPEND, prepend 'index'/'weight' to the model
saved, otherwise prepend the default values (1/1.0).
In case of success, return 0. In case of failure, return -1 and set
errno.
*/
int mlp_save(struct mlp *perceptron, int mode, int index, float weight);
/*
File-pointer-based version of mlp_save().
In case of success, return 0. In case of failure, return -1 and set
errno.
*/
int mlp_write(FILE *fptr, struct mlp *perceptron, int mode, int index, float weight);
typedef float (*mlp_func)(float [], struct mlp *, float **, int, int *, float **,
int *, FILE *, FILE *);
typedef void (*mlp_dfunc)(float [], float [], struct mlp *, float **, int,
float **, int *, FILE *, FILE *);
typedef float (*mlp_f1dim)(float, struct mlp *, float **, int, int *, float **,
int *, FILE *, FILE *);
typedef float (*mlp_df1dim)(float, struct mlp *, float **, int, int *, float **,
int *, FILE *, FILE *);
void frprmn(float p[], int n, float ftol, int *iter, float *fret, mlp_func func,
mlp_dfunc dfunc, struct mlp *perceptron, float **x, int nsamples,
int *nd, float **t, int *errc, FILE *outdev, FILE *fdbg);
void linmin(float p[], float xi[], int n, float *fret, mlp_func func,
struct mlp *perceptron, float **x, int nsamples, int *nd, float **t,
int *errc, FILE *outdev, FILE *fdbg);
float brent(float ax, float bx, float cx, mlp_f1dim f, float tol, float *xmin,
struct mlp *perceptron, float **_x, int nsamples, int *nd, float **t,
int *errc, FILE *outdev, FILE *fdbg);
float f1dim(float x, struct mlp *perceptron, float **_x, int nsamples, int *nd,
float **t, int *errc, FILE *outdev, FILE *fdbg);
void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb,
float *fc, mlp_f1dim func, struct mlp *perceptron, float **x,
int nsamples, int *nd, float **t, int *errc, FILE *outdev,
FILE *fdbg);
void dlinmin(float p[], float xi[], int n, float *fret, mlp_func func, mlp_dfunc dfunc,
struct mlp *perceptron, float **x, int nsamples, int *nd, float **t,
int *errc, FILE *outdev, FILE *fdbg);
float dbrent(float ax, float bx, float cx, mlp_f1dim f, mlp_df1dim df,
float tol, float *xmin, struct mlp *perceptron, float **_x,
int nsamples, int *nd, float **t, int *errc, FILE *outdev, FILE *fdbg);
float df1dim(float x, struct mlp *perceptron, float **_x, int nsamples, int *nd,
float **t, int *errc, FILE *outdev, FILE *fdbg);
/*
Classify dataset 'dset' using MLP defined in 'perceptrons'. The MLP
outputs are placed in the returned struct mlp, and the
classification results are placed in dset->cx. The function assigns
each vector to the class corresponding to the node with the largest
output, unless 'thd' is > 0. In that case, the assignment is
performed only if the largest node output exceeds 'thd'.
'perceptrons' is an array of 'struct mlp' objects. It can be
created, for example, from a file using calling mlp_load().
In case of error, return NULL and place error code in 'errc'.
*/
struct mlp *mlp_predict(struct dataset *dset, struct mlp **perceptrons, float thd, int *errc);
/*
Load one or more multi-layer perceptrons described in 'fname' into
(struct mlp **) array. The last element in the array is NULL. In
case of success, returns 0. In case of failure, returns -1 and sets
errno.
*/
struct mlp **mlp_load(char *fname);
#endif /* _MLP_H_ */
syntax highlighted by Code2HTML, v. 0.9.1