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