const-fixing functions
[mldemos:baraks-mldemos.git] / _AlgorithmsPlugins / OpenCV / classifierMLP.cpp
1 /*********************************************************************\r
2 MLDemos: A User-Friendly visualization toolkit for machine learning\r
3 Copyright (C) 2010  Basilio Noris\r
4 Contact: mldemos@b4silio.com\r
5 \r
6 This library is free software; you can redistribute it and/or\r
7 modify it under the terms of the GNU Lesser General Public\r
8 License as published by the Free Software Foundation; either\r
9 version 2.1 of the License, or (at your option) any later version.\r
10 \r
11 This library is distributed in the hope that it will be useful,\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
14 Library General Public License for more details.\r
15 \r
16 You should have received a copy of the GNU Lesser General Public\r
17 License along with this library; if not, write to the Free\r
18 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
19 *********************************************************************/\r
20 #include "public.h"\r
21 #include "basicMath.h"\r
22 #include "classifierMLP.h"\r
23 \r
24 ClassifierMLP::~ClassifierMLP()\r
25 {\r
26         DEL(mlp);\r
27 }\r
28 \r
29 void ClassifierMLP::Train(std::vector< fvec > samples, ivec labels)\r
30 {\r
31         u32 sampleCnt = samples.size();\r
32         if(!sampleCnt) return;\r
33         DEL(mlp);\r
34         dim = samples[0].size();\r
35 \r
36         CvMat *layers;\r
37 //      if(neuronCount == 3) neuronCount = 2; // don't ask me why but 3 neurons mess up everything...\r
38 \r
39         if(!layerCount || neuronCount < 2)\r
40         {\r
41                 layers = cvCreateMat(2,1,CV_32SC1);\r
42                 cvSet1D(layers, 0, cvScalar(dim));\r
43                 cvSet1D(layers, 1, cvScalar(1));\r
44         }\r
45         else\r
46         {\r
47                 layers = cvCreateMat(2+layerCount,1,CV_32SC1);\r
48                 cvSet1D(layers, 0, cvScalar(dim));\r
49                 cvSet1D(layers, layerCount+1, cvScalar(1));\r
50                 FOR(i, layerCount) cvSet1D(layers, i+1, cvScalar(neuronCount));\r
51         }\r
52 \r
53         u32 *perm = randPerm(sampleCnt);\r
54 \r
55         CvMat *trainSamples = cvCreateMat(sampleCnt, dim, CV_32FC1);\r
56         CvMat *trainLabels = cvCreateMat(labels.size(), 1, CV_32FC1);\r
57         CvMat *sampleWeights = cvCreateMat(samples.size(), 1, CV_32FC1);\r
58         FOR(i, sampleCnt)\r
59         {\r
60                 FOR(d, dim) cvSetReal2D(trainSamples, i, d, samples[perm[i]][d]);\r
61                 cvSet1D(trainLabels, i, cvScalar(labels[perm[i]]));\r
62                 cvSet1D(sampleWeights, i, cvScalar(1));\r
63         }\r
64 \r
65         delete [] perm;\r
66 \r
67         int activationFunction = functionType == 2 ? CvANN_MLP::GAUSSIAN : functionType ? CvANN_MLP::SIGMOID_SYM : CvANN_MLP::IDENTITY;\r
68 \r
69 \r
70         mlp = new CvANN_MLP();\r
71         mlp->create(layers, activationFunction, alpha, beta);\r
72 \r
73         CvANN_MLP_TrainParams params;\r
74         params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 1000, 0.001);\r
75         mlp->train(trainSamples, trainLabels, sampleWeights, 0, params);\r
76         cvReleaseMat(&trainSamples);\r
77         cvReleaseMat(&trainLabels);\r
78         cvReleaseMat(&sampleWeights);\r
79         cvReleaseMat(&layers);\r
80 }\r
81 \r
82 float ClassifierMLP::Test( const fvec &sample) const\r
83 {\r
84         if(!mlp) return 0;\r
85         float *_input = new float[dim];\r
86         FOR(d, dim) _input[d] = sample[d];\r
87         CvMat input = cvMat(1,dim,CV_32FC1, _input);\r
88         float _output[1];\r
89         CvMat output = cvMat(1,1,CV_32FC1, _output);\r
90         mlp->predict(&input, &output);\r
91         delete [] _input;\r
92         return _output[0];\r
93 }\r
94 \r
95 void ClassifierMLP::SetParams(u32 functionType, u32 neuronCount, u32 layerCount, f32 alpha, f32 beta)\r
96 {\r
97         this->functionType = functionType;\r
98         this->neuronCount = neuronCount;\r
99         this->layerCount = layerCount;\r
100         this->alpha = alpha;\r
101         this->beta = beta; \r
102 }\r
103 \r
104 const char *ClassifierMLP::GetInfoString() const\r
105 {\r
106         char *text = new char[1024];\r
107         sprintf(text, "Multi-Layer Perceptron\n");\r
108         sprintf(text, "%sLayers: %d\n", text, layerCount);\r
109         sprintf(text, "%sNeurons: %d\n", text, neuronCount);\r
110         sprintf(text, "%sActivation Function: ", text);\r
111         switch(functionType)\r
112         {\r
113         case 0:\r
114                 sprintf(text, "%s identity\n", text);\r
115                 break;\r
116         case 1:\r
117                 sprintf(text, "%s sigmoid (alpha: %f beta: %f)\n\t%s\n", text, alpha, beta, "beta*(1-exp(-alpha*x)) / (1 + exp(-alpha*x))");\r
118                 break;\r
119         case 2:\r
120                 sprintf(text, "%s gaussian (alpha: %f beta: %f)\n\t%s\n", text, alpha, beta, "beta*exp(-alpha*x*x)");\r
121                 break;\r
122         }\r
123         return text;\r
124 }\r