GestureRecognitionToolkit  Version: 0.2.0
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
GestureRecognitionPipeline.cpp
1 /*
2 GRT MIT License
3 Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
4 
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 and associated documentation files (the "Software"), to deal in the Software without restriction,
7 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in all copies or substantial
12 portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 */
20 
21 #define GRT_DLL_EXPORTS
23 
24 GRT_BEGIN_NAMESPACE
25 
27 {
28  init();
29 
30  debugLog.setProceedingText("[DEBUG GRP]");
31  errorLog.setProceedingText("[ERROR GRP]");
32  warningLog.setProceedingText("[WARNING GRP]");
33  testingLog.setProceedingText("[TEST GRP]");
34 }
35 
37 
38  init();
39 
40  debugLog.setProceedingText("[DEBUG GRP]");
41  errorLog.setProceedingText("[ERROR GRP]");
42  warningLog.setProceedingText("[WARNING GRP]");
43  testingLog.setProceedingText("[TEST GRP]");
44 
45  //Invoke the equals operator to copy the rhs data to this instance
46  *this = rhs;
47 }
48 
49 
51 
52  if( this != &rhs ){
53  this->clear();
54 
55  //Copy the pipeline variables
56  this->initialized = rhs.initialized;
57  this->trained = rhs.trained;
58  this->info = rhs.info;
59  this->inputVectorDimensions = rhs.inputVectorDimensions;
60  this->outputVectorDimensions = rhs.outputVectorDimensions;
61  this->predictedClassLabel = rhs.predictedClassLabel;
62  this->predictedClusterLabel = rhs.predictedClusterLabel;
63  this->pipelineMode = rhs.pipelineMode;
64  this->predictionModuleIndex = rhs.predictionModuleIndex;
65  this->numTrainingSamples = rhs.numTrainingSamples;
66  this->numTestSamples = rhs.numTestSamples;
67  this->testAccuracy = rhs.testAccuracy;
68  this->testRMSError = rhs.testRMSError;
69  this->testSquaredError = rhs.testSquaredError;
70  this->testTime = rhs.testTime;
71  this->trainingTime = rhs.trainingTime;
72  this->testFMeasure = rhs.testFMeasure;
73  this->testPrecision = rhs.testPrecision;
74  this->testRecall = rhs.testRecall;
75  this->regressionData = rhs.regressionData;
76  this->testRejectionPrecision = rhs.testRejectionPrecision;
77  this->testRejectionRecall = rhs.testRejectionRecall;
78  this->testConfusionMatrix = rhs.testConfusionMatrix;
79  this->crossValidationResults = rhs.crossValidationResults;
80  this->testResults = rhs.testResults;
81 
82  //Copy the GRT Base variables
83  this->debugLog = rhs.debugLog;
84  this->errorLog = rhs.errorLog;
85  this->trainingLog = rhs.trainingLog;
86  this->testingLog = rhs.testingLog;
87  this->warningLog = rhs.warningLog;
88 
89  for(unsigned int i=0; i<rhs.preProcessingModules.size(); i++){
90  this->addPreProcessingModule( *(rhs.preProcessingModules[i]) );
91  }
92 
93  for(unsigned int i=0; i<rhs.featureExtractionModules.size(); i++){
94  this->addFeatureExtractionModule( *(rhs.featureExtractionModules[i]) );
95  }
96 
98  setClassifier( *rhs.classifier );
99  }
100 
101  if( rhs.getIsPipelineInRegressionMode() ){
102  setRegressifier( *rhs.regressifier );
103  }
104 
105  if( rhs.getIsClustererSet() ){
106  setClusterer( *rhs.clusterer );
107  }
108 
109  for(unsigned int i=0; i<rhs.postProcessingModules.size(); i++){
110  this->addPostProcessingModule( *(rhs.postProcessingModules[i]) );
111  }
112 
113  for(unsigned int k=0; k<NUM_CONTEXT_LEVELS; k++){
114  for(unsigned int i=0; i<rhs.contextModules[k].size(); i++){
115  this->addContextModule( *(rhs.contextModules[k][i]), k );
116  }
117  }
118 
119  //Adding the modules will automatically set trained to false, so make sure we get the correct state
120  this->trained = rhs.trained;
121  }
122 
123  return *this;
124 }
125 
127  this->addPreProcessingModule( module );
128  return *this;
129 }
130 
132  this->addFeatureExtractionModule( module );
133  return *this;
134 }
135 
137  this->setClassifier( module );
138  return *this;
139 }
140 
142  this->setRegressifier( module );
143  return *this;
144 }
145 
147  this->setClusterer( module );
148  return *this;
149 }
150 
152  this->addPostProcessingModule( module );
153  return *this;
154 }
155 
157 {
158  //Clean up the memory
159  clear();
160 }
161 
163 
164  trained = false;
165  trainingTime = 0;
167 
168  if( !getIsClassifierSet() ){
169  errorLog << "train(ClassificationData trainingData) - Failed To Train Classifier, the classifier has not been set!" << std::endl;
170  return false;
171  }
172 
173  if( trainingData.getNumSamples() == 0 ){
174  errorLog << "train(ClassificationData trainingData) - Failed To Train Classifier, there is no training data!" << std::endl;
175  return false;
176  }
177 
178  //Reset all the modules
179  reset();
180 
181  //Set the input Vector dimension size
182  inputVectorDimensions = trainingData.getNumDimensions();
183 
184  //Pass the training data through any pre-processing or feature extraction units
185  UINT numDimensions = trainingData.getNumDimensions();
186 
187  //If there are any preprocessing or feature extraction modules, then get the size of the last module
190  numDimensions = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
191  }else{
192  numDimensions = preProcessingModules[ preProcessingModules.size()-1 ]->getNumOutputDimensions();
193  }
194  }
195 
196  //Start the training timer
197  Timer timer;
198  timer.start();
199 
200  ClassificationData processedTrainingData( numDimensions );
201  processedTrainingData.reserve( trainingData.getNumSamples() );
202  UINT classLabel = 0;
203  VectorFloat trainingSample;
204  for(UINT i=0; i<trainingData.getNumSamples(); i++){
205  bool okToAddProcessedData = true;
206  classLabel = trainingData[i].getClassLabel();
207  trainingSample = trainingData[i].getSample();
208 
209  //Perform any preprocessing
210  if( getIsPreProcessingSet() ){
211  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
212  if( !preProcessingModules[moduleIndex]->process( trainingSample ) ){
213  errorLog << "train(ClassificationData trainingData) - Failed to PreProcess Training Data. PreProcessingModuleIndex: ";
214  errorLog << moduleIndex;
215  errorLog << std::endl;
216  return false;
217  }
218  trainingSample = preProcessingModules[moduleIndex]->getProcessedData();
219  }
220  }
221 
222  //Compute any features
224  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
225  if( !featureExtractionModules[moduleIndex]->computeFeatures( trainingSample ) ){
226  errorLog << "train(ClassificationData trainingData) - Failed to Compute Features from Training Data. FeatureExtractionModuleIndex ";
227  errorLog << moduleIndex;
228  errorLog << std::endl;
229  return false;
230  }
231  if( featureExtractionModules[moduleIndex]->getFeatureDataReady() ){
232  trainingSample = featureExtractionModules[moduleIndex]->getFeatureVector();
233  }else{
234  okToAddProcessedData = false;
235  break;
236  }
237  }
238  }
239 
240  if( okToAddProcessedData ){
241  //Add the training sample to the processed training data
242  processedTrainingData.addSample(classLabel, trainingSample);
243  }
244 
245  }
246 
247  if( processedTrainingData.getNumSamples() != trainingData.getNumSamples() ){
248  warningLog << "train(ClassificationData trainingData) - Lost " << trainingData.getNumSamples()-processedTrainingData.getNumSamples() << " of " << trainingData.getNumSamples() << " training samples due to the processing stage!" << std::endl;
249  }
250 
251  //Store the number of training samples
252  numTrainingSamples = processedTrainingData.getNumSamples();
253 
254  //Train the classifier
255  trained = classifier->train_( processedTrainingData );
256  if( !trained ){
257  errorLog << "train(ClassificationData trainingData) - Failed To Train Classifier: " << classifier->getLastErrorMessage() << std::endl;
258  return false;
259  }
260 
261  //Store the training time
262  trainingTime = timer.getMilliSeconds();
263 
264  return true;
265 }
266 
267 bool GestureRecognitionPipeline::train(const ClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling){
268 
269  trained = false;
270  trainingTime = 0;
272 
273  if( !getIsClassifierSet() ){
274  errorLog << "train(const ClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed To Train Classifier, the classifier has not been set!" << std::endl;
275  return false;
276  }
277 
278  if( trainingData.getNumSamples() == 0 ){
279  errorLog << "train(const ClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed To Train Classifier, there is no training data!" << std::endl;
280  return false;
281  }
282 
283  //Reset all the modules
284  reset();
285 
286  //Start the training timer
287  Timer timer;
288  timer.start();
289 
290  //Get a copy of the data so we can spilt it
291  ClassificationData data = trainingData;
292 
293  //Spilt the data into K folds
294  bool spiltResult = data.spiltDataIntoKFolds(kFoldValue, useStratifiedSampling);
295 
296  if( !spiltResult ){
297  return false;
298  }
299 
300  //Run the k-fold training and testing
301  Float crossValidationAccuracy = 0;
302  ClassificationData foldTrainingData;
303  ClassificationData foldTestData;
304  Vector< TestResult > cvResults(kFoldValue);
305 
306  for(UINT k=0; k<kFoldValue; k++){
308  foldTrainingData = data.getTrainingFoldData(k);
309 
310  if( !train( foldTrainingData ) ){
311  return false;
312  }
313 
314  //Test the classification system
315  foldTestData = data.getTestFoldData(k);
316 
317  if( !test( foldTestData ) ){
318  return false;
319  }
320 
321  crossValidationAccuracy += getTestAccuracy();
322  cvResults[k] = getTestResults();
323  }
324 
325  //Flag that the model has been trained
326  trained = true;
327 
328  //Set the accuracy of the classification system averaged over the kfolds
329  testAccuracy = crossValidationAccuracy / Float(kFoldValue);
330  crossValidationResults = cvResults;
331 
332  //Store the training time
333  trainingTime = timer.getMilliSeconds();
334 
335  return true;
336 }
337 
339 
340  trained = false;
341  trainingTime = 0;
343 
344  if( !getIsClassifierSet() ){
345  errorLog << "train(const TimeSeriesClassificationData &trainingData) - Failed To Train Classifier, the classifier has not been set!" << std::endl;
346  return false;
347  }
348 
349  if( trainingData.getNumSamples() == 0 ){
350  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To Train Classifier, there is no training data!" << std::endl;
351  return false;
352  }
353 
354  //Reset all the modules
355  reset();
356 
357  //Start the training timer
358  Timer timer;
359  timer.start();
360 
361  //Set the input Vector dimension size of the pipeline
362  inputVectorDimensions = trainingData.getNumDimensions();
363 
364  TimeSeriesClassificationData processedTrainingData( trainingData.getNumDimensions() );
365  TimeSeriesClassificationData timeseriesClassificationData;
366  ClassificationData classificationData;
367 
368  bool allowNullGestureClass = true;
369  processedTrainingData.setAllowNullGestureClass( allowNullGestureClass );
370  timeseriesClassificationData.setAllowNullGestureClass( allowNullGestureClass );
371  classificationData.setAllowNullGestureClass( allowNullGestureClass );
372 
373  //Setup the data structure, if the classifier works with timeseries data then we use TimeSeriesClassificationData
374  //otherwise we format the data as ClassificationData
375  if( classifier->getTimeseriesCompatible() ){
376  UINT trainingDataInputDimensionSize = trainingData.getNumDimensions();
377  if( getIsPreProcessingSet() ){
378  trainingDataInputDimensionSize = preProcessingModules[ preProcessingModules.size()-1 ]->getNumOutputDimensions();
379  }
381  trainingDataInputDimensionSize = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
382  }
383  timeseriesClassificationData.setNumDimensions( trainingDataInputDimensionSize );
384  }else{
385  UINT trainingDataInputDimensionSize = trainingData.getNumDimensions();
386  if( getIsPreProcessingSet() ){
387  trainingDataInputDimensionSize = preProcessingModules[ preProcessingModules.size()-1 ]->getNumOutputDimensions();
388  }
390  trainingDataInputDimensionSize = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
391  }
392  classificationData.setNumDimensions( trainingDataInputDimensionSize );
393  }
394 
395  //Pass the timeseries data through any pre-processing modules and add it to the processedTrainingData structure
396  for(UINT i=0; i<trainingData.getNumSamples(); i++){
397  UINT classLabel = trainingData[i].getClassLabel();
398  MatrixFloat trainingSample = trainingData[i].getData();
399 
400  if( getIsPreProcessingSet() ){
401 
402  //Try to process the matrix data row-by-row
403  bool resetPreprocessingModule = true;
404  for(UINT r=0; r<trainingSample.getNumRows(); r++){
405  VectorFloat sample = trainingSample.getRow( r );
406 
407  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
408 
409  if( resetPreprocessingModule ){
410  preProcessingModules[moduleIndex]->reset();
411  }
412 
413  //Validate the input and output dimensions match!
414  if( preProcessingModules[moduleIndex]->getNumInputDimensions() != preProcessingModules[moduleIndex]->getNumOutputDimensions() ){
415  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To PreProcess Training Data. The number of inputDimensions (";
416  errorLog << preProcessingModules[moduleIndex]->getNumInputDimensions();
417  errorLog << ") in PreProcessingModule ";
418  errorLog << moduleIndex;
419  errorLog << " do not match the number of outputDimensions (";
420  errorLog << preProcessingModules[moduleIndex]->getNumOutputDimensions();
421  errorLog << std::endl;
422  return false;
423  }
424 
425  if( !preProcessingModules[moduleIndex]->process( sample ) ){
426  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To PreProcess Training Data. PreProcessingModuleIndex: ";
427  errorLog << moduleIndex;
428  errorLog << std::endl;
429  return false;
430  }
431  sample = preProcessingModules[moduleIndex]->getProcessedData();
432  }
433 
434  //The preprocessing modules should only be reset when r==0
435  resetPreprocessingModule = false;
436 
437  //Overwrite the original training sample with the preProcessed sample
438  for(UINT c=0; c<sample.size(); c++){
439  trainingSample[r][c] = sample[c];
440  }
441  }
442 
443  }
444 
445  //Add the training sample to the processed training data
446  processedTrainingData.addSample(classLabel,trainingSample);
447  }
448 
449  //Loop over the processed training data, perfrom any feature extraction if needed
450  //Add the data to either the timeseries or classification data structures
451  for(UINT i=0; i<processedTrainingData.getNumSamples(); i++){
452  UINT classLabel = processedTrainingData[i].getClassLabel();
453  MatrixFloat trainingSample = processedTrainingData[i].getData();
454  bool featureDataReady = false;
455  bool resetFeatureExtractionModules = true;
456 
457  VectorFloat inputVector;
458  MatrixFloat featureData;
459  //Try to process the matrix data row-by-row
460  for(UINT r=0; r<trainingSample.getNumRows(); r++){
461  inputVector = trainingSample.getRow( r );
462  featureDataReady = true;
463 
464  //Pass the processed training data through the feature extraction
466 
467  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
468 
469  if( resetFeatureExtractionModules ){
470  featureExtractionModules[moduleIndex]->reset();
471  }
472 
473  if( !featureExtractionModules[moduleIndex]->computeFeatures( inputVector ) ){
474  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To Compute Features For Training Data. FeatureExtractionModuleIndex: ";
475  errorLog << moduleIndex;
476  errorLog << std::endl;
477  return false;
478  }
479 
480  //Overwrite the input Vector with the features so this can either be input to the next feature module
481  //or converted to the LabelledClassificationData format
482  inputVector = featureExtractionModules[moduleIndex]->getFeatureVector();
483  featureDataReady = featureExtractionModules[moduleIndex]->getFeatureDataReady();
484 
485  //If feature data is not ready at any stage, stop the rest of the pipeline.
486  if( !featureDataReady ) { break; }
487  }
488 
489  //The feature extraction modules should only be reset on r == 0
490  resetFeatureExtractionModules = false;
491 
492  if( featureDataReady ){
493 
494  if( classifier->getTimeseriesCompatible() ){
495  if( !featureData.push_back( inputVector ) ){
496  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To add feature Vector to feature data matrix! FeatureExtractionModuleIndex: " << std::endl;
497  return false;
498  }
499  }else classificationData.addSample(classLabel, inputVector);
500  }
501 
502  }else{
503  if( classifier->getTimeseriesCompatible() ){
504  if( !featureData.push_back( inputVector ) ){
505  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To add feature Vector to feature data matrix! FeatureExtractionModuleIndex: " << std::endl;
506  return false;
507  }
508  }
509  else classificationData.addSample(classLabel, inputVector);
510  }
511  }
512 
513  if( classifier->getTimeseriesCompatible() ) timeseriesClassificationData.addSample(classLabel, featureData);
514 
515  }
516 
517  //Train the classification system
518  if( classifier->getTimeseriesCompatible() ){
519  numTrainingSamples = timeseriesClassificationData.getNumSamples();
520  trained = classifier->train( timeseriesClassificationData );
521  }else{
522  numTrainingSamples = classificationData.getNumSamples();
523  trained = classifier->train( classificationData );
524  }
525 
526  if( !trained ){
527  errorLog << "train(TimeSeriesClassificationData trainingData) - Failed To Train Classifier" << classifier->getLastErrorMessage() << std::endl;
528  return false;
529  }
530 
531  //Store the training time
532  trainingTime = timer.getMilliSeconds();
533 
534  return true;
535 }
536 
537 bool GestureRecognitionPipeline::train(const TimeSeriesClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling){
538 
539  trained = false;
540  trainingTime = 0;
542 
543  if( !getIsClassifierSet() ){
544  errorLog << "train(const TimeSeriesClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed To Train Classifier, the classifier has not been set!" << std::endl;
545  return false;
546  }
547 
548  if( trainingData.getNumSamples() == 0 ){
549  errorLog << "train(const TimeSeriesClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed To Train Classifier, there is no training data!" << std::endl;
550  return false;
551  }
552 
553  //Reset all the modules
554  reset();
555 
556  //Start the training timer
557  Timer timer;
558  timer.start();
559 
560  //Get a copy of the data so we can split it
561  TimeSeriesClassificationData data = trainingData;
562 
563  //Spilt the data into K folds
564  if( !data.spiltDataIntoKFolds(kFoldValue, useStratifiedSampling) ){
565  errorLog << "train(const TimeSeriesClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed To Spilt Dataset into KFolds!" << std::endl;
566  return false;
567  }
568 
569  //Run the k-fold training and testing
570  Float crossValidationAccuracy = 0;
571  TimeSeriesClassificationData foldTrainingData;
572  TimeSeriesClassificationData foldTestData;
573 
574  for(UINT k=0; k<kFoldValue; k++){
576  foldTrainingData = data.getTrainingFoldData(k);
577 
578  if( !train( foldTrainingData ) ){
579  errorLog << "train(const TimeSeriesClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed to train pipeline for fold " << k << "." << std::endl;
580  return false;
581  }
582 
583  //Test the classification system
584  foldTestData = data.getTestFoldData(k);
585 
586  if( !test( foldTestData ) ){
587  errorLog << "train(const TimeSeriesClassificationData &trainingData,const UINT kFoldValue,const bool useStratifiedSampling) - Failed to test pipeline for fold " << k << "." << std::endl;
588  return false;
589  }
590 
591  crossValidationAccuracy += getTestAccuracy();
592  }
593 
594  //Flag that the model has been trained
595  trained = true;
596 
597  //Set the accuracy of the classification system averaged over the kfolds
598  testAccuracy = crossValidationAccuracy / Float(kFoldValue);
599 
600  //Store the training time
601  trainingTime = timer.getMilliSeconds();
602 
603  return true;
604 }
605 
607 
608  trained = false;
609  trainingTime = 0;
611 
612  if( !getIsClassifierSet() ){
613  errorLog << "train(ClassificationDataStream trainingData) - Failed To train Classifier, the classifier has not been set!" << std::endl;
614  return false;
615  }
616 
617  if( trainingData.getNumSamples() == 0 ){
618  errorLog << "train(ClassificationDataStream trainingData) - Failed To train Classifier, there is no training data!" << std::endl;
619  return false;
620  }
621 
622  //Reset all the modules
623  reset();
624 
625  //Set the input Vector dimension size
626  inputVectorDimensions = trainingData.getNumDimensions();
627 
628  //Pass the training data through any pre-processing or feature extraction units
629  UINT numDimensions = inputVectorDimensions;
630 
631  //If there are any preprocessing or feature extraction modules, then get the size of the last module
634  numDimensions = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
635  }else{
636  numDimensions = preProcessingModules[ preProcessingModules.size()-1 ]->getNumOutputDimensions();
637  }
638  }
639 
640  //Start the training timer
641  Timer timer;
642  timer.start();
643 
644  ClassificationData processedTrainingData( numDimensions );
645  processedTrainingData.reserve( trainingData.getNumSamples() );
646  UINT classLabel = 0;
647  VectorFloat trainingSample;
648  for(UINT i=0; i<trainingData.getNumSamples(); i++){
649  bool okToAddProcessedData = true;
650  classLabel = trainingData[i].getClassLabel();
651  trainingSample = trainingData[i].getSample();
652 
653  //Perform any preprocessing
654  if( getIsPreProcessingSet() ){
655  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
656  if( !preProcessingModules[moduleIndex]->process( trainingSample ) ){
657  errorLog << "train(ClassificationDataStream trainingData) - Failed to PreProcess training Data. PreProcessingModuleIndex: ";
658  errorLog << moduleIndex;
659  errorLog << std::endl;
660  return false;
661  }
662  trainingSample = preProcessingModules[moduleIndex]->getProcessedData();
663  }
664  }
665 
666  //Compute any features
668  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
669  if( !featureExtractionModules[moduleIndex]->computeFeatures( trainingSample ) ){
670  errorLog << "train(ClassificationDataStream trainingData) - Failed to Compute Features from training Data. FeatureExtractionModuleIndex ";
671  errorLog << moduleIndex;
672  errorLog << std::endl;
673  return false;
674  }
675  if( featureExtractionModules[moduleIndex]->getFeatureDataReady() ){
676  trainingSample = featureExtractionModules[moduleIndex]->getFeatureVector();
677  }else{
678  okToAddProcessedData = false;
679  break;
680  }
681  }
682  }
683 
684  if( okToAddProcessedData ){
685  //Add the training sample to the processed training data
686  processedTrainingData.addSample(classLabel, trainingSample);
687  }
688 
689  }
690 
691  if( processedTrainingData.getNumSamples() != trainingData.getNumSamples() ){
692  warningLog << "train(ClassificationDataStream trainingData) - Lost " << trainingData.getNumSamples()-processedTrainingData.getNumSamples() << " of " << trainingData.getNumSamples() << " training samples due to the processing stage!" << std::endl;
693  }
694 
695  //Store the number of training samples
696  numTrainingSamples = processedTrainingData.getNumSamples();
697 
698  //Train the classifier
699  trained = classifier->train_( processedTrainingData );
700  if( !trained ){
701  errorLog << "train(ClassificationDataStream trainingData) - Failed To Train Classifier: " << classifier->getLastErrorMessage() << std::endl;
702  return false;
703  }
704 
705  //Store the training time
706  trainingTime = timer.getMilliSeconds();
707 
708  return true;
709 }
710 
712 
713  trained = false;
714  trainingTime = 0;
716 
717  //Reset all the modules
718  reset();
719 
720  //Start the training timer
721  Timer timer;
722  timer.start();
723 
724  //Set the input Vector dimension size
725  inputVectorDimensions = trainingData.getNumInputDimensions();
726 
727  //Pass the training data through any pre-processing or feature extraction units
728  RegressionData processedTrainingData;
729 
730  //Set the dimensionality of the data
731  UINT numInputs = 0;
732  UINT numTargets = trainingData.getNumTargetDimensions();
734  numInputs = trainingData.getNumInputDimensions();
735  }else{
736 
738  numInputs = preProcessingModules[ preProcessingModules.size()-1 ]->getNumOutputDimensions();
739  }
740 
742  numInputs = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
743  }
744 
746  numInputs = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
747  }
748  }
749 
750  processedTrainingData.setInputAndTargetDimensions(numInputs, numTargets);
751 
752  for(UINT i=0; i<trainingData.getNumSamples(); i++){
753  VectorFloat inputVector = trainingData[i].getInputVector();
754  VectorFloat targetVector = trainingData[i].getTargetVector();
755 
756  if( getIsPreProcessingSet() ){
757  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
758  if( !preProcessingModules[ moduleIndex ]->process( inputVector ) ){
759  errorLog << "train(const RegressionData &trainingData) - Failed To Compute Features For Training Data. PreProcessingModuleIndex: " << moduleIndex << std::endl;
760  return false;
761  }
762 
763  inputVector = preProcessingModules[ moduleIndex ]->getProcessedData();
764  }
765  }
766 
768  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
769  if( !featureExtractionModules[ moduleIndex ]->computeFeatures( inputVector ) ){
770  errorLog << "train(const RegressionData &trainingData) - Failed To Compute Features For Training Data. FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
771  return false;
772  }
773 
774  inputVector = featureExtractionModules[ moduleIndex ]->getFeatureVector();
775  }
776  }
777 
778  //Add the training sample to the processed training data
779  if( !processedTrainingData.addSample(inputVector,targetVector) ){
780  errorLog << "train(const RegressionData &trainingData) - Failed to add processed training sample to training data" << std::endl;
781  return false;
782  }
783  }
784 
785  //Store the number of training samples
786  numTrainingSamples = processedTrainingData.getNumSamples();
787 
788  //Train the classification system
789  if( getIsRegressifierSet() ){
790  trained = regressifier->train( processedTrainingData );
791  if( !trained ){
792  errorLog << "train(const RegressionData &trainingData) - Failed To Train Regressifier: " << regressifier->getLastErrorMessage() << std::endl;
793  return false;
794  }
795  }else{
796  errorLog << "train(const RegressionData &trainingData) - Classifier is not set" << std::endl;
797  return false;
798  }
799 
800  //Store the training time
801  trainingTime = timer.getMilliSeconds();
802 
803  return true;
804 }
805 
806 bool GestureRecognitionPipeline::train(const RegressionData &trainingData,const UINT kFoldValue){
807 
808  trained = false;
809  trainingTime = 0;
811 
812  if( !getIsRegressifierSet() ){
813  errorLog << "train(const RegressionData &trainingData,const UINT kFoldValue) - Failed To Train Regressifier, the regressifier has not been set!" << std::endl;
814  return false;
815  }
816 
817  if( trainingData.getNumSamples() == 0 ){
818  errorLog << "train(const RegressionData &trainingData,const UINT kFoldValue) - Failed To Train Regressifier, there is no training data!" << std::endl;
819  return false;
820  }
821 
822  //Reset all the modules
823  reset();
824 
825  //Start the training timer
826  Timer timer;
827  timer.start();
828 
829  //Get a copy of the training data so we can split it
830  RegressionData data = trainingData;
831 
832  //Spilt the data into K folds
833  bool spiltResult = data.spiltDataIntoKFolds(kFoldValue);
834 
835  if( !spiltResult ){
836  return false;
837  }
838 
839  //Run the k-fold training and testing
840  Float crossValidationAccuracy = 0;
841  RegressionData foldTrainingData;
842  RegressionData foldTestData;
843  for(UINT k=0; k<kFoldValue; k++){
845  foldTrainingData = data.getTrainingFoldData(k);
846 
847  if( !train( foldTrainingData ) ){
848  return false;
849  }
850 
851  //Test the classification system
852  foldTestData = data.getTestFoldData(k);
853 
854  if( !test( foldTestData ) ){
855  return false;
856  }
857 
858  crossValidationAccuracy += getTestRMSError();
859 
860  }
861 
862  //Flag that the model has been trained
863  trained = true;
864 
865  testAccuracy = crossValidationAccuracy / Float(kFoldValue);
866 
867  //Store the training time
868  trainingTime = timer.getMilliSeconds();
869 
870  return true;
871 }
872 
874 
875  trained = false;
876  trainingTime = 0;
878 
879  if( !getIsClustererSet() ){
880  errorLog << "train(const UnlabelledData &trainingData) - Failed To Train Clusterer, the clusterer has not been set!" << std::endl;
881  return false;
882  }
883 
884  if( trainingData.getNumSamples() == 0 ){
885  errorLog << "train(const UnlabelledData &trainingData) - Failed To Train Clusterer, there is no training data!" << std::endl;
886  return false;
887  }
888 
889  //Reset all the modules
890  reset();
891 
892  //Set the input Vector dimension size
893  inputVectorDimensions = trainingData.getNumDimensions();
894 
895  //Pass the training data through any pre-processing or feature extraction units
896  UINT numDimensions = trainingData.getNumDimensions();
897 
898  //If there are any preprocessing or feature extraction modules, then get the size of the last module
901  numDimensions = featureExtractionModules[ featureExtractionModules.size()-1 ]->getNumOutputDimensions();
902  }else{
903  numDimensions = preProcessingModules[ preProcessingModules.size()-1 ]->getNumOutputDimensions();
904  }
905  }
906 
907  //Start the training timer
908  Timer timer;
909  timer.start();
910 
911  UnlabelledData processedTrainingData( numDimensions );
912 
913  for(UINT i=0; i<trainingData.getNumSamples(); i++){
914  bool okToAddProcessedData = true;
915  VectorFloat trainingSample = trainingData[i];
916 
917  //Perform any preprocessing
918  if( getIsPreProcessingSet() ){
919  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
920  if( !preProcessingModules[moduleIndex]->process( trainingSample ) ){
921  errorLog << "train(const UnlabelledData &trainingData) - Failed to PreProcess Training Data. PreProcessingModuleIndex: ";
922  errorLog << moduleIndex;
923  errorLog << std::endl;
924  return false;
925  }
926  trainingSample = preProcessingModules[moduleIndex]->getProcessedData();
927  }
928  }
929 
930  //Compute any features
932  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
933  if( !featureExtractionModules[moduleIndex]->computeFeatures( trainingSample ) ){
934  errorLog << "train(const UnlabelledData &trainingData) - Failed to Compute Features from Training Data. FeatureExtractionModuleIndex ";
935  errorLog << moduleIndex;
936  errorLog << std::endl;
937  return false;
938  }
939  if( featureExtractionModules[moduleIndex]->getFeatureDataReady() ){
940  trainingSample = featureExtractionModules[moduleIndex]->getFeatureVector();
941  }else{
942  okToAddProcessedData = false;
943  break;
944  }
945  }
946  }
947 
948  if( okToAddProcessedData ){
949  //Add the training sample to the processed training data
950  processedTrainingData.addSample(trainingSample);
951  }
952 
953  }
954 
955  if( processedTrainingData.getNumSamples() != trainingData.getNumSamples() ){
956 
957  warningLog << "train(const ClassificationData &trainingData) - Lost " << trainingData.getNumSamples()-processedTrainingData.getNumSamples() << " of " << trainingData.getNumSamples() << " training samples due to the processing stage!" << std::endl;
958  }
959 
960  //Store the number of training samples
961  numTrainingSamples = processedTrainingData.getNumSamples();
962 
963  //Train the cluster model
964  trained = clusterer->train_( processedTrainingData );
965  if( !trained ){
966  errorLog << "train(const UnlabelledData &trainingData) - Failed To Train Clusterer: " << clusterer->getLastErrorMessage() << std::endl;
967  return false;
968  }
969 
970  //Store the training time
971  trainingTime = timer.getMilliSeconds();
972 
973  return true;
974 }
975 
977 
978  //Clear any previous test results
980 
981  //Make sure the classification model has been trained
982  if( !trained ){
983  errorLog << "test(const ClassificationData &testData) - Classifier is not trained" << std::endl;
984  return false;
985  }
986 
987  //Make sure the dimensionality of the test data matches the input Vector's dimensions
988  if( testData.getNumDimensions() != inputVectorDimensions ){
989  errorLog << "test(const ClassificationData &testData) - The dimensionality of the test data (" + Util::toString(testData.getNumDimensions()) + ") does not match that of the input Vector dimensions of the pipeline (" << inputVectorDimensions << ")" << std::endl;
990  return false;
991  }
992 
993  if( !getIsClassifierSet() ){
994  errorLog << "test(const ClassificationData &testData) - The classifier has not been set" << std::endl;
995  return false;
996  }
997 
998  //Reset all the modules
999  reset();
1000 
1001  //Validate that the class labels in the test data match the class labels in the model
1002  bool classLabelValidationPassed = true;
1003  for(UINT i=0; i<testData.getNumClasses(); i++){
1004  bool labelFound = false;
1005  for(UINT k=0; k<classifier->getNumClasses(); k++){
1006  if( testData.getClassTracker()[i].classLabel == classifier->getClassLabels()[k] ){
1007  labelFound = true;
1008  break;
1009  }
1010  }
1011 
1012  if( !labelFound ){
1013  classLabelValidationPassed = false;
1014  errorLog << "test(const ClassificationData &testData) - The test dataset contains a class label (" << testData.getClassTracker()[i].classLabel << ") that is not in the model!" << std::endl;
1015  }
1016  }
1017 
1018  if( !classLabelValidationPassed ){
1019  errorLog << "test(const ClassificationData &testData) - Model Class Labels: ";
1020  for(UINT k=0; k<classifier->getNumClasses(); k++){
1021  errorLog << classifier->getClassLabels()[k] << "\t";
1022  }
1023  errorLog << std::endl;
1024  return false;
1025  }
1026 
1027  Float rejectionPrecisionCounter = 0;
1028  Float rejectionRecallCounter = 0;
1029  unsigned int confusionMatrixSize = classifier->getNullRejectionEnabled() ? classifier->getNumClasses()+1 : classifier->getNumClasses();
1030  VectorFloat precisionCounter(classifier->getNumClasses(), 0);
1031  VectorFloat recallCounter(classifier->getNumClasses(), 0);
1032  VectorFloat confusionMatrixCounter(confusionMatrixSize,0);
1033 
1034  //Resize the test matrix
1035  testConfusionMatrix.resize(confusionMatrixSize, confusionMatrixSize);
1036  testConfusionMatrix.setAllValues(0);
1037 
1038  //Resize the precision and recall Vectors
1039  testPrecision.clear();
1040  testRecall.clear();
1041  testFMeasure.clear();
1042  testPrecision.resize(getNumClassesInModel(), 0);
1043  testRecall.resize(getNumClassesInModel(), 0);
1044  testFMeasure.resize(getNumClassesInModel(), 0);
1045  testResults.resize(testData.getNumSamples());
1046  numTestSamples = testData.getNumSamples();
1047 
1048  //Start the test timer
1049  Timer timer;
1050  timer.start();
1051 
1052  //Run the test
1053  for(UINT i=0; i<numTestSamples; i++){
1054  UINT classLabel = testData[i].getClassLabel();
1055  VectorFloat testSample = testData[i].getSample();
1056 
1057  //Pass the test sample through the pipeline
1058  if( !predict( testSample ) ){
1059  errorLog << "test(const ClassificationData &testData) - Prediction failed for test sample at index: " << i << std::endl;
1060  return false;
1061  }
1062 
1063  //Update the test metrics
1064  UINT predictedClassLabel = getPredictedClassLabel();
1065 
1066  if( !updateTestMetrics(classLabel,predictedClassLabel,precisionCounter,recallCounter,rejectionPrecisionCounter,rejectionRecallCounter, confusionMatrixCounter) ){
1067  errorLog << "test(const ClassificationData &testData) - Failed to update test metrics at test sample index: " << i << std::endl;
1068  return false;
1069  }
1070  //cout << "i: " << i << " class label: " << classLabel << " predictedClassLabel: " << predictedClassLabel << std::endl;
1071 
1072  //Keep track of the classification results encase the user needs them later
1073  testResults[i].setClassificationResult(i, classLabel, predictedClassLabel, getUnProcessedPredictedClassLabel(),getClassLikelihoods(), getClassDistances());
1074 
1075  //Update any observers
1076  classifier->notifyTestResultsObservers( testResults[i] );
1077  }
1078 
1079  if( !computeTestMetrics(precisionCounter,recallCounter,rejectionPrecisionCounter,rejectionRecallCounter, confusionMatrixCounter, numTestSamples) ){
1080  errorLog <<"test(const ClassificationData &testData) - Failed to compute test metrics!" << std::endl;
1081  return false;
1082  }
1083 
1084  testTime = timer.getMilliSeconds();
1085 
1086  return true;
1087 }
1088 
1090 
1091  //Clear any previous test results
1092  clearTestResults();
1093 
1094  //Make sure the classification model has been trained
1095  if( !trained ){
1096  errorLog << "test(const TimeSeriesClassificationData &testData) - The classifier has not been trained" << std::endl;
1097  return false;
1098  }
1099 
1100  //Make sure the dimensionality of the test data matches the input Vector's dimensions
1101  if( testData.getNumDimensions() != inputVectorDimensions ){
1102  errorLog << "test(const TimeSeriesClassificationData &testData) - The dimensionality of the test data (" << testData.getNumDimensions() << ") does not match that of the input Vector dimensions of the pipeline (" << inputVectorDimensions << ")" << std::endl;
1103  return false;
1104  }
1105 
1106  if( !getIsClassifierSet() ){
1107  errorLog << "test(const TimeSeriesClassificationData &testData) - The classifier has not been set" << std::endl;
1108  return false;
1109  }
1110 
1111  //Reset all the modules
1112  reset();
1113 
1114  Float rejectionPrecisionCounter = 0;
1115  Float rejectionRecallCounter = 0;
1116  const UINT K = classifier->getNumClasses();
1117  UINT confusionMatrixSize = classifier->getNullRejectionEnabled() ? K+1 : K;
1118  VectorFloat precisionCounter(K, 0);
1119  VectorFloat recallCounter(K, 0);
1120  VectorFloat confusionMatrixCounter(confusionMatrixSize,0);
1121 
1122  //Resize the test matrix
1123  testConfusionMatrix.resize(confusionMatrixSize,confusionMatrixSize);
1124  testConfusionMatrix.setAllValues(0);
1125 
1126  //Resize the precision and recall Vectors
1127  testPrecision.resize(K, 0);
1128  testRecall.resize(K, 0);
1129  testFMeasure.resize(K, 0);
1130  numTestSamples = testData.getNumSamples();
1131 
1132  //Start the test timer
1133  Timer timer;
1134  timer.start();
1135 
1136  //Run the test
1137  const UINT M = testData.getNumSamples();
1138  for(UINT i=0; i<M; i++){
1139  UINT classLabel = testData[i].getClassLabel();
1140  MatrixFloat timeseries = testData[i].getData();
1141 
1142  //Pass the test timeseries through the pipeline
1143  if( !predict( timeseries ) ){
1144  errorLog << "test(const TimeSeriesClassificationData &testData) - Failed to run prediction for test sample index: " << i << std::endl;
1145  return false;
1146  }
1147 
1148  //Update the test metrics
1149  UINT predictedClassLabel = getPredictedClassLabel();
1150 
1151  if( !updateTestMetrics(classLabel,predictedClassLabel,precisionCounter,recallCounter,rejectionPrecisionCounter,rejectionRecallCounter, confusionMatrixCounter) ){
1152  errorLog << "test(const TimeSeriesClassificationData &testData) - Failed to update test metrics at test sample index: " << i << std::endl;
1153  return false;
1154  }
1155 
1156  }
1157 
1158  if( !computeTestMetrics(precisionCounter,recallCounter,rejectionPrecisionCounter,rejectionRecallCounter, confusionMatrixCounter, M) ){
1159  errorLog << "test(const TimeSeriesClassificationData &testData) - Failed to compute test metrics!" << std::endl;
1160  return false;
1161  }
1162 
1163  testTime = timer.getMilliSeconds();
1164 
1165  return true;
1166 }
1167 
1169 
1170  //Clear any previous test results
1171  clearTestResults();
1172 
1173  //Make sure the classification model has been trained
1174  if( !trained ){
1175  errorLog << "test(const ClassificationDataStream &testData) - The classifier has not been trained" << std::endl;
1176  return false;
1177  }
1178 
1179  //Make sure the dimensionality of the test data matches the input Vector's dimensions
1180  if( testData.getNumDimensions() != inputVectorDimensions ){
1181  errorLog << "test(const ClassificationDataStream &testData) - The dimensionality of the test data (" + Util::toString(testData.getNumDimensions()) + ") does not match that of the input Vector dimensions of the pipeline (" << inputVectorDimensions << ")" << std::endl;
1182  return false;
1183  }
1184 
1185  if( !getIsClassifierSet() ){
1186  errorLog << "test(const ClassificationDataStream &testData) - The classifier has not been set" << std::endl;
1187  return false;
1188  }
1189 
1190  //Reset all the modules
1191  reset();
1192 
1193  //Float rejectionPrecisionCounter = 0;
1194  //Float rejectionRecallCounter = 0;
1195  UINT confusionMatrixSize = classifier->getNullRejectionEnabled() ? classifier->getNumClasses()+1 : classifier->getNumClasses();
1196  VectorFloat precisionCounter(getNumClassesInModel(), 0);
1197  VectorFloat recallCounter(getNumClassesInModel(), 0);
1198  VectorFloat confusionMatrixCounter(confusionMatrixSize,0);
1199 
1200  //Resize the test matrix
1201  testConfusionMatrix.resize(confusionMatrixSize,confusionMatrixSize);
1202  testConfusionMatrix.setAllValues(0);
1203 
1204  //Resize the precision and recall Vectors
1205  testPrecision.resize(getNumClassesInModel(), 0);
1206  testRecall.resize(getNumClassesInModel(), 0);
1207  testFMeasure.resize(getNumClassesInModel(), 0);
1208 
1209  //Resize the classification results Vector
1210  testResults.resize(testData.getNumSamples());
1211  numTestSamples = testData.getNumSamples();
1212 
1213  //Start the test timer
1214  Timer timer;
1215  timer.start();
1216 
1217  //Get a copy of the data so we can modify it
1218  ClassificationDataStream data = testData;
1219 
1220  //Run the test
1221  data.resetPlaybackIndex(0); //Make sure that the test data start at 0
1222  for(UINT i=0; i<data.getNumSamples(); i++){
1223  ClassificationSample sample = data.getNextSample();
1224  UINT classLabel = sample.getClassLabel();
1225  VectorFloat testSample = sample.getSample();
1226 
1227  //Pass the test sample through the pipeline
1228  if( !predict( testSample ) ){
1229  errorLog << "test(const ClassificationDataStream &testData) - Prediction Failed! " << classifier->getLastErrorMessage() << std::endl;
1230  return false;
1231  }
1232 
1233  //Update the test metrics
1234  UINT predictedClassLabel = getPredictedClassLabel();
1235 
1236  /* //TODO - Need to update this!
1237  if( !updateTestMetrics(classLabel,predictedClassLabel,precisionCounter,recallCounter,rejectionPrecisionCounter,rejectionRecallCounter, confusionMatrixCounter) ){
1238  errorLog << "test(LabelledContinuousTimeSeriesClassificationData &testData) - Failed to update test metrics at test sample index: " << i << std::endl;
1239  return false;
1240  }
1241  */
1242 
1243  if( classLabel == predictedClassLabel ) testAccuracy++;
1244 
1245  //Store the test results so they can be used later
1246  testResults[i].setClassificationResult(i, classLabel, predictedClassLabel, getUnProcessedPredictedClassLabel(), getClassLikelihoods(), getClassDistances());
1247 
1248  //Notify all observers of the test result
1249  classifier->notifyTestResultsObservers( testResults[i] );
1250 
1251  testingLog << "test iteration: " << i;
1252  testingLog << "\tClassLabel: " << classLabel;
1253  testingLog << "\tPredictedClassLabel: " << predictedClassLabel;
1254  testingLog << "\tLikelihood: " << getMaximumLikelihood() << std::endl;
1255  }
1256 
1257  /* //TODO - Need to update this!
1258  if( !computeTestMetrics(precisionCounter,recallCounter,rejectionPrecisionCounter,rejectionRecallCounter, confusionMatrixCounter, testData.getNumSamples()) ){
1259  errorLog << "test(LabelledContinuousTimeSeriesClassificationData &testData) - Failed to compute test metrics !" << std::endl;
1260  return false;
1261  }
1262  */
1263 
1264  testTime = timer.getMilliSeconds();
1265  testAccuracy = testAccuracy / Float( testData.getNumSamples() ) * 100.0;
1266 
1267  testingLog << "Test complete. Total testing time: " << testTime << std::endl;
1268 
1269  return true;
1270 }
1271 
1273 
1274  //Clear any previous test results
1275  clearTestResults();
1276 
1277  //Make sure the classification model has been trained
1278  if( !trained ){
1279  errorLog << "test(const RegressionData &testData) - Regressifier is not trained" << std::endl;
1280  return false;
1281  }
1282 
1283  //Make sure the dimensionality of the test data matches the input Vector's dimensions
1284  if( testData.getNumInputDimensions() != inputVectorDimensions ){
1285  errorLog << "test(const RegressionData &testData) - The dimensionality of the test data (" << testData.getNumInputDimensions() << ") does not match that of the input Vector dimensions of the pipeline (" << inputVectorDimensions << ")" << std::endl;
1286  return false;
1287  }
1288 
1289  if( !getIsRegressifierSet() ){
1290  errorLog << "test(const RegressionData &testData) - The regressifier has not been set" << std::endl;
1291  return false;
1292  }
1293 
1294  if( regressifier->getNumOutputDimensions() != testData.getNumTargetDimensions() ){
1295  errorLog << "test(const RegressionData &testData) - The size of the output of the regressifier (" << regressifier->getNumOutputDimensions() << ") does not match that of the size of the number of target dimensions (" << testData.getNumTargetDimensions() << ")" << std::endl;
1296  return false;
1297  }
1298 
1299  //Reset all the modules
1300  reset();
1301 
1302  numTestSamples = testData.getNumSamples();
1303  testResults.resize( numTestSamples );
1304 
1305  //Start the test timer
1306  Timer timer;
1307  timer.start();
1308 
1309  //Run the test
1310  testSquaredError = 0;
1311  testRMSError = 0;
1312  for(UINT i=0; i<numTestSamples; i++){
1313  VectorFloat inputVector = testData[i].getInputVector();
1314  VectorFloat targetVector = testData[i].getTargetVector();
1315 
1316  //Pass the test sample through the pipeline
1317  if( !map( inputVector ) ){
1318  errorLog << "test(const RegressionData &testData) - Failed to map input Vector!" << std::endl;
1319  return false;
1320  }
1321 
1322  //Update the RMS error
1323  Float sum = 0;
1324  VectorFloat regressionData = regressifier->getRegressionData();
1325  for(UINT j=0; j<targetVector.size(); j++){
1326  sum += grt_sqr( regressionData[j]-targetVector[j] );
1327  }
1328 
1329  testSquaredError += sum;
1330 
1331  //Keep track of the regression results encase the user needs them later
1332  testResults[i].setRegressionResult(i,regressionData,targetVector);
1333 
1334  //Update any observers
1335  regressifier->notifyTestResultsObservers( testResults[i] );
1336  }
1337 
1338  //Compute the test metrics
1339  testRMSError = sqrt( testSquaredError / Float( testData.getNumSamples() ) );
1340 
1341  testTime = timer.getMilliSeconds();
1342 
1343  return true;
1344 }
1345 
1347 
1348  //Make sure the classification model has been trained
1349  if( !trained ){
1350  errorLog << "predict(const VectorFloat &inputVector) - The classifier has not been trained" << std::endl;
1351  return false;
1352  }
1353 
1354  //Make sure the dimensionality of the input Vector matches the inputVectorDimensions
1355  if( inputVector.size() != inputVectorDimensions ){
1356  errorLog << "predict(const VectorFloat &inputVector) - The dimensionality of the input Vector (" << int(inputVector.size()) << ") does not match that of the input Vector dimensions of the pipeline (" << inputVectorDimensions << ")" << std::endl;
1357  return false;
1358  }
1359 
1360  if( getIsClassifierSet() ){
1361  return predict_classifier( inputVector );
1362  }
1363 
1364  if( getIsRegressifierSet() ){
1365  return predict_regressifier( inputVector );
1366  }
1367 
1368  if( getIsClustererSet() ){
1369  return predict_clusterer( inputVector );
1370  }
1371 
1372  errorLog << "predict(const VectorFloat &inputVector) - Neither a classifier, regressifer or clusterer is set" << std::endl;
1373  return false;
1374 }
1375 
1377 
1378  //Make sure the classification model has been trained
1379  if( !trained ){
1380  errorLog << "predict(const MatrixFloat &inputMatrix) - The classifier has not been trained!" << std::endl;
1381  return false;
1382  }
1383 
1384  //Make sure the dimensionality of the input matrix matches the inputVectorDimensions
1385  if( input.getNumCols() != inputVectorDimensions ){
1386  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - The dimensionality of the input matrix (" << input.getNumCols() << ") does not match that of the input Vector dimensions of the pipeline (" << inputVectorDimensions << ")" << std::endl;
1387  return false;
1388  }
1389 
1390  if( !getIsClassifierSet() ){
1391  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - A classifier has not been set" << std::endl;
1392  return false;
1393  }
1394 
1395  //Get a copy of the input matrix so it can be processed
1396  MatrixFloat inputMatrix = input;
1397 
1398  //Get a pointer to the input matrix so we can pass it down the pipeline
1399  const void *data = static_cast< const void* >( &inputMatrix );
1400  DataType dataType = DATA_TYPE_MATRIX;
1401 
1402  //Setup a temporary matrix and vector
1403  //VectorFloat tmpVector;
1404  //MatrixFloat tmpMatrix;
1405 
1406  //Update the context module
1407  predictionModuleIndex = START_OF_PIPELINE;
1408 
1409  //Perform any pre-processing
1410  /*
1411  if( getIsPreProcessingSet() ){
1412 
1413  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
1414  MatrixFloat tmpMatrix( inputMatrix.getNumRows(), preProcessingModules[moduleIndex]->getNumOutputDimensions() );
1415 
1416  for(UINT i=0; i<inputMatrix.getNumRows(); i++){
1417  if( !preProcessingModules[moduleIndex]->process( inputMatrix.getRow(i) ) ){
1418  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - Failed to PreProcess Input Matrix. PreProcessingModuleIndex: " << moduleIndex << std::endl;
1419  return false;
1420  }
1421  tmpMatrix.setRowVector( preProcessingModules[moduleIndex]->getProcessedData(), i );
1422  }
1423 
1424  //Update the input matrix with the preprocessed data
1425  inputMatrix = tmpMatrix;
1426  }
1427  }
1428  */
1429 
1430  //Update the context module
1431  predictionModuleIndex = AFTER_PREPROCESSING;
1432  //Perform any feature extraction
1433  if( getIsFeatureExtractionSet() ){
1434 
1435  const void *feInput = data;
1436  const void *feOutput = NULL;
1437  const UINT numFeatureExtractionModules = featureExtractionModules.getSize();
1438  DataType inputType = DATA_TYPE_UNKNOWN;
1439  DataType outputType = DATA_TYPE_UNKNOWN;
1440  for(UINT moduleIndex=0; moduleIndex<numFeatureExtractionModules; moduleIndex++){
1441 
1442  inputType = featureExtractionModules[ moduleIndex ]->getInputType();
1443  outputType = featureExtractionModules[ moduleIndex ]->getOutputType();
1444 
1445  //Run the feature extraction algorithm
1446  switch( inputType ){
1447  case DATA_TYPE_VECTOR:
1448  if( !featureExtractionModules[ moduleIndex ]->computeFeatures( *static_cast< const VectorFloat* >( feInput ) ) ){
1449  errorLog << "predict(const MatrixFloat &inputMatrix) - Failed to PreProcess Input Matrix. FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1450  return false;
1451  }
1452  break;
1453  case DATA_TYPE_MATRIX:
1454  if( !featureExtractionModules[ moduleIndex ]->computeFeatures( *static_cast< const MatrixFloat* >( feInput ) ) ){
1455  errorLog << "predict(const MatrixFloat &inputMatrix) - Failed to PreProcess Input Matrix. FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1456  return false;
1457  }
1458  break;
1459  default:
1460  errorLog << "predict(const MatrixFloat &inputMatrix) - Failed to process data. Unknown output data type for FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1461  return false;
1462  break;
1463  }
1464 
1465  //Get the results and store them in the feOutput pointer
1466  switch( outputType ){
1467  case DATA_TYPE_VECTOR:
1468  feOutput = static_cast< const void* >( &featureExtractionModules[ moduleIndex ]->getFeatureVector() );
1469  break;
1470  case DATA_TYPE_MATRIX:
1471  feOutput = static_cast< const void* >( &featureExtractionModules[ moduleIndex ]->getFeatureMatrix() );
1472  break;
1473  default:
1474  errorLog << "predict(const MatrixFloat &inputMatrix) - Failed to process data. Unknown output data type for FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1475  return false;
1476  break;
1477  }
1478 
1479  //If there are more feature extraction modules to process, then set the feInput
1480  if( moduleIndex+1 < numFeatureExtractionModules ){
1481  feInput = feOutput;
1482  }
1483  }
1484 
1485  //Update the data pointer to the data from the last output from the end feature extraction module
1486  data = feOutput;
1487  dataType = outputType;
1488  }
1489 
1490  //Update the context module
1491  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1492 
1493  //Perform the classification
1494  switch( dataType ){
1495  case DATA_TYPE_VECTOR:
1496  if( !classifier->predict_( *(VectorFloat*)data ) ){
1497  errorLog <<"predict_timeseries(const MatrixFloat &inputMatrix) - Prediction Failed! " << classifier->getLastErrorMessage() << std::endl;
1498  return false;
1499  }
1500  break;
1501  case DATA_TYPE_MATRIX:
1502  if( !classifier->predict_( *(MatrixFloat*)data ) ){
1503  errorLog <<"predict_timeseries(const MatrixFloat &inputMatrix) - Prediction Failed! " << classifier->getLastErrorMessage() << std::endl;
1504  return false;
1505  }
1506  break;
1507  default:
1508  errorLog << "predict(const MatrixFloat &inputMatrix) - Failed to run prediction. Unknown data type!" << std::endl;
1509  return false;
1510  break;
1511  }
1512 
1513  predictedClassLabel = classifier->getPredictedClassLabel();
1514 
1515  //Update the context module
1516  //Todo
1517 
1518  //Perform any post processing
1519  predictionModuleIndex = AFTER_CLASSIFIER;
1520 /*
1521  if( getIsPostProcessingSet() ){
1522 
1523  if( pipelineMode != CLASSIFICATION_MODE){
1524  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - Pipeline Mode Is Not in CLASSIFICATION_MODE!" << std::endl;
1525  return false;
1526  }
1527 
1528  VectorFloat data;
1529  for(UINT moduleIndex=0; moduleIndex<postProcessingModules.size(); moduleIndex++){
1530 
1531  //Select which input we should give the postprocessing module
1532  if( postProcessingModules[moduleIndex]->getIsPostProcessingInputModePredictedClassLabel() ){
1533  //Set the input
1534  data.resize(1);
1535  data[0] = predictedClassLabel;
1536 
1537  //Verify that the input size is OK
1538  if( data.size() != postProcessingModules[moduleIndex]->getNumInputDimensions() ){
1539  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - The size of the data Vector (" << int(data.size()) << ") does not match that of the postProcessingModule (" << postProcessingModules[moduleIndex]->getNumInputDimensions() << ") at the moduleIndex: " << moduleIndex << std::endl;
1540  return false;
1541  }
1542 
1543  //Postprocess the data
1544  if( !postProcessingModules[moduleIndex]->process( data ) ){
1545  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - Failed to post process data. PostProcessing moduleIndex: " << moduleIndex << std::endl;
1546  return false;
1547  }
1548 
1549  //Select which output we should update
1550  data = postProcessingModules[moduleIndex]->getProcessedData();
1551  }
1552 
1553  //Select which output we should update
1554  if( postProcessingModules[moduleIndex]->getIsPostProcessingOutputModePredictedClassLabel() ){
1555  //Get the processed predicted class label
1556  data = postProcessingModules[moduleIndex]->getProcessedData();
1557 
1558  //Verify that the output size is OK
1559  if( data.size() != 1 ){
1560  errorLog << "predict_timeseries(const MatrixFloat &inputMatrix) - The size of the processed data Vector (" << int(data.size()) << ") from postProcessingModule at the moduleIndex: " << moduleIndex << " is not equal to 1 even though it is in OutputModePredictedClassLabel!" << std::endl;
1561  return false;
1562  }
1563 
1564  //Update the predicted class label
1565  predictedClassLabel = (UINT)data[0];
1566  }
1567 
1568  }
1569  }
1570 */
1571  //Update the context module
1572  //TODO
1573  predictionModuleIndex = END_OF_PIPELINE;
1574  return true;
1575 }
1576 
1578  return predict_regressifier( inputVector );
1579 }
1580 
1581 bool GestureRecognitionPipeline::predict_classifier(const VectorFloat &input){
1582 
1583  predictedClassLabel = 0;
1584  VectorFloat inputVector = input;
1585 
1586  //Update the context module
1587  predictionModuleIndex = START_OF_PIPELINE;
1588  if( contextModules[ START_OF_PIPELINE ].size() > 0 ){
1589  for(UINT moduleIndex=0; moduleIndex<contextModules[ START_OF_PIPELINE ].size(); moduleIndex++){
1590  if( !contextModules[ START_OF_PIPELINE ][moduleIndex]->process( inputVector ) ){
1591  errorLog << "predict_classifier(const VectorFloat &inputVector) - Context Module Failed at START_OF_PIPELINE. ModuleIndex: " << moduleIndex << std::endl;
1592  return false;
1593  }
1594  if( !contextModules[ START_OF_PIPELINE ][moduleIndex]->getOK() ){
1595  return true;
1596  }
1597  inputVector = contextModules[ START_OF_PIPELINE ][moduleIndex]->getProcessedData();
1598  }
1599  }
1600 
1601  //Perform any pre-processing
1602  if( getIsPreProcessingSet() ){
1603  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
1604  if( !preProcessingModules[moduleIndex]->process( inputVector ) ){
1605  errorLog << "predict_classifier(const VectorFloat &inputVector) - Failed to PreProcess Input Vector. PreProcessingModuleIndex: " << moduleIndex << std::endl;
1606  return false;
1607  }
1608  inputVector = preProcessingModules[moduleIndex]->getProcessedData();
1609  }
1610  }
1611 
1612  //Update the context module
1613  predictionModuleIndex = AFTER_PREPROCESSING;
1614  if( contextModules[ AFTER_PREPROCESSING ].size() ){
1615  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_PREPROCESSING ].size(); moduleIndex++){
1616  if( !contextModules[ AFTER_PREPROCESSING ][moduleIndex]->process( inputVector ) ){
1617  errorLog << "predict_classifier(VectorFloat inputVector) - Context Module Failed at AFTER_PREPROCESSING. ModuleIndex: " << moduleIndex << std::endl;
1618  return false;
1619  }
1620  if( !contextModules[ AFTER_PREPROCESSING ][moduleIndex]->getOK() ){
1621  predictionModuleIndex = AFTER_PREPROCESSING;
1622  return false;
1623  }
1624  inputVector = contextModules[ AFTER_PREPROCESSING ][moduleIndex]->getProcessedData();
1625  }
1626  }
1627 
1628  //Perform any feature extraction
1629  if( getIsFeatureExtractionSet() ){
1630  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
1631  if( !featureExtractionModules[moduleIndex]->computeFeatures( inputVector ) ){
1632  errorLog << "predict_classifier(VectorFloat inputVector) - Failed to compute features from data. FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1633  return false;
1634  }
1635  inputVector = featureExtractionModules[moduleIndex]->getFeatureVector();
1636  }
1637  }
1638 
1639  //Update the context module
1640  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1641  if( contextModules[ AFTER_FEATURE_EXTRACTION ].size() ){
1642  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_FEATURE_EXTRACTION ].size(); moduleIndex++){
1643  if( !contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->process( inputVector ) ){
1644  errorLog << "predict_classifier(VectorFloat inputVector) - Context Module Failed at AFTER_FEATURE_EXTRACTION. ModuleIndex: " << moduleIndex << std::endl;
1645  return false;
1646  }
1647  if( !contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->getOK() ){
1648  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1649  return false;
1650  }
1651  inputVector = contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->getProcessedData();
1652  }
1653  }
1654 
1655  //Perform the classification
1656  if( !classifier->predict(inputVector) ){
1657  errorLog << "predict_classifier(VectorFloat inputVector) - Prediction Failed! " << classifier->getLastErrorMessage() << std::endl;
1658  return false;
1659  }
1660  predictedClassLabel = classifier->getPredictedClassLabel();
1661 
1662  //Update the context module
1663  if( contextModules[ AFTER_CLASSIFIER ].size() ){
1664  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_CLASSIFIER ].size(); moduleIndex++){
1665  if( !contextModules[ AFTER_CLASSIFIER ][moduleIndex]->process( VectorFloat(1,predictedClassLabel) ) ){
1666  errorLog << "predict_classifier(VectorFloat inputVector) - Context Module Failed at AFTER_CLASSIFIER. ModuleIndex: " << moduleIndex << std::endl;
1667  return false;
1668  }
1669  if( !contextModules[ AFTER_CLASSIFIER ][moduleIndex]->getOK() ){
1670  predictionModuleIndex = AFTER_CLASSIFIER;
1671  return false;
1672  }
1673  predictedClassLabel = (UINT)contextModules[ AFTER_CLASSIFIER ][moduleIndex]->getProcessedData()[0];
1674  }
1675  }
1676 
1677  //Perform any post processing
1678  predictionModuleIndex = AFTER_CLASSIFIER;
1679  if( getIsPostProcessingSet() ){
1680 
1681  if( pipelineMode != CLASSIFICATION_MODE){
1682  errorLog << "predict_classifier(VectorFloat inputVector) - Pipeline Mode Is Not in CLASSIFICATION_MODE!" << std::endl;
1683  return false;
1684  }
1685 
1686  VectorFloat data;
1687  for(UINT moduleIndex=0; moduleIndex<postProcessingModules.size(); moduleIndex++){
1688 
1689  //Select which input we should give the postprocessing module
1690  if( postProcessingModules[moduleIndex]->getIsPostProcessingInputModePredictedClassLabel() ){
1691  //Set the input
1692  data.resize(1);
1693  data[0] = predictedClassLabel;
1694 
1695  //Verify that the input size is OK
1696  if( data.size() != postProcessingModules[moduleIndex]->getNumInputDimensions() ){
1697  errorLog << "predict_classifier(VectorFloat inputVector) - The size of the data Vector (" << int(data.size()) << ") does not match that of the postProcessingModule (" << postProcessingModules[moduleIndex]->getNumInputDimensions() << ") at the moduleIndex: " << moduleIndex << std::endl;
1698  return false;
1699  }
1700 
1701  //Postprocess the data
1702  if( !postProcessingModules[moduleIndex]->process( data ) ){
1703  errorLog << "predict_classifier(VectorFloat inputVector) - Failed to post process data. PostProcessing moduleIndex: " << moduleIndex << std::endl;
1704  return false;
1705  }
1706 
1707  //Select which output we should update
1708  data = postProcessingModules[moduleIndex]->getProcessedData();
1709  }
1710 
1711  //Select which output we should update
1712  if( postProcessingModules[moduleIndex]->getIsPostProcessingOutputModePredictedClassLabel() ){
1713  //Get the processed predicted class label
1714  data = postProcessingModules[moduleIndex]->getProcessedData();
1715 
1716  //Verify that the output size is OK
1717  if( data.size() != 1 ){
1718  errorLog << "predict_classifier(VectorFloat inputVector) - The size of the processed data Vector (" << int(data.size()) << ") from postProcessingModule at the moduleIndex: " << moduleIndex << " is not equal to 1 even though it is in OutputModePredictedClassLabel!" << std::endl;
1719  return false;
1720  }
1721 
1722  //Update the predicted class label
1723  predictedClassLabel = (UINT)data[0];
1724  }
1725 
1726  }
1727  }
1728 
1729  //Update the context module
1730  predictionModuleIndex = END_OF_PIPELINE;
1731  if( contextModules[ END_OF_PIPELINE ].size() ){
1732  for(UINT moduleIndex=0; moduleIndex<contextModules[ END_OF_PIPELINE ].size(); moduleIndex++){
1733  if( !contextModules[ END_OF_PIPELINE ][moduleIndex]->process( VectorFloat(1,predictedClassLabel) ) ){
1734  errorLog << "predict_classifier(VectorFloat inputVector) - Context Module Failed at END_OF_PIPELINE. ModuleIndex: " << moduleIndex << std::endl;
1735  return false;
1736  }
1737  if( !contextModules[ END_OF_PIPELINE ][moduleIndex]->getOK() ){
1738  predictionModuleIndex = END_OF_PIPELINE;
1739  return false;
1740  }
1741  predictedClassLabel = (UINT)contextModules[ END_OF_PIPELINE ][moduleIndex]->getProcessedData()[0];
1742  }
1743  }
1744 
1745  return true;
1746 }
1747 
1748 bool GestureRecognitionPipeline::predict_regressifier(const VectorFloat &input){
1749 
1750  VectorFloat inputVector = input;
1751 
1752  //Update the context module
1753  predictionModuleIndex = START_OF_PIPELINE;
1754  if( contextModules[ START_OF_PIPELINE ].size() ){
1755  for(UINT moduleIndex=0; moduleIndex<contextModules[ START_OF_PIPELINE ].size(); moduleIndex++){
1756  if( !contextModules[ START_OF_PIPELINE ][moduleIndex]->process( inputVector ) ){
1757  errorLog << "predict_regressifier(VectorFloat inputVector) - Context Module Failed at START_OF_PIPELINE. ModuleIndex: " << moduleIndex << std::endl;
1758  return false;
1759  }
1760  if( !contextModules[ START_OF_PIPELINE ][moduleIndex]->getOK() ){
1761  return true;
1762  }
1763  inputVector = contextModules[ START_OF_PIPELINE ][moduleIndex]->getProcessedData();
1764  }
1765  }
1766 
1767  //Perform any pre-processing
1768  if( getIsPreProcessingSet() ){
1769  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
1770  if( !preProcessingModules[moduleIndex]->process( inputVector ) ){
1771  errorLog << "predict_regressifier(VectorFloat inputVector) - Failed to PreProcess Input Vector. PreProcessingModuleIndex: " << moduleIndex << std::endl;
1772  return false;
1773  }
1774  inputVector = preProcessingModules[moduleIndex]->getProcessedData();
1775  }
1776  }
1777 
1778  //Update the context module
1779  predictionModuleIndex = AFTER_PREPROCESSING;
1780  if( contextModules[ AFTER_PREPROCESSING ].size() ){
1781  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_PREPROCESSING ].size(); moduleIndex++){
1782  if( !contextModules[ AFTER_PREPROCESSING ][moduleIndex]->process( inputVector ) ){
1783  errorLog << "predict_regressifier(VectorFloat inputVector) - Context Module Failed at AFTER_PREPROCESSING. ModuleIndex: " << moduleIndex << std::endl;
1784  return false;
1785  }
1786  if( !contextModules[ AFTER_PREPROCESSING ][moduleIndex]->getOK() ){
1787  predictionModuleIndex = AFTER_PREPROCESSING;
1788  return false;
1789  }
1790  inputVector = contextModules[ AFTER_PREPROCESSING ][moduleIndex]->getProcessedData();
1791  }
1792  }
1793 
1794  //Perform any feature extraction
1795  if( getIsFeatureExtractionSet() ){
1796  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
1797  if( !featureExtractionModules[moduleIndex]->computeFeatures( inputVector ) ){
1798  errorLog << "predict_regressifier(VectorFloat inputVector) - Failed to compute features from data. FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1799  return false;
1800  }
1801  inputVector = featureExtractionModules[moduleIndex]->getFeatureVector();
1802  }
1803  }
1804 
1805  //Update the context module
1806  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1807  if( contextModules[ AFTER_FEATURE_EXTRACTION ].size() ){
1808  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_FEATURE_EXTRACTION ].size(); moduleIndex++){
1809  if( !contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->process( inputVector ) ){
1810  errorLog << "predict_regressifier(VectorFloat inputVector) - Context Module Failed at AFTER_FEATURE_EXTRACTION. ModuleIndex: " << moduleIndex << std::endl;
1811  return false;
1812  }
1813  if( !contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->getOK() ){
1814  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1815  return false;
1816  }
1817  inputVector = contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->getProcessedData();
1818  }
1819  }
1820 
1821  //Perform the regression
1822  if( !regressifier->predict(inputVector) ){
1823  errorLog << "predict_regressifier(VectorFloat inputVector) - Prediction Failed! " << regressifier->getLastErrorMessage() << std::endl;
1824  return false;
1825  }
1826  regressionData = regressifier->getRegressionData();
1827 
1828  //Update the context module
1829  if( contextModules[ AFTER_CLASSIFIER ].size() ){
1830  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_CLASSIFIER ].size(); moduleIndex++){
1831  if( !contextModules[ AFTER_CLASSIFIER ][moduleIndex]->process( regressionData ) ){
1832  errorLog << "predict_regressifier(VectorFloat inputVector) - Context Module Failed at AFTER_CLASSIFIER. ModuleIndex: " << moduleIndex << std::endl;
1833  return false;
1834  }
1835  if( !contextModules[ AFTER_CLASSIFIER ][moduleIndex]->getOK() ){
1836  predictionModuleIndex = AFTER_CLASSIFIER;
1837  return false;
1838  }
1839  regressionData = contextModules[ AFTER_CLASSIFIER ][moduleIndex]->getProcessedData();
1840  }
1841  }
1842 
1843  //Perform any post processing
1844  predictionModuleIndex = AFTER_CLASSIFIER;
1845  if( getIsPostProcessingSet() ){
1846 
1847  if( pipelineMode != REGRESSION_MODE ){
1848  errorLog << "predict_regressifier(VectorFloat inputVector) - Pipeline Mode Is Not In RegressionMode!" << std::endl;
1849  return false;
1850  }
1851 
1852  for(UINT moduleIndex=0; moduleIndex<postProcessingModules.size(); moduleIndex++){
1853  if( regressionData.size() != postProcessingModules[moduleIndex]->getNumInputDimensions() ){
1854  errorLog << "predict_regressifier(VectorFloat inputVector) - The size of the regression Vector (" << int(regressionData.size()) << ") does not match that of the postProcessingModule (" << postProcessingModules[moduleIndex]->getNumInputDimensions() << ") at the moduleIndex: " << moduleIndex << std::endl;
1855  return false;
1856  }
1857 
1858  if( !postProcessingModules[moduleIndex]->process( regressionData ) ){
1859  errorLog << "predict_regressifier(VectorFloat inputVector) - Failed to post process data. PostProcessing moduleIndex: " << moduleIndex << std::endl;
1860  return false;
1861  }
1862  regressionData = postProcessingModules[moduleIndex]->getProcessedData();
1863  }
1864 
1865  }
1866 
1867  //Update the context module
1868  predictionModuleIndex = END_OF_PIPELINE;
1869  if( contextModules[ END_OF_PIPELINE ].size() ){
1870  for(UINT moduleIndex=0; moduleIndex<contextModules[ END_OF_PIPELINE ].size(); moduleIndex++){
1871  if( !contextModules[ END_OF_PIPELINE ][moduleIndex]->process( inputVector ) ){
1872  errorLog << "predict_regressifier(VectorFloat inputVector) - Context Module Failed at END_OF_PIPELINE. ModuleIndex: " << moduleIndex << std::endl;
1873  return false;
1874  }
1875  if( !contextModules[ END_OF_PIPELINE ][moduleIndex]->getOK() ){
1876  predictionModuleIndex = END_OF_PIPELINE;
1877  return false;
1878  }
1879  regressionData = contextModules[ END_OF_PIPELINE ][moduleIndex]->getProcessedData();
1880  }
1881  }
1882 
1883  return true;
1884 }
1885 
1886 bool GestureRecognitionPipeline::predict_clusterer(const VectorFloat &input){
1887 
1888  VectorFloat inputVector = input;
1889  predictedClusterLabel = 0;
1890 
1891  //Update the context module
1892  predictionModuleIndex = START_OF_PIPELINE;
1893  if( contextModules[ START_OF_PIPELINE ].size() ){
1894  for(UINT moduleIndex=0; moduleIndex<contextModules[ START_OF_PIPELINE ].size(); moduleIndex++){
1895  if( !contextModules[ START_OF_PIPELINE ][moduleIndex]->process( inputVector ) ){
1896  errorLog << "predict_clusterer(VectorFloat inputVector) - Context Module Failed at START_OF_PIPELINE. ModuleIndex: " << moduleIndex << std::endl;
1897  return false;
1898  }
1899  if( !contextModules[ START_OF_PIPELINE ][moduleIndex]->getOK() ){
1900  return true;
1901  }
1902  inputVector = contextModules[ START_OF_PIPELINE ][moduleIndex]->getProcessedData();
1903  }
1904  }
1905 
1906  //Perform any pre-processing
1907  if( getIsPreProcessingSet() ){
1908  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
1909  if( !preProcessingModules[moduleIndex]->process( inputVector ) ){
1910  errorLog << "predict_clusterer(VectorFloat inputVector) - Failed to PreProcess Input Vector. PreProcessingModuleIndex: " << moduleIndex << std::endl;
1911  return false;
1912  }
1913  inputVector = preProcessingModules[moduleIndex]->getProcessedData();
1914  }
1915  }
1916 
1917  //Update the context module
1918  predictionModuleIndex = AFTER_PREPROCESSING;
1919  if( contextModules[ AFTER_PREPROCESSING ].size() ){
1920  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_PREPROCESSING ].size(); moduleIndex++){
1921  if( !contextModules[ AFTER_PREPROCESSING ][moduleIndex]->process( inputVector ) ){
1922  errorLog << "predict_clusterer(VectorFloat inputVector) - Context Module Failed at AFTER_PREPROCESSING. ModuleIndex: " << moduleIndex << std::endl;
1923  return false;
1924  }
1925  if( !contextModules[ AFTER_PREPROCESSING ][moduleIndex]->getOK() ){
1926  predictionModuleIndex = AFTER_PREPROCESSING;
1927  return false;
1928  }
1929  inputVector = contextModules[ AFTER_PREPROCESSING ][moduleIndex]->getProcessedData();
1930  }
1931  }
1932 
1933  //Perform any feature extraction
1934  if( getIsFeatureExtractionSet() ){
1935  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
1936  if( !featureExtractionModules[moduleIndex]->computeFeatures( inputVector ) ){
1937  errorLog << "predict_clusterer(VectorFloat inputVector) - Failed to compute features from data. FeatureExtractionModuleIndex: " << moduleIndex << std::endl;
1938  return false;
1939  }
1940  inputVector = featureExtractionModules[moduleIndex]->getFeatureVector();
1941  }
1942  }
1943 
1944  //Update the context module
1945  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1946  if( contextModules[ AFTER_FEATURE_EXTRACTION ].size() ){
1947  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_FEATURE_EXTRACTION ].size(); moduleIndex++){
1948  if( !contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->process( inputVector ) ){
1949  errorLog << "predict_clusterer(VectorFloat inputVector) - Context Module Failed at AFTER_FEATURE_EXTRACTION. ModuleIndex: " << moduleIndex << std::endl;
1950  return false;
1951  }
1952  if( !contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->getOK() ){
1953  predictionModuleIndex = AFTER_FEATURE_EXTRACTION;
1954  return false;
1955  }
1956  inputVector = contextModules[ AFTER_FEATURE_EXTRACTION ][moduleIndex]->getProcessedData();
1957  }
1958  }
1959 
1960  //Perform the classification
1961  if( !clusterer->predict(inputVector) ){
1962  errorLog << "predict_clusterer(VectorFloat inputVector) - Prediction Failed! " << clusterer->getLastErrorMessage() << std::endl;
1963  return false;
1964  }
1965  predictedClusterLabel = clusterer->getPredictedClusterLabel();
1966 
1967  //Update the context module
1968  if( contextModules[ AFTER_CLASSIFIER ].size() ){
1969  for(UINT moduleIndex=0; moduleIndex<contextModules[ AFTER_CLASSIFIER ].size(); moduleIndex++){
1970  if( !contextModules[ AFTER_CLASSIFIER ][moduleIndex]->process( VectorFloat(1,predictedClusterLabel) ) ){
1971  errorLog << "predict_clusterer(VectorFloat inputVector) - Context Module Failed at AFTER_CLASSIFIER. ModuleIndex: " << moduleIndex << std::endl;
1972  return false;
1973  }
1974  if( !contextModules[ AFTER_CLASSIFIER ][moduleIndex]->getOK() ){
1975  predictionModuleIndex = AFTER_CLASSIFIER;
1976  return false;
1977  }
1978  predictedClusterLabel = (UINT)contextModules[ AFTER_CLASSIFIER ][moduleIndex]->getProcessedData()[0];
1979  }
1980  }
1981 
1982  //Perform any post processing
1983  predictionModuleIndex = AFTER_CLASSIFIER;
1984  if( getIsPostProcessingSet() ){
1985 
1986  if( pipelineMode != CLASSIFICATION_MODE){
1987  errorLog << "predict_clusterer(VectorFloat inputVector) - Pipeline Mode Is Not in CLASSIFICATION_MODE!" << std::endl;
1988  return false;
1989  }
1990 
1991  VectorFloat data;
1992  for(UINT moduleIndex=0; moduleIndex<postProcessingModules.size(); moduleIndex++){
1993 
1994  //Select which input we should give the postprocessing module
1995  if( postProcessingModules[moduleIndex]->getIsPostProcessingInputModePredictedClassLabel() ){
1996  //Set the input
1997  data.resize(1);
1998  data[0] = predictedClusterLabel;
1999 
2000  //Verify that the input size is OK
2001  if( data.size() != postProcessingModules[moduleIndex]->getNumInputDimensions() ){
2002  errorLog << "predict_clusterer(VectorFloat inputVector) - The size of the data Vector (" << int(data.size()) << ") does not match that of the postProcessingModule (" << postProcessingModules[moduleIndex]->getNumInputDimensions() << ") at the moduleIndex: " << moduleIndex << std::endl;
2003  return false;
2004  }
2005 
2006  //Postprocess the data
2007  if( !postProcessingModules[moduleIndex]->process( data ) ){
2008  errorLog << "predict_clusterer(VectorFloat inputVector) - Failed to post process data. PostProcessing moduleIndex: " << moduleIndex << std::endl;
2009  return false;
2010  }
2011 
2012  //Select which output we should update
2013  data = postProcessingModules[moduleIndex]->getProcessedData();
2014  }
2015 
2016  //Select which output we should update
2017  if( postProcessingModules[moduleIndex]->getIsPostProcessingOutputModePredictedClassLabel() ){
2018  //Get the processed predicted class label
2019  data = postProcessingModules[moduleIndex]->getProcessedData();
2020 
2021  //Verify that the output size is OK
2022  if( data.size() != 1 ){
2023  errorLog << "predict_clusterer(VectorFloat inputVector) - The size of the processed data Vector (" << int(data.size()) << ") from postProcessingModule at the moduleIndex: " << moduleIndex << " is not equal to 1 even though it is in OutputModePredictedClassLabel!" << std::endl;
2024  return false;
2025  }
2026 
2027  //Update the predicted cluster label
2028  predictedClusterLabel = (UINT)data[0];
2029  }
2030 
2031  }
2032  }
2033 
2034  //Update the context module
2035  predictionModuleIndex = END_OF_PIPELINE;
2036  if( contextModules[ END_OF_PIPELINE ].size() ){
2037  for(UINT moduleIndex=0; moduleIndex<contextModules[ END_OF_PIPELINE ].size(); moduleIndex++){
2038  if( !contextModules[ END_OF_PIPELINE ][moduleIndex]->process( VectorFloat(1,predictedClassLabel) ) ){
2039  errorLog << "predict_clusterer(VectorFloat inputVector) - Context Module Failed at END_OF_PIPELINE. ModuleIndex: " << moduleIndex << std::endl;
2040  return false;
2041  }
2042  if( !contextModules[ END_OF_PIPELINE ][moduleIndex]->getOK() ){
2043  predictionModuleIndex = END_OF_PIPELINE;
2044  return false;
2045  }
2046  predictedClusterLabel = (UINT)contextModules[ END_OF_PIPELINE ][moduleIndex]->getProcessedData()[0];
2047  }
2048  }
2049 
2050  return true;
2051 }
2052 
2054 
2055  //Reset any pre processing
2056  if( getIsPreProcessingSet() ){
2057  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
2058  if( !preProcessingModules[ moduleIndex ]->reset() ){
2059  errorLog << "Failed To Reset PreProcessingModule " << moduleIndex << std::endl;
2060  return false;
2061  }
2062  }
2063  }
2064 
2065  //Reset any feature extraction
2066  if( getIsFeatureExtractionSet() ){
2067  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
2068  if( !featureExtractionModules[ moduleIndex ]->reset() ){
2069  errorLog << "Failed To Reset FeatureExtractionModule " << moduleIndex << std::endl;
2070  return false;
2071  }
2072  }
2073  }
2074 
2075  //Reset the classifier
2076  if( getIsClassifierSet() ){
2077  if( !classifier->reset() ){
2078  errorLog << "Failed To Reset Classifier! " << classifier->getLastErrorMessage() << std::endl;
2079  return false;
2080  }
2081  }
2082 
2083  //Reset the regressiier
2084  if( getIsRegressifierSet() ){
2085  if( !regressifier->reset() ){
2086  errorLog << "Failed To Reset Regressifier! " << regressifier->getLastErrorMessage() << std::endl;
2087  return false;
2088  }
2089  }
2090 
2091  //Reset the clusterer
2092  if( getIsClustererSet() ){
2093  if( !clusterer->reset() ){
2094  errorLog << "Failed To Reset clusterer! " << clusterer->getLastErrorMessage() << std::endl;
2095  return false;
2096  }
2097  }
2098 
2099  //Reset any post processing
2100  if( getIsPostProcessingSet() ){
2101  for(UINT moduleIndex=0; moduleIndex<postProcessingModules.size(); moduleIndex++){
2102  if( !postProcessingModules[ moduleIndex ]->reset() ){
2103  errorLog << "Failed To Reset PostProcessingModule " << moduleIndex << std::endl;
2104  return false;
2105  }
2106  }
2107  }
2108 
2109  return true;
2110 }
2111 
2112 bool GestureRecognitionPipeline::clearAll(){ return clear(); }
2113 
2115 
2116  //Clear the entire pipeline
2117  clearTestResults();
2118  deleteAllPreProcessingModules();
2119  deleteAllFeatureExtractionModules();
2120  deleteClassifier();
2121  deleteRegressifier();
2122  deleteClusterer();
2123  deleteAllPostProcessingModules();
2124  deleteAllContextModules();
2125 
2126  //Reset the pipeline
2127  return init();
2128 }
2129 
2131 
2132  //Clear any preprocessing module
2133  for(UINT i=0; i<getNumPreProcessingModules(); i++){
2134  preProcessingModules[i]->clear();
2135  }
2136 
2137  //Clear any feature extraction module
2138  for(UINT i=0; i<getNumFeatureExtractionModules(); i++){
2139  featureExtractionModules[i]->clear();
2140  }
2141 
2142  //Clear any ML model
2143  switch( pipelineMode ){
2144  case PIPELINE_MODE_NOT_SET:
2145  break;
2146  case CLASSIFICATION_MODE:
2147  if( getIsClassifierSet() ){
2148  classifier->clear();
2149  }
2150  break;
2151  case REGRESSION_MODE:
2152  if( getIsRegressifierSet() ){
2153  regressifier->clear();
2154  }
2155  break;
2156  case CLUSTER_MODE:
2157  if( getIsClustererSet() ){
2158  clusterer->clear();
2159  }
2160  break;
2161  default:
2162  break;
2163  }
2164 
2165  //Clear any post processing modules
2166  for(UINT i=0; i<getNumPostProcessingModules(); i++){
2167  postProcessingModules[i]->clear();
2168  }
2169 
2170  return true;
2171 }
2172 
2173 bool GestureRecognitionPipeline::save(const std::string &filename) const {
2174  return savePipelineToFile( filename );
2175 }
2176 
2177 bool GestureRecognitionPipeline::savePipelineToFile(const std::string &filename) const {
2178 
2179  if( !initialized ){
2180  errorLog << "Failed to write pipeline to file as the pipeline has not been initialized yet!" << std::endl;
2181  return false;
2182  }
2183 
2184  std::fstream file;
2185 
2186  file.open(filename.c_str(), std::iostream::out );
2187 
2188  if( !file.is_open() ){
2189  errorLog << "Failed to open file with filename: " << filename << std::endl;
2190  return false;
2191  }
2192 
2193  //Write the pipeline header info
2194  file << "GRT_PIPELINE_FILE_V3.0\n";
2195  file << "PipelineMode: " << getPipelineModeAsString() << std::endl;
2196  file << "NumPreprocessingModules: " << getNumPreProcessingModules() << std::endl;
2197  file << "NumFeatureExtractionModules: " << getNumFeatureExtractionModules() << std::endl;
2198  file << "NumPostprocessingModules: " << getNumPostProcessingModules() << std::endl;
2199  file << "Trained: " << getTrained() << std::endl;
2200  file << "Info: " << info << std::endl;
2201 
2202  //Write the module datatype names
2203  file << "PreProcessingModuleDatatypes:";
2204  for(UINT i=0; i<getNumPreProcessingModules(); i++){
2205  file << "\t" << preProcessingModules[i]->getPreProcessingType();
2206  }
2207  file << std::endl;
2208 
2209  file << "FeatureExtractionModuleDatatypes:";
2210  for(UINT i=0; i<getNumFeatureExtractionModules(); i++){
2211  file << "\t" << featureExtractionModules[i]->getFeatureExtractionType();
2212  }
2213  file << std::endl;
2214 
2215  switch( pipelineMode ){
2216  case PIPELINE_MODE_NOT_SET:
2217  break;
2218  case CLASSIFICATION_MODE:
2219  if( getIsClassifierSet() ) file << "ClassificationModuleDatatype:\t" << classifier->getClassifierType() << std::endl;
2220  else file << "ClassificationModuleDatatype:\tCLASSIFIER_NOT_SET" << std::endl;
2221  break;
2222  case REGRESSION_MODE:
2223  if( getIsRegressifierSet() ) file << "RegressionModuleDatatype:\t" << regressifier->getRegressifierType() << std::endl;
2224  else file << "RegressionModuleDatatype:\tREGRESSIFIER_NOT_SET" << std::endl;
2225  break;
2226  case CLUSTER_MODE:
2227  if( getIsClustererSet() ) file << "ClusterModuleDatatype:\t" << clusterer->getClustererType() << std::endl;
2228  else file << "ClusterModuleDatatype:\tCLUSTERER_NOT_SET" << std::endl;
2229  break;
2230  default:
2231  break;
2232  }
2233 
2234  file << "PostProcessingModuleDatatypes:";
2235  for(UINT i=0; i<getNumPostProcessingModules(); i++){
2236  file << "\t" << postProcessingModules[i]->getPostProcessingType();
2237  }
2238  file << std::endl;
2239 
2240  //Write the preprocessing module data to the file
2241  for(UINT i=0; i<getNumPreProcessingModules(); i++){
2242  file << "PreProcessingModule_" << Util::intToString(i+1) << std::endl;
2243  if( !preProcessingModules[i]->save( file ) ){
2244  errorLog << "Failed to write preprocessing module " << i << " settings to file!" << std::endl;
2245  file.close();
2246  return false;
2247  }
2248  }
2249 
2250  //Write the feature extraction module data to the file
2251  for(UINT i=0; i<getNumFeatureExtractionModules(); i++){
2252  file << "FeatureExtractionModule_" << Util::intToString(i+1) << std::endl;
2253  if( !featureExtractionModules[i]->save( file ) ){
2254  errorLog << "Failed to write feature extraction module " << i << " settings to file!" << std::endl;
2255  file.close();
2256  return false;
2257  }
2258  }
2259 
2260  switch( pipelineMode ){
2261  case PIPELINE_MODE_NOT_SET:
2262  break;
2263  case CLASSIFICATION_MODE:
2264  if( getIsClassifierSet() ){
2265  if( !classifier->save( file ) ){
2266  errorLog << "Failed to write classifier model to file!" << std::endl;
2267  file.close();
2268  return false;
2269  }
2270  }
2271  break;
2272  case REGRESSION_MODE:
2273  if( getIsRegressifierSet() ){
2274  if( !regressifier->save( file ) ){
2275  errorLog << "Failed to write regressifier model to file!" << std::endl;
2276  file.close();
2277  return false;
2278  }
2279  }
2280  break;
2281  case CLUSTER_MODE:
2282  if( getIsClustererSet() ){
2283  if( !clusterer->save( file ) ){
2284  errorLog << "Failed to write clusterer model to file!" << std::endl;
2285  file.close();
2286  return false;
2287  }
2288  }
2289  break;
2290  default:
2291  break;
2292  }
2293 
2294  //Write the post processing module data to the file
2295  for(UINT i=0; i<getNumPostProcessingModules(); i++){
2296  file << "PostProcessingModule_" << Util::intToString(i+1) << std::endl;
2297  if( !postProcessingModules[i]->save( file ) ){
2298  errorLog <<"Failed to write post processing module " << i << " settings to file!" << std::endl;
2299  file.close();
2300  return false;
2301  }
2302  }
2303 
2304  //Close the file
2305  file.close();
2306 
2307  return true;
2308 }
2309 
2310 bool GestureRecognitionPipeline::load(const std::string &filename){
2311  return loadPipelineFromFile( filename );
2312 }
2313 
2314 bool GestureRecognitionPipeline::loadPipelineFromFile(const std::string &filename){
2315 
2316  std::fstream file;
2317 
2318  //Clear any previous setup
2319  clear();
2320 
2321  file.open(filename.c_str(), std::iostream::in );
2322 
2323  if( !file.is_open() ){
2324  errorLog << "loadPipelineFromFile(string filename) - Failed to open file with filename: " << filename << std::endl;
2325  return false;
2326  }
2327 
2328  std::string word;
2329 
2330  //Load the file header
2331  file >> word;
2332  if( word != "GRT_PIPELINE_FILE_V3.0" ){
2333  errorLog << "loadPipelineFromFile(string filename) - Failed to read file header" << std::endl;
2334  file.close();
2335  return false;
2336  }
2337 
2338  //Load the pipeline mode
2339  file >> word;
2340  if( word != "PipelineMode:" ){
2341  errorLog << "loadPipelineFromFile(string filename) - Failed to read PipelineMode" << std::endl;
2342  file.close();
2343  return false;
2344  }
2345  file >> word;
2346  pipelineMode = getPipelineModeFromString(word);
2347 
2348  //Load the NumPreprocessingModules
2349  file >> word;
2350  if( word != "NumPreprocessingModules:" ){
2351  errorLog << "loadPipelineFromFile(string filename) - Failed to read NumPreprocessingModules header" << std::endl;
2352  file.close();
2353  return false;
2354  }
2355  unsigned int numPreprocessingModules;
2356  file >> numPreprocessingModules;
2357 
2358  //Load the NumFeatureExtractionModules
2359  file >> word;
2360  if( word != "NumFeatureExtractionModules:" ){
2361  errorLog << "loadPipelineFromFile(string filename) - Failed to read NumFeatureExtractionModules header" << std::endl;
2362  file.close();
2363  return false;
2364  }
2365  unsigned int numFeatureExtractionModules;
2366  file >> numFeatureExtractionModules;
2367 
2368  //Load the NumPostprocessingModules
2369  file >> word;
2370  if( word != "NumPostprocessingModules:" ){
2371  errorLog << "loadPipelineFromFile(string filename) - Failed to read NumPostprocessingModules header" << std::endl;
2372  file.close();
2373  return false;
2374  }
2375  unsigned int numPostprocessingModules;
2376  file >> numPostprocessingModules;
2377 
2378  //Load if the pipeline has been trained
2379  file >> word;
2380  if( word != "Trained:" ){
2381  errorLog << "loadPipelineFromFile(string filename) - Failed to read Trained header" << std::endl;
2382  file.close();
2383  return false;
2384  }
2385  file >> trained;
2386 
2387  //Load the info
2388  file >> word;
2389  if( word != "Info:" ){
2390  errorLog << "loadPipelineFromFile(string filename) - Failed to read Info header" << std::endl;
2391  file.close();
2392  return false;
2393  }
2394  info = "";
2395  //Read the info text
2396  file >> word;
2397  while( word != "PreProcessingModuleDatatypes:" ){
2398  info += word;
2399  file >> word;
2400  }
2401 
2402  //Resize the modules
2403  if( numPreprocessingModules > 0 ) preProcessingModules.resize(numPreprocessingModules,NULL);
2404  if( numFeatureExtractionModules > 0 ) featureExtractionModules.resize(numFeatureExtractionModules,NULL);
2405  if( numPostprocessingModules > 0 ) postProcessingModules.resize(numPostprocessingModules,NULL);
2406 
2407  //Load the preprocessing module datatypes and initialize the modules
2408  if( word != "PreProcessingModuleDatatypes:" ){
2409  errorLog << "loadPipelineFromFile(string filename) - Failed to read PreProcessingModuleDatatypes" << std::endl;
2410  file.close();
2411  return false;
2412  }
2413  for(UINT i=0; i<numPreprocessingModules; i++){
2414  file >> word;
2415  preProcessingModules[i] = PreProcessing::createInstanceFromString( word );
2416  if( preProcessingModules[i] == NULL ){
2417  errorLog << "loadPipelineFromFile(string filename) - Failed to create preprocessing instance from string: " << word << std::endl;
2418  file.close();
2419  return false;
2420  }
2421  }
2422 
2423  //Load the feature extraction module datatypes and initialize the modules
2424  file >> word;
2425  if( word != "FeatureExtractionModuleDatatypes:" ){
2426  errorLog << "loadPipelineFromFile(string filename) - Failed to read FeatureExtractionModuleDatatypes" << std::endl;
2427  file.close();
2428  return false;
2429  }
2430  for(UINT i=0; i<numFeatureExtractionModules; i++){
2431  file >> word;
2432  featureExtractionModules[i] = FeatureExtraction::createInstanceFromString( word );
2433  if( featureExtractionModules[i] == NULL ){
2434  errorLog << "loadPipelineFromFile(string filename) - Failed to create feature extraction instance from string: " << word << std::endl;
2435  file.close();
2436  return false;
2437  }
2438  }
2439 
2440  switch( pipelineMode ){
2441  case PIPELINE_MODE_NOT_SET:
2442  break;
2443  case CLASSIFICATION_MODE:
2444  file >> word;
2445  if( word != "ClassificationModuleDatatype:" ){
2446  errorLog << "loadPipelineFromFile(string filename) - Failed to read ClassificationModuleDatatype" << std::endl;
2447  file.close();
2448  return false;
2449  }
2450  //Load the classifier type
2451  file >> word;
2452 
2453  //Initialize the classifier
2454  classifier = Classifier::createInstanceFromString( word );
2455  if( classifier == NULL ){
2456  errorLog << "loadPipelineFromFile(string filename) - Failed to create classifier instance from string: " << word << std::endl;
2457  file.close();
2458  return false;
2459  }
2460  break;
2461  case REGRESSION_MODE:
2462  file >> word;
2463  if( word != "RegressionModuleDatatype:" ){
2464  errorLog << "loadPipelineFromFile(string filename) - Failed to read RegressionModuleDatatype" << std::endl;
2465  file.close();
2466  return false;
2467  }
2468  //Load the regressifier type
2469  file >> word;
2470 
2471  //Initialize the regressifier
2472  regressifier = Regressifier::createInstanceFromString( word );
2473  if( regressifier == NULL ){
2474  errorLog << "loadPipelineFromFile(string filename) - Failed to create regressifier instance from string: " << word << std::endl;
2475  file.close();
2476  return false;
2477  }
2478  break;
2479  case CLUSTER_MODE:
2480  file >> word;
2481  if( word != "ClusterModuleDatatype:" ){
2482  errorLog << "loadPipelineFromFile(string filename) - Failed to read ClusterModuleDatatype" << std::endl;
2483  file.close();
2484  return false;
2485  }
2486  //Load the clusterer type
2487  file >> word;
2488 
2489  //Initialize the clusterer
2490  clusterer = Clusterer::createInstanceFromString( word );
2491  if( clusterer == NULL ){
2492  errorLog << "loadPipelineFromFile(string filename) - Failed to create clusterer instance from string: " << word << std::endl;
2493  file.close();
2494  return false;
2495  }
2496  break;
2497  default:
2498  break;
2499  }
2500 
2501  //Load the post processing module datatypes and initialize the modules
2502  file >> word;
2503  if( word != "PostProcessingModuleDatatypes:" ){
2504  errorLog << "loadPipelineFromFile(string filename) - Failed to read PostProcessingModuleDatatypes" << std::endl;
2505  file.close();
2506  return false;
2507  }
2508  for(UINT i=0; i<numPostprocessingModules; i++){
2509  file >> word;
2510  postProcessingModules[i] = PostProcessing::createInstanceFromString( word );
2511  }
2512 
2513  //Load the preprocessing module data from the file
2514  for(UINT i=0; i<numPreprocessingModules; i++){
2515  //Load the preprocessing module header
2516  file >> word;
2517  if( !preProcessingModules[i]->load( file ) ){
2518  errorLog << "Failed to load preprocessing module " << i << " settings from file!" << std::endl;
2519  file.close();
2520  return false;
2521  }
2522  }
2523 
2524  //Load the feature extraction module data from the file
2525  for(UINT i=0; i<numFeatureExtractionModules; i++){
2526  //Load the feature extraction module header
2527  file >> word;
2528  if( !featureExtractionModules[i]->load( file ) ){
2529  errorLog << "Failed to load feature extraction module " << i << " settings from file!" << std::endl;
2530  file.close();
2531  return false;
2532  }
2533  }
2534 
2535  //Load the classifier or regressifer data
2536  switch( pipelineMode ){
2537  case PIPELINE_MODE_NOT_SET:
2538  break;
2539  case CLASSIFICATION_MODE:
2540  if( !classifier->load( file ) ){
2541  errorLog << "Failed to load classifier model from file!" << std::endl;
2542  file.close();
2543  return false;
2544  }
2545  break;
2546  case REGRESSION_MODE:
2547  if( !regressifier->load( file ) ){
2548  errorLog << "Failed to load regressifier model from file!" << std::endl;
2549  file.close();
2550  return false;
2551  }
2552  break;
2553  case CLUSTER_MODE:
2554  if( !clusterer->load( file ) ){
2555  errorLog << "Failed to load cluster model from file!" << std::endl;
2556  file.close();
2557  return false;
2558  }
2559  break;
2560  default:
2561  break;
2562  }
2563 
2564  //Load the post processing module data from the file
2565  for(UINT i=0; i<numPostprocessingModules; i++){
2566  //Load the post processing module header
2567  file >> word;
2568  if( !postProcessingModules[i]->load( file ) ){
2569  errorLog << "Failed to load post processing module " << i << " settings from file!" << std::endl;
2570  file.close();
2571  return false;
2572  }
2573  }
2574 
2575  //Close the file
2576  file.close();
2577 
2578  //Set the expected input Vector size
2579  inputVectorDimensions = 0;
2580 
2581  if( numPreprocessingModules > 0 ){
2582  inputVectorDimensions = preProcessingModules[0]->getNumInputDimensions();
2583  }else{
2584  if( numFeatureExtractionModules > 0 ){
2585  inputVectorDimensions = featureExtractionModules[0]->getNumInputDimensions();
2586  }else{
2587  switch( pipelineMode ){
2588  case PIPELINE_MODE_NOT_SET:
2589  break;
2590  case CLASSIFICATION_MODE:
2591  inputVectorDimensions = classifier->getNumInputDimensions();
2592  break;
2593  case REGRESSION_MODE:
2594  inputVectorDimensions = regressifier->getNumInputDimensions();
2595  break;
2596  case CLUSTER_MODE:
2597  inputVectorDimensions = clusterer->getNumInputDimensions();
2598  break;
2599  default:
2600  break;
2601  }
2602  }
2603  }
2604 
2605  //Flag that the pipeline is now initialized
2606  initialized = true;
2607 
2608  return true;
2609 }
2610 
2611 bool GestureRecognitionPipeline::preProcessData(VectorFloat inputVector,bool computeFeatures){
2612 
2613  if( getIsPreProcessingSet() ){
2614  for(UINT moduleIndex=0; moduleIndex<preProcessingModules.size(); moduleIndex++){
2615 
2616  if( inputVector.size() != preProcessingModules[ moduleIndex ]->getNumInputDimensions() ){
2617  errorLog << "preProcessData(VectorFloat inputVector) - The size of the input Vector (" << preProcessingModules[ moduleIndex ]->getNumInputDimensions() << ") does not match that of the PreProcessing Module at moduleIndex: " << moduleIndex << std::endl;
2618  return false;
2619  }
2620 
2621  if( !preProcessingModules[ moduleIndex ]->process( inputVector ) ){
2622  errorLog << "preProcessData(VectorFloat inputVector) - Failed To PreProcess Input Vector. PreProcessing moduleIndex: " << moduleIndex << std::endl;
2623  return false;
2624  }
2625  inputVector = preProcessingModules[ moduleIndex ]->getProcessedData();
2626  }
2627  }
2628 
2629  //Perform any feature extraction
2630  if( getIsFeatureExtractionSet() && computeFeatures ){
2631  for(UINT moduleIndex=0; moduleIndex<featureExtractionModules.size(); moduleIndex++){
2632  if( inputVector.size() != featureExtractionModules[ moduleIndex ]->getNumInputDimensions() ){
2633  errorLog << "FeatureExtraction(VectorFloat inputVector) - The size of the input Vector (" << featureExtractionModules[ moduleIndex ]->getNumInputDimensions() << ") does not match that of the FeatureExtraction Module at moduleIndex: " << moduleIndex << std::endl;
2634  return false;
2635  }
2636 
2637  if( !featureExtractionModules[ moduleIndex ]->computeFeatures( inputVector ) ){
2638  errorLog << "FeatureExtraction(VectorFloat inputVector) - Failed To Compute Features from Input Vector. FeatureExtraction moduleIndex: " << moduleIndex << std::endl;
2639  return false;
2640  }
2641  inputVector = featureExtractionModules[ moduleIndex ]->getFeatureVector();
2642  }
2643  }
2644 
2645  return true;
2646 }
2647 
2650  return initialized;
2651 }
2652 
2654  return trained;
2655 }
2656 
2658  return preProcessingModules.size() > 0;
2659 }
2660 
2662  return featureExtractionModules.size() > 0;
2663 }
2664 
2666  return (classifier!=NULL);
2667 }
2668 
2670  return (regressifier!=NULL);
2671 }
2672 
2674  return (clusterer!=NULL);
2675 }
2676 
2678  return postProcessingModules.size() > 0;
2679 }
2680 
2682  for(UINT i=0; i<NUM_CONTEXT_LEVELS; i++){
2683  if( contextModules[i].size() > 0 ) return true;
2684  }
2685  return false;
2686 }
2687 
2689  return (pipelineMode!=PIPELINE_MODE_NOT_SET);
2690 }
2691 
2693  return (pipelineMode==CLASSIFICATION_MODE);
2694 }
2695 
2697  return pipelineMode==REGRESSION_MODE;
2698 }
2699 
2701 
2702  if( getIsPreProcessingSet() ){
2703  return preProcessingModules[0]->getNumInputDimensions();
2704  }
2705 
2706  if( getIsFeatureExtractionSet() ){
2707  return featureExtractionModules[0]->getNumInputDimensions();
2708  }
2709 
2711  return classifier->getNumInputFeatures();
2712  }
2714  return regressifier->getNumInputFeatures();
2715  }
2716  return 0;
2717 }
2718 
2720  if( getIsClassifierSet() ) return 1; //The output of the pipeline for classification will always be 1
2721  if( getIsRegressifierSet() ){
2722  return regressifier->getNumOutputDimensions();
2723  }
2724  return 0;
2725 }
2726 
2728  return getNumClasses();
2729 }
2730 
2732  UINT numClasses = 0;
2733  if( getIsClassifierSet() ){
2734  numClasses = classifier->getNumClasses();
2735  }
2736  if( getIsClustererSet() ){
2737  numClasses = clusterer->getNumClusters();
2738  }
2739  return numClasses;
2740 }
2741 
2743  return preProcessingModules.getSize();
2744 }
2745 
2747  return featureExtractionModules.getSize();
2748 }
2749 
2751  return postProcessingModules.getSize();
2752 }
2753 
2755  return predictionModuleIndex;
2756 }
2757 
2759 
2760  if( getIsClassifierSet() ){
2761  return predictedClassLabel;
2762  }
2763  if( getIsClustererSet() ){
2764  return predictedClusterLabel;
2765  }
2766  return 0;
2767 }
2768 
2770  if( getIsClassifierSet() ){
2771  return classifier->getPredictedClassLabel();
2772  }
2773  if( getIsClustererSet() ){
2774  return clusterer->getPredictedClusterLabel();
2775  }
2776  return 0;
2777 }
2778 
2780  return numTrainingSamples;
2781 }
2782 
2784  return numTestSamples;
2785 }
2786 
2788  if( getIsClassifierSet() ){
2789  return classifier->getMaximumLikelihood();
2790  }
2791  if( getIsClustererSet() ){
2792  return clusterer->getMaximumLikelihood();
2793  }
2794  return 0;
2795 }
2796 
2798  if( getIsClassifierSet() ){
2799  return classifier->getPhase();
2800  }
2801  return 0;
2802 }
2803 
2805  return (getIsClassifierSet()||getIsRegressifierSet() ? testAccuracy : 0);
2806 }
2807 
2809  return testAccuracy;
2810 }
2811 
2813  return testRMSError;
2814 }
2815 
2817  return testSquaredError;
2818 }
2819 
2820 Float GestureRecognitionPipeline::getTestFMeasure(const UINT classLabel) const{
2821 
2822  if( !getIsClassifierSet() ) return -1;
2823  if( getClassLabels().size() != testFMeasure.size() ) return -1;
2824 
2825  for(UINT i=0; i<testFMeasure.size(); i++){
2826  if( getClassLabels()[i] == classLabel ){
2827  return testFMeasure[i];
2828  }
2829  }
2830  return -1;
2831 }
2832 
2833 Float GestureRecognitionPipeline::getTestPrecision(const UINT classLabel) const{
2834 
2835  if( !getIsClassifierSet() ) return -1;
2836  if( getClassLabels().size() != testPrecision.size() ) return -1;
2837 
2838  for(UINT i=0; i<testPrecision.size(); i++){
2839  if( getClassLabels()[i] == classLabel ){
2840  return testPrecision[i];
2841  }
2842  }
2843  return -1;
2844 }
2845 
2846 Float GestureRecognitionPipeline::getTestRecall(const UINT classLabel) const{
2847 
2848  if( !getIsClassifierSet() ) return -1;
2849  if( getClassLabels().getSize() != testRecall.getSize() ) return -1;
2850 
2851  for(UINT i=0; i<testRecall.getSize(); i++){
2852  if( getClassLabels()[i] == classLabel ){
2853  return testRecall[i];
2854  }
2855  }
2856  return -1;
2857 }
2858 
2860  return testRejectionPrecision;
2861 }
2862 
2864  return testRejectionRecall;
2865 }
2866 
2868  return testTime;
2869 }
2870 
2872  return trainingTime;
2873 }
2874 
2876  return getIsRegressifierSet() ? regressifier->getRootMeanSquaredTrainingError() : 0;
2877 }
2878 
2880  return getIsRegressifierSet() ? regressifier->getTotalSquaredTrainingError() : 0;
2881 }
2882 
2884  return testConfusionMatrix;
2885 }
2886 
2888  TestResult testResults;
2889  testResults.numTrainingSamples = numTrainingSamples;
2890  testResults.numTestSamples = numTestSamples;
2891  testResults.accuracy = testAccuracy;
2892  testResults.rmsError = testRMSError;
2893  testResults.totalSquaredError = testSquaredError;
2894  testResults.trainingTime = trainingTime;
2895  testResults.testTime = testTime;
2896  testResults.rejectionPrecision = testRejectionPrecision;
2897  testResults.rejectionRecall = testRejectionRecall;
2898  testResults.precision = testPrecision;
2899  testResults.recall = testRecall;
2900  testResults.fMeasure = testFMeasure;
2901  testResults.confusionMatrix = testConfusionMatrix;
2902  return testResults;
2903 }
2904 
2906  return testPrecision;
2907 }
2908 
2910  return testRecall;
2911 }
2912 
2914  return testFMeasure;
2915 }
2916 
2918  if( getIsClassifierSet() ){ return classifier->getClassLikelihoods(); }
2919  if( getIsClustererSet() ){ return clusterer->getClusterLikelihoods(); }
2920  else{ return VectorFloat(); }
2921 }
2922 
2924  if( getIsClassifierSet() ){ return classifier->getClassDistances(); }
2925  if( getIsClustererSet() ){ return clusterer->getClusterDistances(); }
2926  else{ return VectorFloat(); }
2927 }
2928 
2930  if( getIsClassifierSet() ){ return classifier->getNullRejectionThresholds(); }
2931  else{ return VectorFloat(); }
2932 }
2933 
2935  return regressionData;
2936 }
2937 
2939  if( getIsRegressifierSet() ) {
2940  return regressifier->getRegressionData();
2941  }
2942  return VectorFloat();
2943 }
2944 
2946  if( getIsPreProcessingSet() ){
2947  return preProcessingModules[ preProcessingModules.size()-1 ]->getProcessedData();
2948  }
2949  return VectorFloat();
2950 }
2951 
2953  if( getIsPreProcessingSet() ){
2954  if( moduleIndex < preProcessingModules.size() ){
2955  return preProcessingModules[ moduleIndex ]->getProcessedData();
2956  }
2957  }
2958  return VectorFloat();
2959 }
2960 
2962  if( getIsFeatureExtractionSet() ){
2963  return featureExtractionModules[ featureExtractionModules.size()-1 ]->getFeatureVector();
2964  }
2965  return VectorFloat();
2966 }
2967 
2969  if( getIsFeatureExtractionSet() ){
2970  if( moduleIndex < featureExtractionModules.size() ){
2971  return featureExtractionModules[ moduleIndex ]->getFeatureVector();
2972  }
2973  }
2974  warningLog << "getFeatureExtractionData(UINT moduleIndex) - Failed to get class labels!" << std::endl;
2975  return VectorFloat();
2976 }
2977 
2979  if( getIsClassifierSet() ){
2980  return classifier->getClassLabels();
2981  }
2982  if( getIsClustererSet() ){
2983  return clusterer->getClusterLabels();
2984  }
2985  warningLog << "getClassLabels() - Failed to get class labels!" << std::endl;
2986  return Vector< UINT>();
2987 }
2988 
2990  return testResults;
2991 }
2992 
2994  return crossValidationResults;
2995 }
2996 
2998  if( moduleIndex < preProcessingModules.size() ){
2999  return preProcessingModules[ moduleIndex ];
3000  }
3001  warningLog << "getPreProcessingModule(const UINT moduleIndex) - Failed to get pre processing module!" << std::endl;
3002  return NULL;
3003 }
3004 
3006  if( moduleIndex < featureExtractionModules.size() ){
3007  return featureExtractionModules[ moduleIndex ];
3008  }
3009  warningLog << "getFeatureExtractionModule(const UINT moduleIndex) - Failed to get feature extraction module!" << std::endl;
3010  return NULL;
3011 }
3012 
3014  return classifier;
3015 }
3016 
3018  return regressifier;
3019 }
3020 
3022  return clusterer;
3023 }
3024 
3026  if( moduleIndex < postProcessingModules.size() ){
3027  return postProcessingModules[ moduleIndex ];
3028  }
3029  warningLog << "getPostProcessingModule(UINT moduleIndex) - Failed to get post processing module!" << std::endl;
3030  return NULL;
3031 }
3032 
3033 Context* GestureRecognitionPipeline::getContextModule(UINT contextLevel,UINT moduleIndex) const{
3034  if( contextLevel < contextModules.size() ){
3035  if( moduleIndex < contextModules[ contextLevel ].size() ){
3036  return contextModules[ contextLevel ][ moduleIndex ];
3037  }
3038  }
3039  warningLog << "getContextModule(UINT contextLevel,UINT moduleIndex) - Failed to get context module!" << std::endl;
3040  return NULL;
3041 }
3042 
3046 
3047 bool GestureRecognitionPipeline::addPreProcessingModule(const PreProcessing &preProcessingModule,UINT insertIndex){
3048 
3049  //Validate the insertIndex is valid
3050  if( insertIndex != INSERT_AT_END_INDEX && insertIndex >= preProcessingModules.size() ){
3051  errorLog << "addPreProcessingModule(const PreProcessing &preProcessingModule) - Invalid insertIndex value!" << std::endl;
3052  return false;
3053  }
3054 
3055  //Create a new instance of the preProcessing and then clone the values across from the reference preProcessing
3056  PreProcessing *newInstance = preProcessingModule.createNewInstance();
3057 
3058  //Verify that the clone was successful
3059  if( !newInstance->deepCopyFrom( &preProcessingModule ) ){
3060  delete newInstance;
3061  newInstance = NULL;
3062  errorLog << "addPreProcessingModule(const PreProcessing &preProcessingModule) - PreProcessing Module Not Set!" << std::endl;
3063  return false;
3064  }
3065 
3066  //Add the new instance to the preProcessingModules
3067  Vector< PreProcessing* >::iterator iter = preProcessingModules.begin();
3068 
3069  if( insertIndex == INSERT_AT_END_INDEX ) iter = preProcessingModules.end();
3070  else iter = preProcessingModules.begin() + insertIndex;
3071 
3072  preProcessingModules.insert(iter, newInstance);
3073 
3074  //The pipeline has been changed, so flag that the pipeline is no longer trained
3075  trained = false;
3076 
3077  return true;
3078 }
3079 
3082  return addPreProcessingModule( preProcessingModule );
3083 }
3084 
3085 bool GestureRecognitionPipeline::addFeatureExtractionModule(const FeatureExtraction &featureExtractionModule,UINT insertIndex){
3086 
3087  //Validate the insertIndex is valid
3088  if( insertIndex != INSERT_AT_END_INDEX && insertIndex >= featureExtractionModules.size() ){
3089  errorLog << "addFeatureExtractionModule(const FeatureExtraction &featureExtractionModule) - Invalid insertIndex value!" << std::endl;
3090  return false;
3091  }
3092 
3093  //Create a new instance of the preProcessing and then clone the values across from the reference preProcessing
3094  FeatureExtraction *newInstance = featureExtractionModule.createNewInstance();
3095 
3096  //Verify that the clone was successful
3097  if( !newInstance->deepCopyFrom( &featureExtractionModule ) ){
3098  delete newInstance;
3099  newInstance = NULL;
3100  errorLog << "addFeatureExtractionModule(const FeatureExtraction &featureExtractionModule - FeatureExtraction Module Not Set!" << std::endl;
3101  return false;
3102  }
3103 
3104  //Add the new instance to the preProcessingModules
3105  Vector< FeatureExtraction* >::iterator iter = featureExtractionModules.begin();
3106 
3107  if( insertIndex == INSERT_AT_END_INDEX ) iter = featureExtractionModules.end();
3108  else iter = featureExtractionModules.begin() + insertIndex;
3109 
3110  featureExtractionModules.insert(iter, newInstance);
3111 
3112  //The pipeline has been changed, so flag that the pipeline is no longer trained
3113  trained = false;
3114 
3115  return true;
3116 }
3117 
3120  return addFeatureExtractionModule( featureExtractionModule );
3121 }
3122 
3124 
3125  //Delete any previous classifier, regressifier or clusterer
3126  deleteClassifier();
3127  deleteRegressifier();
3128  deleteClusterer();
3129 
3130  //Create a new instance of the classifier and then clone the values across from the reference classifier
3131  this->classifier = classifier.createNewInstance();
3132 
3133  if( this->classifier == NULL ){
3134  errorLog << "setClassifier(const Classifier classifier) - Classifier Module Not Set!" << std::endl;
3135  return false;
3136  }
3137 
3138  //Deep copy the data from the rhs classifier into this classifier
3139  if( !this->classifier->deepCopyFrom( &classifier ) ){
3140  deleteClassifier();
3141  pipelineMode = PIPELINE_MODE_NOT_SET;
3142  errorLog << "setClassifier(const Classifier classifier) - Classifier Module Not Set!" << std::endl;
3143  return false;
3144  }
3145 
3146  //Set the mode of the pipeline to classification mode
3147  pipelineMode = CLASSIFICATION_MODE;
3148 
3149  //Flag that the key part of the pipeline has now been initialized
3150  initialized = true;
3151 
3152  //If there is no preprocessing / feature extraction and the classifier is trained, then flag the pipeline is trained
3153  //Otherwise the user needs to train the pipeline
3154  if( !getIsPreProcessingSet() && !getIsFeatureExtractionSet() && classifier.getTrained() ){
3155  inputVectorDimensions = classifier.getNumInputDimensions();
3156  trained = true;
3157  }else trained = false;
3158 
3159  return true;
3160 }
3161 
3163 
3164  //Delete any previous classifier, regressifier or clusterer
3165  deleteClassifier();
3166  deleteRegressifier();
3167  deleteClusterer();
3168 
3169  //Set the mode of the pipeline to regression mode
3170  pipelineMode = REGRESSION_MODE;
3171 
3172  //Create a new instance of the regressifier and then clone the values across from the reference regressifier
3173  this->regressifier = regressifier.createNewInstance();
3174 
3175  //Validate that the regressifier was cloned correctly
3176  if( !this->regressifier->deepCopyFrom( &regressifier ) ){
3177  deleteRegressifier();
3178  pipelineMode = PIPELINE_MODE_NOT_SET;
3179  errorLog << "setRegressifier(const Regressifier &regressifier) - Regressifier Module Not Set!" << std::endl;
3180  return false;
3181  }
3182 
3183  //Flag that the key part of the pipeline has now been initialized
3184  initialized = true;
3185 
3186  //If there is no preprocessing / feature extraction and the regressifier is trained, then flag the pipeline is trained
3187  //Otherwise the user needs to train the pipeline
3189  trained = regressifier.getTrained();
3190  }else trained = false;
3191 
3192  return true;
3193 }
3194 
3196 
3197  //Delete any previous classifier, regressifier or clusterer
3198  deleteClassifier();
3199  deleteRegressifier();
3200  deleteClusterer();
3201 
3202  //Set the mode of the pipeline to cluster mode
3203  pipelineMode = CLUSTER_MODE;
3204 
3205  //Create a new instance of the clusterer and then clone the values across from the reference clusterer
3206  this->clusterer = clusterer.createNewInstance();
3207 
3208  //Validate that the regressifier was cloned correctly
3209  if( !this->clusterer->deepCopyFrom( &clusterer ) ){
3210  deleteClusterer();
3211  pipelineMode = PIPELINE_MODE_NOT_SET;
3212  errorLog << "setClusterer(const Clusterer &clusterer) - Clusterer Module Not Set!" << std::endl;
3213  return false;
3214  }
3215 
3216  //Flag that the key part of the pipeline has now been initialized
3217  initialized = true;
3218 
3219  //If there is no preprocessing / feature extraction and the regressifier is trained, then flag the pipeline is trained
3220  //Otherwise the user needs to train the pipeline
3222  trained = clusterer.getTrained();
3223  }else trained = false;
3224 
3225  return true;
3226 }
3227 
3228 bool GestureRecognitionPipeline::addPostProcessingModule(const PostProcessing &postProcessingModule,UINT insertIndex){
3229 
3230  //Validate the insertIndex is valid
3231  if( insertIndex != INSERT_AT_END_INDEX && insertIndex >= postProcessingModules.size() ){
3232  errorLog << "addPostProcessingModule((const PostProcessing &postProcessingModule) - Invalid insertIndex value!" << std::endl;
3233  return false;
3234  }
3235 
3236  //Create a new instance of the preProcessing and then clone the values across from the reference preProcessing
3237  PostProcessing *newInstance = postProcessingModule.createNewInstance();
3238 
3239  //Verify that the clone was successful
3240  if( !newInstance->deepCopyFrom( &postProcessingModule ) ){
3241  delete newInstance;
3242  newInstance = NULL;
3243  errorLog << "addPostProcessingModule(const PostProcessing &postProcessingModule) - PostProcessing Module Not Set!" << std::endl;
3244  return false;
3245  }
3246 
3247  //Add the new instance to the postProcessingModules
3248  Vector< PostProcessing* >::iterator iter = postProcessingModules.begin();
3249 
3250  if( insertIndex == INSERT_AT_END_INDEX ) iter = postProcessingModules.end();
3251  else iter = postProcessingModules.begin() + insertIndex;
3252 
3253  postProcessingModules.insert(iter, newInstance);
3254 
3255  //Note, we don't change the trained state of the pipeline for post processing modules, as they are added after the core ML module
3256 
3257  return true;
3258 }
3259 
3262  return addPostProcessingModule( postProcessingModule );
3263 }
3264 
3265 bool GestureRecognitionPipeline::addContextModule(const Context &contextModule,UINT contextLevel,UINT insertIndex){
3266 
3267  //Validate the contextLevel is valid
3268  if( contextLevel >= contextModules.size() ){
3269  errorLog << "addContextModule(...) - Invalid contextLevel value!" << std::endl;
3270  return false;
3271  }
3272 
3273  //Validate the insertIndex is valid
3274  if( insertIndex != INSERT_AT_END_INDEX && insertIndex >= contextModules[contextLevel].size() ){
3275  errorLog << "addContextModule(...) - Invalid insertIndex value!" << std::endl;
3276  return false;
3277  }
3278 
3279  //Create a new instance of the preProcessing and then clone the values across from the reference preProcessing
3280  Context *newInstance = contextModule.createNewInstance();
3281 
3282  //Verify that the clone was successful
3283  if( !newInstance->deepCopyFrom( &contextModule ) ){
3284  delete newInstance;
3285  newInstance = NULL;
3286  errorLog << "addContextModule(...) - Context Module Not Set!" << std::endl;
3287  return false;
3288  }
3289 
3290  //Add the new instance to the contextModules
3291  Vector< Context* >::iterator iter = contextModules[ contextLevel ].begin();
3292 
3293  if( insertIndex == INSERT_AT_END_INDEX ) iter = contextModules[ contextLevel ].end();
3294  else iter = contextModules[ contextLevel ].begin() + insertIndex;
3295 
3296  contextModules[ contextLevel ].insert(iter, newInstance);
3297 
3298  return true;
3299 }
3300 
3301 bool GestureRecognitionPipeline::updateContextModule(bool value,UINT contextLevel,UINT moduleIndex){
3302 
3303  //Validate the contextLevel is valid
3304  if( contextLevel >= contextModules.size() ){
3305  errorLog << "updateContextModule(...) - Context Level is out of bounds!" << std::endl;
3306  return false;
3307  }
3308 
3309  //Validate the moduleIndex is valid
3310  if( moduleIndex >= contextModules[contextLevel].size() ){
3311  errorLog << "updateContextModule(...) - Invalid contextLevel value!" << std::endl;
3312  return false;
3313  }
3314 
3315  return contextModules[contextLevel][moduleIndex]->updateContext( value );
3316 }
3317 
3319  deleteAllPreProcessingModules();
3320  return true;
3321 }
3322 
3324  if( moduleIndex >= preProcessingModules.size() ){
3325  errorLog << "removePreProcessingModule(UINT moduleIndex) - Invalid moduleIndex " << moduleIndex << ". The size of the preProcessingModules Vector is " << int(preProcessingModules.size()) << std::endl;
3326  return false;
3327  }
3328 
3329  //Delete the module
3330  delete preProcessingModules[ moduleIndex ];
3331  preProcessingModules[ moduleIndex ] = NULL;
3332  preProcessingModules.erase( preProcessingModules.begin() + moduleIndex );
3333 
3334  //The pipeline has been changed, so flag that the pipeline is no longer trained
3335  trained = false;
3336 
3337  return true;
3338 }
3339 
3341  deleteAllFeatureExtractionModules();
3342  return true;
3343 }
3344 
3346  if( moduleIndex >= featureExtractionModules.size() ){
3347  errorLog << "removeFeatureExtractionModule(UINT moduleIndex) - Invalid moduleIndex " << moduleIndex << ". The size of the featureExtractionModules Vector is " << int(featureExtractionModules.size()) << std::endl;
3348  return false;
3349  }
3350 
3351  //Delete the module
3352  delete featureExtractionModules[ moduleIndex ];
3353  featureExtractionModules[ moduleIndex ] = NULL;
3354  featureExtractionModules.erase( featureExtractionModules.begin() + moduleIndex );
3355 
3356  //The pipeline has been changed, so flag that the pipeline is no longer trained
3357  trained = false;
3358 
3359  return true;
3360 }
3361 
3363  deleteAllPostProcessingModules();
3364  return true;
3365 }
3366 
3368  if( moduleIndex >= postProcessingModules.size() ){
3369  errorLog << "removePostProcessingModule(UINT moduleIndex) - Invalid moduleIndex " << moduleIndex << ". The size of the postProcessingModules Vector is " << int(postProcessingModules.size()) << std::endl;
3370  return false;
3371  }
3372 
3373  //Delete the module
3374  delete postProcessingModules[ moduleIndex ];
3375  postProcessingModules[ moduleIndex ] = NULL;
3376  postProcessingModules.erase( postProcessingModules.begin() + moduleIndex );
3377 
3378  //The pipeline has been changed, so flag that the pipeline is no longer trained
3379  trained = false;
3380 
3381  return true;
3382 }
3383 
3384 bool GestureRecognitionPipeline::removeContextModule(UINT contextLevel,UINT moduleIndex){
3385  if( contextLevel >= NUM_CONTEXT_LEVELS ){
3386  errorLog << "removeContextModule(UINT contextLevel,UINT moduleIndex) - Invalid moduleIndex " << moduleIndex << " is out of bounds!" << std::endl;
3387  return false;
3388  }
3389 
3390  if( moduleIndex >= contextModules[contextLevel].size() ){
3391  errorLog << "removePostProcessingModule(UINT moduleIndex) - Invalid moduleIndex " << moduleIndex << ". The size of the contextModules Vector at context level " << " is " << int(contextModules[contextLevel].size()) << std::endl;
3392  return false;
3393  }
3394 
3395  //Delete the module
3396  delete contextModules[contextLevel][moduleIndex];
3397  contextModules[contextLevel][moduleIndex] = NULL;
3398  contextModules[contextLevel].erase( contextModules[contextLevel].begin() + moduleIndex );
3399  return true;
3400 }
3401 
3403  deleteAllContextModules();
3404  return true;
3405 }
3406 
3408 
3409  numTestSamples = 0;
3410  testAccuracy = 0;
3411  testRMSError = 0;
3412  testSquaredError = 0;
3413  testTime = 0;
3414  testFMeasure.clear();
3415  testPrecision.clear();
3416  testRecall.clear();
3417  testRejectionPrecision = 0;
3418  testRejectionRecall = 0;
3419  testConfusionMatrix.clear();
3420  testResults.clear();
3421  crossValidationResults.clear();
3422 
3423  return true;
3424 }
3425 
3426 bool GestureRecognitionPipeline::setInfo(const std::string &info){
3427  this->info = info;
3428  return true;
3429 }
3430 
3434 
3435 void GestureRecognitionPipeline::deleteAllPreProcessingModules(){
3436  if( preProcessingModules.size() != 0 ){
3437  for(UINT i=0; i<preProcessingModules.size(); i++){
3438  delete preProcessingModules[i];
3439  preProcessingModules[i] = NULL;
3440  }
3441  preProcessingModules.clear();
3442  trained = false;
3443  }
3444 }
3445 
3446 void GestureRecognitionPipeline::deleteAllFeatureExtractionModules(){
3447  if( featureExtractionModules.size() != 0 ){
3448  for(UINT i=0; i<featureExtractionModules.size(); i++){
3449  delete featureExtractionModules[i];
3450  featureExtractionModules[i] = NULL;
3451  }
3452  featureExtractionModules.clear();
3453  trained = false;
3454  }
3455 }
3456 
3457 void GestureRecognitionPipeline::deleteClassifier(){
3458  if( classifier != NULL ){
3459  delete classifier;
3460  classifier = NULL;
3461  }
3462  trained = false;
3463  initialized = false;
3464 }
3465 
3466 void GestureRecognitionPipeline::deleteRegressifier(){
3467  if( regressifier != NULL ){
3468  delete regressifier;
3469  regressifier = NULL;
3470  }
3471  trained = false;
3472  initialized = false;
3473 }
3474 
3475 void GestureRecognitionPipeline::deleteClusterer(){
3476  if( clusterer != NULL ){
3477  delete clusterer;
3478  clusterer = NULL;
3479  }
3480  trained = false;
3481  initialized = false;
3482 }
3483 
3484 void GestureRecognitionPipeline::deleteAllPostProcessingModules(){
3485  if( postProcessingModules.size() != 0 ){
3486  for(UINT i=0; i<postProcessingModules.size(); i++){
3487  delete postProcessingModules[i];
3488  postProcessingModules[i] = NULL;
3489  }
3490  postProcessingModules.clear();
3491  trained = false;
3492  }
3493 }
3494 
3495 void GestureRecognitionPipeline::deleteAllContextModules(){
3496  for(UINT i=0; i<contextModules.size(); i++){
3497  for(UINT j=0; j<contextModules[i].size(); j++){
3498  delete contextModules[i][j];
3499  contextModules[i][j] = NULL;
3500  }
3501  contextModules[i].clear();
3502  }
3503 }
3504 
3505 bool GestureRecognitionPipeline::init(){
3506  initialized = false;
3507  trained = false;
3508  info = "";
3509  pipelineMode = PIPELINE_MODE_NOT_SET;
3510  inputVectorDimensions = 0;
3511  outputVectorDimensions = 0;
3512  predictedClassLabel = 0;
3513  predictedClusterLabel = 0;
3514  predictionModuleIndex = 0;
3515  numTrainingSamples = 0;
3516  numTestSamples = 0;
3517  testAccuracy = 0;
3518  testRMSError = 0;
3519  testSquaredError = 0;
3520  testRejectionPrecision = 0;
3521  testRejectionRecall = 0;
3522  testTime = 0;
3523  trainingTime = 0;
3524  classifier = NULL;
3525  regressifier = NULL;
3526  clusterer = NULL;
3527  contextModules.resize( NUM_CONTEXT_LEVELS );
3528  return true;
3529 }
3530 
3531 bool GestureRecognitionPipeline::updateTestMetrics(const UINT classLabel,const UINT predictedClassLabel,VectorFloat &precisionCounter,VectorFloat &recallCounter,Float &rejectionPrecisionCounter,Float &rejectionRecallCounter,VectorFloat &confusionMatrixCounter){
3532 
3533  const bool nullRejectionEnabled = classifier->getNullRejectionEnabled();
3534 
3535  //Find the index of the classLabel
3536  UINT predictedClassLabelIndex =0;
3537  bool predictedClassLabelIndexFound = false;
3538  for(UINT k=0; k<getNumClassesInModel(); k++){
3539  if( predictedClassLabel == classifier->getClassLabels()[k] ){
3540  predictedClassLabelIndex = k;
3541  predictedClassLabelIndexFound = true;
3542  break;
3543  }
3544  }
3545 
3546  if( !predictedClassLabelIndexFound && (nullRejectionEnabled == false || predictedClassLabel != GRT_DEFAULT_NULL_CLASS_LABEL) ){
3547  errorLog << "Failed to find class label index for label: " << predictedClassLabel << std::endl;
3548  return false;
3549  }
3550 
3551  //Find the index of the class label
3552  UINT actualClassLabelIndex = 0;
3553  for(UINT k=0; k<getNumClassesInModel(); k++){
3554  if( classLabel == classifier->getClassLabels()[k] ){
3555  actualClassLabelIndex = k;
3556  break;
3557  }
3558  }
3559 
3560  //Update the classification accuracy
3561  if( classLabel == predictedClassLabel ){
3562  testAccuracy++;
3563  }
3564 
3565  if( nullRejectionEnabled == false ){
3566 
3567  //Update the precision
3568  if( classLabel == predictedClassLabel ){
3569  //Update the precision value
3570  testPrecision[ predictedClassLabelIndex ]++;
3571  }
3572  //Update the precision counter
3573  precisionCounter[ predictedClassLabelIndex ]++;
3574 
3575  //Update the recall
3576  if( classLabel == predictedClassLabel ){
3577  //Update the recall value
3578  testRecall[ predictedClassLabelIndex ]++;
3579  }
3580  //Update the recall counter
3581  recallCounter[ actualClassLabelIndex ]++;
3582 
3583  //Update the confusion matrix
3584  testConfusionMatrix[ actualClassLabelIndex ][ predictedClassLabelIndex ]++;
3585  confusionMatrixCounter[ actualClassLabelIndex ]++;
3586 
3587  }else{ //Null rejection is enabled
3588  //Update the precision
3589  if( predictedClassLabel != GRT_DEFAULT_NULL_CLASS_LABEL ){
3590  if( classLabel == predictedClassLabel ){
3591  //Update the precision value
3592  testPrecision[ predictedClassLabelIndex ]++;
3593  }
3594  //Update the precision counter
3595  precisionCounter[ predictedClassLabelIndex ]++;
3596  }
3597 
3598  //Update the recall
3599  if( classLabel != GRT_DEFAULT_NULL_CLASS_LABEL ){
3600  if( classLabel == predictedClassLabel ){
3601  //Update the recall value
3602  testRecall[ predictedClassLabelIndex ]++;
3603  }
3604  //Update the recall counter
3605  recallCounter[ actualClassLabelIndex ]++;
3606  }
3607 
3608  //Update the rejection precision
3609  if( predictedClassLabel == GRT_DEFAULT_NULL_CLASS_LABEL ){
3610  if( classLabel == GRT_DEFAULT_NULL_CLASS_LABEL ) testRejectionPrecision++;
3611  rejectionPrecisionCounter++;
3612  }
3613 
3614  //Update the rejection recall
3615  if( classLabel == GRT_DEFAULT_NULL_CLASS_LABEL ){
3616  if( predictedClassLabel == GRT_DEFAULT_NULL_CLASS_LABEL ) testRejectionRecall++;
3617  rejectionRecallCounter++;
3618  }
3619 
3620  //Update the confusion matrix
3621  if( classLabel == GRT_DEFAULT_NULL_CLASS_LABEL ) actualClassLabelIndex = 0;
3622  else actualClassLabelIndex++;
3623  if( predictedClassLabel == GRT_DEFAULT_NULL_CLASS_LABEL ) predictedClassLabelIndex = 0;
3624  else predictedClassLabelIndex++;
3625  testConfusionMatrix[ actualClassLabelIndex ][ predictedClassLabelIndex ]++;
3626  confusionMatrixCounter[ actualClassLabelIndex ]++;
3627  }
3628 
3629  return true;
3630 }
3631 
3632 bool GestureRecognitionPipeline::computeTestMetrics(VectorFloat &precisionCounter,VectorFloat &recallCounter,Float &rejectionPrecisionCounter,Float &rejectionRecallCounter,VectorFloat &confusionMatrixCounter,const UINT numTestSamples){
3633 
3634  //Compute the test metrics
3635  testAccuracy = testAccuracy/Float(numTestSamples) * 100.0;
3636 
3637  for(UINT k=0; k<getNumClassesInModel(); k++){
3638  if( precisionCounter[k] > 0 ) testPrecision[k] /= precisionCounter[k];
3639  else testPrecision[k] = 0;
3640  if( recallCounter[k] > 0 ) testRecall[k] /= recallCounter[k];
3641  else testRecall[k] = 0;
3642 
3643  if( precisionCounter[k] + recallCounter[k] > 0 )
3644  testFMeasure[k] = 2 * ((testPrecision[k]*testRecall[k])/(testPrecision[k]+testRecall[k]));
3645  else testFMeasure[k] = 0;
3646  }
3647  if( rejectionPrecisionCounter > 0 ) testRejectionPrecision /= rejectionPrecisionCounter;
3648  if( rejectionRecallCounter > 0 ) testRejectionRecall /= rejectionRecallCounter;
3649 
3650 
3651  for(UINT r=0; r<confusionMatrixCounter.size(); r++){
3652  if( confusionMatrixCounter[r] > 0 ){
3653  for(UINT c=0; c<testConfusionMatrix.getNumCols(); c++){
3654  testConfusionMatrix[r][c] /= confusionMatrixCounter[r];
3655  }
3656  }
3657  }
3658 
3659  return true;
3660 }
3661 
3663  std::string model = "";
3664 
3665  switch( pipelineMode ){
3666  case PIPELINE_MODE_NOT_SET:
3667  break;
3668  case CLASSIFICATION_MODE:
3669  if( getIsClassifierSet() ){
3670  model += "Classifier: " + classifier->getClassifierType() + "\n";
3671  model += classifier->getModelAsString();
3672  }
3673  break;
3674  case REGRESSION_MODE:
3675  if( getIsRegressifierSet() ){
3676  model += "Regressifier: " + regressifier->getRegressifierType() + "\n";
3677  model += regressifier->getModelAsString();
3678  }
3679  break;
3680  default:
3681  break;
3682  }
3683 
3684  return model;
3685 }
3686 
3688  switch( pipelineMode ){
3689  case PIPELINE_MODE_NOT_SET:
3690  return "PIPELINE_MODE_NOT_SET";
3691  break;
3692  case CLASSIFICATION_MODE:
3693  return "CLASSIFICATION_MODE";
3694  break;
3695  case REGRESSION_MODE:
3696  return "REGRESSION_MODE";
3697  break;
3698  default:
3699  return "ERROR_UNKNWON_PIPELINE_MODE";
3700  break;
3701  }
3702 
3703  return "ERROR_UNKNWON_PIPELINE_MODE";
3704 }
3705 
3706 std::string GestureRecognitionPipeline::getInfo() const{
3707  return info;
3708 }
3709 
3710 UINT GestureRecognitionPipeline::getPipelineModeFromString(std::string pipelineModeAsString) const{
3711  if( pipelineModeAsString == "PIPELINE_MODE_NOT_SET" ){
3712  return PIPELINE_MODE_NOT_SET;
3713  }
3714  if( pipelineModeAsString == "CLASSIFICATION_MODE" ){
3715  return CLASSIFICATION_MODE;
3716  }
3717  if( pipelineModeAsString == "REGRESSION_MODE" ){
3718  return REGRESSION_MODE;
3719  }
3720  return PIPELINE_MODE_NOT_SET;
3721 }
3722 
3723 GRT_END_NAMESPACE
3724 
bool removePostProcessingModule(const UINT moduleIndex)
void clear()
Definition: Matrix.h:522
bool spiltDataIntoKFolds(const UINT K, const bool useStratifiedSampling=false)
virtual bool predict(VectorFloat inputVector)
Definition: MLBase.cpp:113
GestureRecognitionPipeline & operator<<(const PreProcessing &module)
static std::string toString(const int &i)
Definition: Util.cpp:74
virtual bool deepCopyFrom(const PostProcessing *postProcessing)
Definition: Timer.h:43
bool addSample(const VectorFloat &sample)
bool train(const ClassificationData &trainingData)
virtual bool deepCopyFrom(const PreProcessing *rhs)
Definition: PreProcessing.h:57
virtual bool predict_(VectorFloat &inputVector)
Definition: MLBase.cpp:115
bool addSample(UINT classLabel, const VectorFloat &sample)
Vector< UINT > getClassLabels() const
Definition: Classifier.cpp:223
ClassificationData getTestFoldData(const UINT foldIndex) const
VectorFloat getNullRejectionThresholds() const
Definition: Classifier.cpp:218
bool removeContextModule(const UINT contextLevel, const UINT moduleIndex)
PreProcessing * createNewInstance() const
std::string getClassifierType() const
Definition: Classifier.cpp:161
Vector< ClassTracker > getClassTracker() const
virtual UINT getNumClasses() const
Definition: Classifier.cpp:191
VectorFloat getClusterLikelihoods() const
Definition: Clusterer.cpp:248
bool getTimeseriesCompatible() const
Definition: Classifier.h:245
std::string getClustererType() const
Definition: Clusterer.cpp:260
bool resetPlaybackIndex(const UINT playbackIndex)
UINT getNumDimensions() const
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
bool setNumDimensions(UINT numDimensions)
RegressionData getTrainingFoldData(const UINT foldIndex) const
virtual bool train(ClassificationData trainingData)
Definition: MLBase.cpp:89
virtual bool deepCopyFrom(const Clusterer *clusterer)
Definition: Clusterer.h:58
bool getTrained() const
Definition: MLBase.cpp:259
Float getRootMeanSquaredTrainingError() const
Definition: MLBase.cpp:239
UINT getNumSamples() const
virtual bool reset()
UINT getNumOutputDimensions() const
Definition: MLBase.cpp:214
Regressifier * createNewInstance() const
T * getData() const
Definition: Matrix.h:583
bool addContextModule(const Context &contextModule, UINT contextLevel, UINT insertIndex=INSERT_AT_END_INDEX)
bool preProcessData(VectorFloat inputVector, bool computeFeatures=true)
UINT getSize() const
Definition: Vector.h:191
static Regressifier * createInstanceFromString(const std::string &regressifierType)
bool setRegressifier(const Regressifier &regressifier)
UINT getNumInputDimensions() const
bool setAllowNullGestureClass(bool allowNullGestureClass)
bool removeFeatureExtractionModule(UINT moduleIndex)
static std::string intToString(const int &i)
Definition: Util.cpp:62
std::string getLastErrorMessage() const
Definition: GRTBase.cpp:55
bool setClassifier(const Classifier &classifier)
signed long getMilliSeconds()
Definition: Timer.h:117
Vector< TestInstanceResult > getTestInstanceResults() const
This file contains the GestureRecognitionPipeline class.
static PreProcessing * createInstanceFromString(std::string const &preProcessingType)
bool setAllValues(const T &value)
Definition: Matrix.h:336
bool setInputAndTargetDimensions(const UINT numInputDimensions, const UINT numTargetDimensions)
virtual bool save(const std::string filename) const
Definition: MLBase.cpp:143
virtual bool deepCopyFrom(const Regressifier *regressifier)
Definition: Regressifier.h:63
virtual bool load(const std::string filename)
Definition: MLBase.cpp:167
virtual bool deepCopyFrom(const Classifier *classifier)
Definition: Classifier.h:63
bool predict(const VectorFloat &inputVector)
UINT getNumSamples() const
bool load(const std::string &filename)
UINT getNumTargetDimensions() const
ClassificationSample getNextSample()
bool spiltDataIntoKFolds(const UINT K, const bool useStratifiedSampling=false)
Float getTotalSquaredTrainingError() const
Definition: MLBase.cpp:243
Vector< UINT > getClusterLabels() const
Definition: Clusterer.cpp:256
bool addPreProcessingModule(const PreProcessing &preProcessingModule, UINT insertIndex=INSERT_AT_END_INDEX)
bool getNullRejectionEnabled() const
Definition: Classifier.cpp:169
bool setClusterer(const Clusterer &clusterer)
Float getPhase() const
Definition: Classifier.cpp:182
std::string getRegressifierType() const
UINT getPredictedClassLabel() const
Definition: Classifier.cpp:203
GestureRecognitionPipeline & operator=(const GestureRecognitionPipeline &rhs)
FeatureExtraction * createNewInstance() const
bool savePipelineToFile(const std::string &filename) const
UINT getPipelineModeFromString(std::string pipelineMode) const
virtual bool reset()
Definition: Clusterer.cpp:128
static Classifier * createInstanceFromString(std::string const &classifierType)
Definition: Classifier.cpp:29
bool save(const std::string &filename) const
bool reserve(const UINT N)
unsigned int getNumRows() const
Definition: Matrix.h:542
UINT getNumDimensions() const
UINT getNumClasses() const
virtual std::string getModelAsString() const
Definition: MLBase.cpp:192
unsigned int getNumCols() const
Definition: Matrix.h:549
UINT getPredictedClusterLabel() const
Definition: Clusterer.cpp:237
Context * getContextModule(const UINT contextLevel, const UINT moduleIndex) const
Float getMaximumLikelihood() const
Definition: Classifier.cpp:177
Context * createNewInstance() const
Definition: Context.cpp:38
bool setFeatureExtractionModule(const FeatureExtraction &featureExtractionModule)
bool addFeatureExtractionModule(const FeatureExtraction &featureExtractionModule, UINT insertIndex=INSERT_AT_END_INDEX)
bool start()
Definition: Timer.h:64
bool loadPipelineFromFile(const std::string &filename)
virtual bool reset()
Definition: Classifier.cpp:123
UINT getNumInputFeatures() const
Definition: MLBase.cpp:210
Vector< TestResult > getCrossValidationResults() const
FeatureExtraction * getFeatureExtractionModule(const UINT moduleIndex) const
bool setInfo(const std::string &info)
bool map(const VectorFloat &inputVector)
VectorFloat getRow(const unsigned int r) const
Definition: MatrixFloat.h:100
VectorFloat getClassDistances() const
Definition: Classifier.cpp:213
virtual bool train_(ClassificationData &trainingData)
Definition: MLBase.cpp:91
bool notifyTestResultsObservers(const TestInstanceResult &data)
Definition: MLBase.cpp:359
bool addPostProcessingModule(const PostProcessing &postProcessingModule, UINT insertIndex=INSERT_AT_END_INDEX)
bool removePreProcessingModule(UINT moduleIndex)
UINT getNumClusters() const
Definition: Clusterer.cpp:235
bool updateContextModule(bool value, UINT contextLevel=0, UINT moduleIndex=0)
VectorFloat getClassLikelihoods() const
Definition: Classifier.cpp:208
bool setPostProcessingModule(const PostProcessing &postProcessingModule)
virtual bool train_(MatrixFloat &trainingData)
Definition: Clusterer.cpp:114
static PostProcessing * createInstanceFromString(std::string const &postProcessingType)
VectorFloat getRegressionData() const
PostProcessing * getPostProcessingModule(UINT moduleIndex) const
#define INSERT_AT_END_INDEX
virtual bool resize(const unsigned int r, const unsigned int c)
Definition: Matrix.h:232
PreProcessing * getPreProcessingModule(const UINT moduleIndex) const
VectorFloat getUnProcessedRegressionData() const
UINT getNumInputDimensions() const
Definition: MLBase.cpp:212
static Clusterer * createInstanceFromString(std::string const &ClustererType)
Definition: Clusterer.cpp:29
VectorFloat getClusterDistances() const
Definition: Clusterer.cpp:252
ClassificationData getTrainingFoldData(const UINT foldIndex) const
RegressionData getTestFoldData(const UINT foldIndex) const
bool test(const ClassificationData &testData)
bool push_back(const Vector< T > &sample)
Definition: Matrix.h:401
virtual bool clear()
Definition: Clusterer.cpp:142
virtual bool clear()
Definition: Classifier.cpp:142
TimeSeriesClassificationData getTrainingFoldData(const UINT foldIndex) const
Float getMaximumLikelihood() const
Definition: Clusterer.cpp:240
bool setPreProcessingModule(const PreProcessing &preProcessingModule)
bool addSample(const VectorFloat &inputVector, const VectorFloat &targetVector)
virtual bool deepCopyFrom(const FeatureExtraction *rhs)
Classifier * createNewInstance() const
Definition: Classifier.cpp:37
bool spiltDataIntoKFolds(const UINT K)
UINT getNumSamples() const
virtual bool clear()
Clusterer * createNewInstance() const
Definition: Clusterer.cpp:37
PostProcessing * createNewInstance() const
TimeSeriesClassificationData getTestFoldData(const UINT foldIndex) const