0% found this document useful (0 votes)
7 views5 pages

syMLP UsingFeatureFile

The document provides a C++ implementation of a Multilayer Perceptron (MLP) artificial neural network (ANN) that reads data from a CSV file for training and testing. It includes functions for reading feature-label matrices, splitting data into training and testing sets, shuffling rows, and training/testing the ANN while calculating a confusion matrix and accuracy. The example is configured for a diabetes dataset, but can be adapted for other datasets by changing the input file.

Uploaded by

Alex Al
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views5 pages

syMLP UsingFeatureFile

The document provides a C++ implementation of a Multilayer Perceptron (MLP) artificial neural network (ANN) that reads data from a CSV file for training and testing. It includes functions for reading feature-label matrices, splitting data into training and testing sets, shuffling rows, and training/testing the ANN while calculating a confusion matrix and accuracy. The example is configured for a diabetes dataset, but can be adapted for other datasets by changing the input file.

Uploaded by

Alex Al
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1 //

2 // syMLP_UsingFeatureFile.cpp
3 //
4 // Example of using an ANN (a Multilayer Perceptron)
5 // for a unspecified task, using data in a csv file
6 //
7 // Raul E. Sanchez-Yanez
8 // Revision: 2025-10-22, SanchezY
9 //
10
11 #include <iostream>
12 #include <fstream>
13 using namespace std;
14
15 #include <[Link]>
16 #include <[Link]>
17 #include <[Link]>
18 using namespace cv::ml;
19 using namespace cv;
20
21
22 int syFeatureAndLabelMatrix_Read(string filename, Mat &fullFeatureMat);
23 int syFeatureAndLabelMatrix_Split(const Mat &fullFeatureMat, Mat &trainMat,
Mat &trainLabelsMat,
24 Mat &testMat, Mat &testLabelsMat, int
nFolds);
25 int syImShuffleRows(const Mat &src, Mat &dst);
26 int syANN_MLP_Train_and_Test(int nClasses, const Mat &trainMat, const Mat
&trainLabelsMat,
27 const Mat &testMat, const Mat &testLabelsMat,
Mat &confusion);
28
29
30 int main(void)
31 {
32 system("COLOR F1");
33
34 // BEGIN CONFIGURATION
35
36 string filenameFeatureAndLabel = "../ref_features/diabetes_Table.csv";
// Filename containing feature header
37 // string filenameFeatureAndLabel =
"../ref_features/featureMat_FACESall_320w.csv"; // Filename containing
feature header
38 // string filenameFeatureAndLabel =
"../ref_features/[Link]"; // Filename containing feature
header
39
40 int nFolds = 10; // Number of partitions to be used
in classification test
41
42 // END CONFIGURATION
43
44 Mat fullFeatureMat; // To store data read from feature-and-label matrix
45 Mat trainMat, trainLabelsMat, testMat, testLabelsMat; // For matrices
required to train and test the ANN_MLP
46
47 // Read feature-and-label file
48 syFeatureAndLabelMatrix_Read(filenameFeatureAndLabel, fullFeatureMat);
49 // Split into files
50 syFeatureAndLabelMatrix_Split(fullFeatureMat, trainMat, trainLabelsMat,
testMat, testLabelsMat, nFolds);
51
52 cout<< "\nFull-feature matrix size: " << [Link]();
53 cout<< "\nTrain-data matrix size: " << [Link]();
54 cout<< "\nTrain-label matrix size: " << [Link]();
55 cout<< "\nTest-data matrix size: " << [Link]();
56 cout<< "\nTest-label matrix size: " << [Link]();
57
58
59 // Number of classes from label matrix
60 double mini, maxi;
61 cv::minMaxLoc(trainLabelsMat, &mini, &maxi);
62 int nClasses = maxi + 1;
63
64 // CONFUSION MATRIX
65 Mat confusion(nClasses,nClasses,CV_32S, Scalar(0)); // will hold our
test results
66 cout << "\n\nConfusion matrix size: "<< [Link]();
67 cout << " because we have " << nClasses << " class labels.\n\n";
68
69
70 // ALL-IN-ONE EXAMPLE OF AN ANN_MLP
71
72 syANN_MLP_Train_and_Test(nClasses,trainMat, trainLabelsMat, testMat,
testLabelsMat, confusion);
73
74 return 0;
75 }
76
77 int syFeatureAndLabelMatrix_Read(string filename, Mat &fullFeatureMat)
78 {
79 // WARNING: First line is assumed to contain feature labels (it is
discarded)!!!
80
81 ifstream inputfile(filename);
82 if(!inputfile) {cout << "\nsyFeatureAndLabelMatrix_Read(): Error reading
input file."; return 0;}
83
84 int nDataRead = 0;
85 if (![Link]()) { cout << "\nReleasing current
feature-and-label matrix."; [Link](); }
86 cout << "\n\nLoading feature-and-label matrix \""<<filename<<"\".\n";
87
88 string current_line;
89 getline(inputfile, current_line); // WARNING!!! We just discard first line
90
91 // Array of float-type arrays
92 vector< vector<float> > all_data;
93 // Start reading lines as long as there are lines in the file
94 while( getline(inputfile, current_line) )
95 {
96 // Now inside each line we need to separate the cols
97 vector<float> values;
98 stringstream temp(current_line);
99 string single_value;
100 while(getline(temp,single_value,',')){
101 values.push_back(atof(single_value.c_str())); // char* to float
102 }
103 // add the row to the complete data vector
104 all_data.push_back(values);
105 }
106 [Link]();
107
108 // Copy values into fullFeatureMat image
109 fullFeatureMat = Mat::zeros((int)all_data.size(),
(int)all_data[0].size(), CV_32FC1);
110 for(int r = 0; r < [Link]; r++)
111 for(int c= 0; c < [Link]; c++)
112 [Link]<float>(r,c) = all_data[r][c];
113 nDataRead = [Link]*[Link];
114 cout << "\nLoaded feature-and-label matrix with
"<<[Link]<<" samples ("<<nDataRead <<" data).\n";
115 return nDataRead;
116 }
117
118 int syFeatureAndLabelMatrix_Split(const Mat &fullFeatureMat, Mat &trainMat,
Mat &trainLabelsMat, Mat &testMat, Mat &testLabelsMat, int nFolds)
119 {
120 // We get 1 of the n-folds of matrices [ columns x
rows ]:
121 //
122 // trainMat: A float-type image of size [ nFeatures x
nTrainSamples ]
123 // testMat: A float-type image of size [ nFeatures x
nTestSamples ]
124 // trainLabelsMat: A uchar-type image of size [ 1 x
nTrainSamples ]
125 // testLabelsMat: A uchar-type image of size [ 1 x
nTestSamples ]
126 //
127 // from the matrix of features and labels, [ nFeatures+1 x
nSamples ]
128 //
129
130 if([Link]())
131 { cout << "\nEmpty Feature-and-Label Matrix.\n"; return false; }
132 if(![Link]()) [Link]();
133 if(![Link]()) [Link]();
134 if(![Link]()) [Link]();
135 if(![Link]()) [Link]();
136
137 Mat shuffled;
138 syImShuffleRows(fullFeatureMat,shuffled);
139 // syImWriteCSV_FEAT("[Link]",shuffled);
140
141 // Get 1 of n-folds
142 int nSamplesPerFold = [Link]/nFolds;
143 int nSamplesLearn = nSamplesPerFold*(nFolds-1);
144 int nSamplesTest = [Link] - nSamplesLearn;
145 cout<<"\n\nFor "<<nFolds<<"-fold test: "<<nSamplesPerFold<< " samples
per fold; "<<nSamplesLearn<<" for learning, "<<nSamplesTest<<" for
testing.\n";
146
147 trainMat = shuffled(Range(0,nSamplesLearn),Range(0,[Link]-1));
148 testMat =
shuffled(Range(nSamplesLearn,[Link]),Range(0,[Link]-1));
149 trainLabelsMat =
shuffled(Range(0,nSamplesLearn),Range([Link]-1,[Link]));
150 testLabelsMat =
shuffled(Range(nSamplesLearn,[Link]),Range([Link]-1,[Link]
ls));
151
152 // From float to uchar data for labels
153 [Link](trainLabelsMat, CV_8UC1);
154 [Link](testLabelsMat, CV_8UC1);
155 return [Link];
156 }
157
158
159 int syImShuffleRows(const Mat &src, Mat &dst)
160 {
161 std::vector <int> rowIndex;
162 for (int r = 0; r < [Link]; r++)
163 rowIndex.push_back(r);
164
165 cv::randShuffle(rowIndex);
166
167 for (int r = 0; r < [Link]; r++)
168 dst.push_back([Link](rowIndex[r]));
169
170 return true;
171 }
172
173
174
175 int syANN_MLP_Train_and_Test(int nClasses, const Mat &trainMat, const Mat
&trainLabelsMat,
176 const Mat &testMat, const Mat &testLabelsMat,
Mat &confusion)
177 {
178
179 // CREATE ANN_MLP
180
181 cout << "\nInitializing ANN_MLP\n\n";
182 Ptr<ml::ANN_MLP> ann = ml::ANN_MLP::create();
183
184 int nFeatures = [Link];
185
186 Mat_<int> layers(3,1); // only 3 layers
187 layers(0) = nFeatures; // input layer
188 layers(1) = nFeatures*2+1; // hidden layer
189 layers(2) = nClasses; // output layer, 1 pin per class.
190
191 ann->setLayerSizes(layers);
192 ann->setActivationFunction(ml::ANN_MLP::SIGMOID_SYM, 0, 0);
193
ann->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,
300, 0.0001));
194 ann->setTrainMethod(ml::ANN_MLP::BACKPROP, 0.0001);
195
196
197 // TRAIN THE NETWORK
198
199 // Warning: ann requires "one-hot" encoding of class labels:
200 // Class labels in a float-type sparse matrix of Samples x Classes
201 // with an '1' in the corresponding correct-label column
202
203 Mat train_classes = Mat::zeros([Link], nClasses, CV_32FC1);
204 for(int i=0; i<train_classes.rows; i++)
205 train_classes.at<float>(i, [Link]<uchar>(i)) = 1.0;
206 cout <<"\nTrain data size: "<< [Link]() << "\nTrain classes size:
" << train_classes.size() << "\n\n";
207
208 cout << "Training the ANN... (please wait)\n\n\n";
209 ann->train(trainMat, ml::ROW_SAMPLE, train_classes);
210
211
212 //// // HERE, WE COUD'VE INCLUDED CODE FOR WRITNG THE MODEL...
213 //// ann->save("ANN_Model.yml");
214 ////
215 //// // AND, LATER READING THE MODEL
216 //// Ptr<ANN_MLP> annTRAINED = cv::ml::ANN_MLP::load("ANN_Model.yml");
217
218
219 // TEST THE NETWORK
220
221 cout << "ANN prediction test\n\n";
222
223 // Test samples in testMat Mat
224 for(int i=0; i<[Link]; i++)
225 {
226 int pred = ann->predict([Link](i), noArray());
227 int truth = [Link]<uchar>(i);
228 [Link]<int>(truth,pred) ++;
229 }
230 cout << "Confusion matrix:\n" << confusion << endl;
231
232 Mat correct = [Link]();
233 float accuracy = sum(correct)[0] / sum(confusion)[0];
234 cout << "\nAccuracy: " << accuracy << "\n\n";
235 return 1;
236 }
237
238

You might also like