|
@@ -5,11 +5,15 @@
|
|
* @date 02/01/2012
|
|
* @date 02/01/2012
|
|
|
|
|
|
*/
|
|
*/
|
|
|
|
+
|
|
|
|
+// STL includes
|
|
#include <iostream>
|
|
#include <iostream>
|
|
|
|
|
|
-#include "core/basics/numerictools.h"
|
|
|
|
|
|
+// NICE-core includes
|
|
|
|
+#include <core/basics/numerictools.h>
|
|
#include <core/basics/Timer.h>
|
|
#include <core/basics/Timer.h>
|
|
|
|
|
|
|
|
+// gp-hik-core includes
|
|
#include "GPHIKClassifier.h"
|
|
#include "GPHIKClassifier.h"
|
|
#include "gp-hik-core/parameterizedFunctions/PFAbsExp.h"
|
|
#include "gp-hik-core/parameterizedFunctions/PFAbsExp.h"
|
|
#include "gp-hik-core/parameterizedFunctions/PFExp.h"
|
|
#include "gp-hik-core/parameterizedFunctions/PFExp.h"
|
|
@@ -18,43 +22,17 @@
|
|
using namespace std;
|
|
using namespace std;
|
|
using namespace NICE;
|
|
using namespace NICE;
|
|
|
|
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+// PROTECTED METHODS
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
|
|
-GPHIKClassifier::GPHIKClassifier( const Config *conf, const string & confSection )
|
|
|
|
-{
|
|
|
|
- //default settings, may be overwritten lateron
|
|
|
|
- gphyper = NULL;
|
|
|
|
- pf = NULL;
|
|
|
|
- confCopy = NULL;
|
|
|
|
- //just a default value
|
|
|
|
- uncertaintyPredictionForClassification = false;
|
|
|
|
-
|
|
|
|
- if ( conf == NULL )
|
|
|
|
- {
|
|
|
|
- fthrow(Exception, "GPHIKClassifier: the config is NULL -- use a default config and the restore-function instaed!");
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- this->init(conf, confSection);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-GPHIKClassifier::~GPHIKClassifier()
|
|
|
|
-{
|
|
|
|
- if ( gphyper != NULL )
|
|
|
|
- delete gphyper;
|
|
|
|
-
|
|
|
|
- if (pf != NULL)
|
|
|
|
- delete pf;
|
|
|
|
-
|
|
|
|
- if ( confCopy != NULL )
|
|
|
|
- delete confCopy;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void GPHIKClassifier::init(const Config *conf, const string & confSection)
|
|
|
|
|
|
+void GPHIKClassifier::init(const Config *conf, const string & s_confSection)
|
|
{
|
|
{
|
|
- double parameterLowerBound = conf->gD(confSection, "parameter_lower_bound", 1.0 );
|
|
|
|
double parameterUpperBound = conf->gD(confSection, "parameter_upper_bound", 5.0 );
|
|
double parameterUpperBound = conf->gD(confSection, "parameter_upper_bound", 5.0 );
|
|
|
|
+ double parameterLowerBound = conf->gD(confSection, "parameter_lower_bound", 1.0 );
|
|
|
|
|
|
- if (gphyper == NULL)
|
|
|
|
- this->gphyper = new FMKGPHyperparameterOptimization;
|
|
|
|
this->noise = conf->gD(confSection, "noise", 0.01);
|
|
this->noise = conf->gD(confSection, "noise", 0.01);
|
|
|
|
|
|
string transform = conf->gS(confSection, "transform", "absexp" );
|
|
string transform = conf->gS(confSection, "transform", "absexp" );
|
|
@@ -74,7 +52,8 @@ void GPHIKClassifier::init(const Config *conf, const string & confSection)
|
|
fthrow(Exception, "Transformation type is unknown " << transform);
|
|
fthrow(Exception, "Transformation type is unknown " << transform);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else{
|
|
|
|
|
|
+ else
|
|
|
|
+ {
|
|
//we already know the pf from the restore-function
|
|
//we already know the pf from the restore-function
|
|
}
|
|
}
|
|
this->confSection = confSection;
|
|
this->confSection = confSection;
|
|
@@ -83,23 +62,23 @@ void GPHIKClassifier::init(const Config *conf, const string & confSection)
|
|
this->uncertaintyPredictionForClassification = conf->gB( confSection, "uncertaintyPredictionForClassification", false );
|
|
this->uncertaintyPredictionForClassification = conf->gB( confSection, "uncertaintyPredictionForClassification", false );
|
|
|
|
|
|
if (confCopy != conf)
|
|
if (confCopy != conf)
|
|
- {
|
|
|
|
|
|
+ {
|
|
this->confCopy = new Config ( *conf );
|
|
this->confCopy = new Config ( *conf );
|
|
//we do not want to read until end of file for restoring
|
|
//we do not want to read until end of file for restoring
|
|
confCopy->setIoUntilEndOfFile(false);
|
|
confCopy->setIoUntilEndOfFile(false);
|
|
}
|
|
}
|
|
|
|
|
|
//how do we approximate the predictive variance for classification uncertainty?
|
|
//how do we approximate the predictive variance for classification uncertainty?
|
|
- string varianceApproximationString = conf->gS(confSection, "varianceApproximation", "approximate_fine"); //default: fine approximative uncertainty prediction
|
|
|
|
- if ( (varianceApproximationString.compare("approximate_rough") == 0) || ((varianceApproximationString.compare("1") == 0)) )
|
|
|
|
|
|
+ string s_varianceApproximation = conf->gS(confSection, "varianceApproximation", "approximate_fine"); //default: fine approximative uncertainty prediction
|
|
|
|
+ if ( (s_varianceApproximation.compare("approximate_rough") == 0) || ((s_varianceApproximation.compare("1") == 0)) )
|
|
{
|
|
{
|
|
this->varianceApproximation = APPROXIMATE_ROUGH;
|
|
this->varianceApproximation = APPROXIMATE_ROUGH;
|
|
}
|
|
}
|
|
- else if ( (varianceApproximationString.compare("approximate_fine") == 0) || ((varianceApproximationString.compare("2") == 0)) )
|
|
|
|
|
|
+ else if ( (s_varianceApproximation.compare("approximate_fine") == 0) || ((s_varianceApproximation.compare("2") == 0)) )
|
|
{
|
|
{
|
|
this->varianceApproximation = APPROXIMATE_FINE;
|
|
this->varianceApproximation = APPROXIMATE_FINE;
|
|
}
|
|
}
|
|
- else if ( (varianceApproximationString.compare("exact") == 0) || ((varianceApproximationString.compare("3") == 0)) )
|
|
|
|
|
|
+ else if ( (s_varianceApproximation.compare("exact") == 0) || ((s_varianceApproximation.compare("3") == 0)) )
|
|
{
|
|
{
|
|
this->varianceApproximation = EXACT;
|
|
this->varianceApproximation = EXACT;
|
|
}
|
|
}
|
|
@@ -107,23 +86,79 @@ void GPHIKClassifier::init(const Config *conf, const string & confSection)
|
|
{
|
|
{
|
|
this->varianceApproximation = NONE;
|
|
this->varianceApproximation = NONE;
|
|
}
|
|
}
|
|
- std::cerr << "varianceApproximationStrategy: " << varianceApproximationString << std::endl;
|
|
|
|
|
|
+
|
|
|
|
+ if ( this->verbose )
|
|
|
|
+ std::cerr << "varianceApproximationStrategy: " << s_varianceApproximation << std::endl;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+// PUBLIC METHODS
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+/////////////////////////////////////////////////////
|
|
|
|
+GPHIKClassifier::GPHIKClassifier( const Config *conf, const string & s_confSection )
|
|
|
|
+{
|
|
|
|
+ //default settings, may be overwritten lateron
|
|
|
|
+ gphyper = NULL;
|
|
|
|
+ pf = NULL;
|
|
|
|
+ confCopy = NULL;
|
|
|
|
+ //just a default value
|
|
|
|
+ uncertaintyPredictionForClassification = false;
|
|
|
|
+
|
|
|
|
+ this->confSection = s_confSection;
|
|
|
|
+
|
|
|
|
+ // if no config file was given, we either restore the classifier from an external file, or run ::init with
|
|
|
|
+ // an emtpy config (using default values thereby) when calling the train-method
|
|
|
|
+ if ( conf != NULL )
|
|
|
|
+ this->init(conf, confSection);
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::classify ( const SparseVector * example, int & result, SparseVector & scores )
|
|
|
|
|
|
+GPHIKClassifier::~GPHIKClassifier()
|
|
|
|
+{
|
|
|
|
+ if ( gphyper != NULL )
|
|
|
|
+ delete gphyper;
|
|
|
|
+
|
|
|
|
+ if (pf != NULL)
|
|
|
|
+ delete pf;
|
|
|
|
+
|
|
|
|
+ if ( confCopy != NULL )
|
|
|
|
+ delete confCopy;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+///////////////////// ///////////////////// /////////////////////
|
|
|
|
+// GET / SET
|
|
|
|
+///////////////////// ///////////////////// /////////////////////
|
|
|
|
+
|
|
|
|
+std::set<int> GPHIKClassifier::getKnownClassNumbers ( ) const
|
|
|
|
+{
|
|
|
|
+ if (gphyper == NULL)
|
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
|
+
|
|
|
|
+ return gphyper->getKnownClassNumbers();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+///////////////////// ///////////////////// /////////////////////
|
|
|
|
+// CLASSIFIER STUFF
|
|
|
|
+///////////////////// ///////////////////// /////////////////////
|
|
|
|
+
|
|
|
|
+void GPHIKClassifier::classify ( const SparseVector * example, int & result, SparseVector & scores ) const
|
|
{
|
|
{
|
|
double tmpUncertainty;
|
|
double tmpUncertainty;
|
|
this->classify( example, result, scores, tmpUncertainty );
|
|
this->classify( example, result, scores, tmpUncertainty );
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::classify ( const NICE::Vector * example, int & result, SparseVector & scores )
|
|
|
|
|
|
+void GPHIKClassifier::classify ( const NICE::Vector * example, int & result, SparseVector & scores ) const
|
|
{
|
|
{
|
|
double tmpUncertainty;
|
|
double tmpUncertainty;
|
|
this->classify( example, result, scores, tmpUncertainty );
|
|
this->classify( example, result, scores, tmpUncertainty );
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::classify ( const SparseVector * example, int & result, SparseVector & scores, double & uncertainty )
|
|
|
|
|
|
+void GPHIKClassifier::classify ( const SparseVector * example, int & result, SparseVector & scores, double & uncertainty ) const
|
|
{
|
|
{
|
|
|
|
+ if (gphyper == NULL)
|
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
|
+
|
|
scores.clear();
|
|
scores.clear();
|
|
|
|
|
|
int classno = gphyper->classify ( *example, scores );
|
|
int classno = gphyper->classify ( *example, scores );
|
|
@@ -138,9 +173,7 @@ void GPHIKClassifier::classify ( const SparseVector * example, int & result, Sp
|
|
{
|
|
{
|
|
if (varianceApproximation != NONE)
|
|
if (varianceApproximation != NONE)
|
|
{
|
|
{
|
|
- NICE::Vector uncertainties;
|
|
|
|
- this->predictUncertainty( example, uncertainties );
|
|
|
|
- uncertainty = uncertainties.Max();
|
|
|
|
|
|
+ this->predictUncertainty( example, uncertainty );
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
@@ -155,8 +188,11 @@ void GPHIKClassifier::classify ( const SparseVector * example, int & result, Sp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::classify ( const NICE::Vector * example, int & result, SparseVector & scores, double & uncertainty )
|
|
|
|
|
|
+void GPHIKClassifier::classify ( const NICE::Vector * example, int & result, SparseVector & scores, double & uncertainty ) const
|
|
{
|
|
{
|
|
|
|
+ if (gphyper == NULL)
|
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
|
+
|
|
scores.clear();
|
|
scores.clear();
|
|
|
|
|
|
int classno = gphyper->classify ( *example, scores );
|
|
int classno = gphyper->classify ( *example, scores );
|
|
@@ -166,13 +202,12 @@ void GPHIKClassifier::classify ( const NICE::Vector * example, int & result, Sp
|
|
}
|
|
}
|
|
|
|
|
|
result = scores.maxElement();
|
|
result = scores.maxElement();
|
|
-
|
|
|
|
|
|
+
|
|
if (uncertaintyPredictionForClassification)
|
|
if (uncertaintyPredictionForClassification)
|
|
{
|
|
{
|
|
if (varianceApproximation != NONE)
|
|
if (varianceApproximation != NONE)
|
|
{
|
|
{
|
|
- std::cerr << "ERROR: Uncertainty computation is currently not supported for NICE::Vector - use SparseVector instead" << std::endl;
|
|
|
|
- uncertainty = std::numeric_limits<double>::max();
|
|
|
|
|
|
+ this->predictUncertainty( example, uncertainty );
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
@@ -184,14 +219,23 @@ void GPHIKClassifier::classify ( const NICE::Vector * example, int & result, Sp
|
|
{
|
|
{
|
|
//do nothing
|
|
//do nothing
|
|
uncertainty = std::numeric_limits<double>::max();
|
|
uncertainty = std::numeric_limits<double>::max();
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/** training process */
|
|
/** training process */
|
|
-void GPHIKClassifier::train ( const std::vector< NICE::SparseVector *> & examples, const NICE::Vector & labels )
|
|
|
|
|
|
+void GPHIKClassifier::train ( const std::vector< const NICE::SparseVector *> & examples, const NICE::Vector & labels )
|
|
{
|
|
{
|
|
if (verbose)
|
|
if (verbose)
|
|
|
|
+ {
|
|
std::cerr << "GPHIKClassifier::train" << std::endl;
|
|
std::cerr << "GPHIKClassifier::train" << std::endl;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this->confCopy == NULL )
|
|
|
|
+ {
|
|
|
|
+ std::cerr << "WARNING -- No config used so far, initialize values with empty config file now..." << std::endl;
|
|
|
|
+ NICE::Config tmpConfEmpty ;
|
|
|
|
+ this->init ( &tmpConfEmpty, this->confSection );
|
|
|
|
+ }
|
|
|
|
|
|
Timer t;
|
|
Timer t;
|
|
t.start();
|
|
t.start();
|
|
@@ -201,6 +245,13 @@ void GPHIKClassifier::train ( const std::vector< NICE::SparseVector *> & example
|
|
if (verbose)
|
|
if (verbose)
|
|
std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
|
|
std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
|
|
|
|
|
|
|
|
+ if (gphyper != NULL)
|
|
|
|
+ delete gphyper;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if ( ( varianceApproximation != APPROXIMATE_FINE) )
|
|
|
|
+ confCopy->sI ( confSection, "nrOfEigenvaluesToConsiderForVarApprox", 0);
|
|
|
|
+
|
|
gphyper = new FMKGPHyperparameterOptimization ( confCopy, pf, fmk, confSection );
|
|
gphyper = new FMKGPHyperparameterOptimization ( confCopy, pf, fmk, confSection );
|
|
|
|
|
|
if (verbose)
|
|
if (verbose)
|
|
@@ -209,14 +260,36 @@ void GPHIKClassifier::train ( const std::vector< NICE::SparseVector *> & example
|
|
// go go go
|
|
// go go go
|
|
gphyper->optimize ( labels );
|
|
gphyper->optimize ( labels );
|
|
if (verbose)
|
|
if (verbose)
|
|
- std::cerr << "optimization done, now prepare for the uncertainty prediction" << std::endl;
|
|
|
|
|
|
+ std::cerr << "optimization done" << std::endl;
|
|
|
|
|
|
- if ( (varianceApproximation == APPROXIMATE_ROUGH) )
|
|
|
|
|
|
+ if ( ( varianceApproximation != NONE ) )
|
|
{
|
|
{
|
|
- //prepare for variance computation (approximative)
|
|
|
|
- gphyper->prepareVarianceApproximation();
|
|
|
|
|
|
+ std::cerr << "now prepare for the uncertainty prediction" << std::endl;
|
|
|
|
+
|
|
|
|
+ switch (varianceApproximation)
|
|
|
|
+ {
|
|
|
|
+ case APPROXIMATE_ROUGH:
|
|
|
|
+ {
|
|
|
|
+ gphyper->prepareVarianceApproximationRough();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case APPROXIMATE_FINE:
|
|
|
|
+ {
|
|
|
|
+ gphyper->prepareVarianceApproximationFine();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case EXACT:
|
|
|
|
+ {
|
|
|
|
+ //nothing to prepare
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ {
|
|
|
|
+ //nothing to prepare
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- //for exact variance computation, we do not have to prepare anything
|
|
|
|
|
|
+
|
|
|
|
|
|
// clean up all examples ??
|
|
// clean up all examples ??
|
|
if (verbose)
|
|
if (verbose)
|
|
@@ -224,10 +297,17 @@ void GPHIKClassifier::train ( const std::vector< NICE::SparseVector *> & example
|
|
}
|
|
}
|
|
|
|
|
|
/** training process */
|
|
/** training process */
|
|
-void GPHIKClassifier::train ( const std::vector< SparseVector *> & examples, std::map<int, NICE::Vector> & binLabels )
|
|
|
|
|
|
+void GPHIKClassifier::train ( const std::vector< const NICE::SparseVector *> & examples, std::map<int, NICE::Vector> & binLabels )
|
|
{
|
|
{
|
|
if (verbose)
|
|
if (verbose)
|
|
std::cerr << "GPHIKClassifier::train" << std::endl;
|
|
std::cerr << "GPHIKClassifier::train" << std::endl;
|
|
|
|
+
|
|
|
|
+ if ( this->confCopy == NULL )
|
|
|
|
+ {
|
|
|
|
+ std::cerr << "WARNING -- No config used so far, initialize values with empty config file now..." << std::endl;
|
|
|
|
+ NICE::Config tmpConfEmpty ;
|
|
|
|
+ this->init ( &tmpConfEmpty, this->confSection );
|
|
|
|
+ }
|
|
|
|
|
|
Timer t;
|
|
Timer t;
|
|
t.start();
|
|
t.start();
|
|
@@ -236,6 +316,8 @@ void GPHIKClassifier::train ( const std::vector< SparseVector *> & examples, std
|
|
if (verbose)
|
|
if (verbose)
|
|
std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
|
|
std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
|
|
|
|
|
|
|
|
+ if (gphyper != NULL)
|
|
|
|
+ delete gphyper;
|
|
gphyper = new FMKGPHyperparameterOptimization ( confCopy, pf, fmk, confSection );
|
|
gphyper = new FMKGPHyperparameterOptimization ( confCopy, pf, fmk, confSection );
|
|
|
|
|
|
if (verbose)
|
|
if (verbose)
|
|
@@ -245,25 +327,39 @@ void GPHIKClassifier::train ( const std::vector< SparseVector *> & examples, std
|
|
if (verbose)
|
|
if (verbose)
|
|
std::cerr << "optimization done, now prepare for the uncertainty prediction" << std::endl;
|
|
std::cerr << "optimization done, now prepare for the uncertainty prediction" << std::endl;
|
|
|
|
|
|
- if ( (varianceApproximation == APPROXIMATE_ROUGH) )
|
|
|
|
|
|
+ if ( ( varianceApproximation != NONE ) )
|
|
{
|
|
{
|
|
- //prepare for variance computation (approximative)
|
|
|
|
- gphyper->prepareVarianceApproximation();
|
|
|
|
|
|
+ std::cerr << "now prepare for the uncertainty prediction" << std::endl;
|
|
|
|
+
|
|
|
|
+ switch (varianceApproximation)
|
|
|
|
+ {
|
|
|
|
+ case APPROXIMATE_ROUGH:
|
|
|
|
+ {
|
|
|
|
+ gphyper->prepareVarianceApproximationRough();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case APPROXIMATE_FINE:
|
|
|
|
+ {
|
|
|
|
+ gphyper->prepareVarianceApproximationFine();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case EXACT:
|
|
|
|
+ {
|
|
|
|
+ //nothing to prepare
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ {
|
|
|
|
+ //nothing to prepare
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- //for exact variance computation, we do not have to prepare anything
|
|
|
|
|
|
|
|
// clean up all examples ??
|
|
// clean up all examples ??
|
|
if (verbose)
|
|
if (verbose)
|
|
std::cerr << "Learning finished" << std::endl;
|
|
std::cerr << "Learning finished" << std::endl;
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::clear ()
|
|
|
|
-{
|
|
|
|
- if ( gphyper != NULL )
|
|
|
|
- delete gphyper;
|
|
|
|
- gphyper = NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
GPHIKClassifier *GPHIKClassifier::clone () const
|
|
GPHIKClassifier *GPHIKClassifier::clone () const
|
|
{
|
|
{
|
|
fthrow(Exception, "GPHIKClassifier: clone() not yet implemented" );
|
|
fthrow(Exception, "GPHIKClassifier: clone() not yet implemented" );
|
|
@@ -271,107 +367,253 @@ GPHIKClassifier *GPHIKClassifier::clone () const
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::predictUncertainty( const NICE::SparseVector * example, NICE::Vector & uncertainties )
|
|
|
|
|
|
+void GPHIKClassifier::predictUncertainty( const NICE::SparseVector * example, double & uncertainty ) const
|
|
|
|
+{
|
|
|
|
+ if (gphyper == NULL)
|
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
|
+
|
|
|
|
+ //we directly store the predictive variances in the vector, that contains the classification uncertainties lateron to save storage
|
|
|
|
+ switch (varianceApproximation)
|
|
|
|
+ {
|
|
|
|
+ case APPROXIMATE_ROUGH:
|
|
|
|
+ {
|
|
|
|
+ gphyper->computePredictiveVarianceApproximateRough( *example, uncertainty );
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case APPROXIMATE_FINE:
|
|
|
|
+ {
|
|
|
|
+ std::cerr << "predict uncertainty fine" << std::endl;
|
|
|
|
+ gphyper->computePredictiveVarianceApproximateFine( *example, uncertainty );
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case EXACT:
|
|
|
|
+ {
|
|
|
|
+ gphyper->computePredictiveVarianceExact( *example, uncertainty );
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ {
|
|
|
|
+ fthrow(Exception, "GPHIKClassifier - your settings disabled the variance approximation needed for uncertainty prediction.");
|
|
|
|
+// uncertainty = numeric_limits<double>::max();
|
|
|
|
+// break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void GPHIKClassifier::predictUncertainty( const NICE::Vector * example, double & uncertainty ) const
|
|
{
|
|
{
|
|
|
|
+ if (gphyper == NULL)
|
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
|
+
|
|
//we directly store the predictive variances in the vector, that contains the classification uncertainties lateron to save storage
|
|
//we directly store the predictive variances in the vector, that contains the classification uncertainties lateron to save storage
|
|
switch (varianceApproximation)
|
|
switch (varianceApproximation)
|
|
{
|
|
{
|
|
case APPROXIMATE_ROUGH:
|
|
case APPROXIMATE_ROUGH:
|
|
{
|
|
{
|
|
- gphyper->computePredictiveVarianceApproximateRough( *example, uncertainties );
|
|
|
|
|
|
+ gphyper->computePredictiveVarianceApproximateRough( *example, uncertainty );
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case APPROXIMATE_FINE:
|
|
case APPROXIMATE_FINE:
|
|
{
|
|
{
|
|
- gphyper->computePredictiveVarianceApproximateFine( *example, uncertainties );
|
|
|
|
|
|
+ std::cerr << "predict uncertainty fine" << std::endl;
|
|
|
|
+ gphyper->computePredictiveVarianceApproximateFine( *example, uncertainty );
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case EXACT:
|
|
case EXACT:
|
|
{
|
|
{
|
|
- gphyper->computePredictiveVarianceExact( *example, uncertainties );
|
|
|
|
|
|
+ gphyper->computePredictiveVarianceExact( *example, uncertainty );
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
default:
|
|
default:
|
|
{
|
|
{
|
|
-// std::cerr << "No Uncertainty Prediction at all" << std::endl;
|
|
|
|
fthrow(Exception, "GPHIKClassifier - your settings disabled the variance approximation needed for uncertainty prediction.");
|
|
fthrow(Exception, "GPHIKClassifier - your settings disabled the variance approximation needed for uncertainty prediction.");
|
|
-// uncertainties.resize( 1 );
|
|
|
|
-// uncertainties.set( numeric_limits<double>::max() );
|
|
|
|
|
|
+// uncertainty = numeric_limits<double>::max();
|
|
// break;
|
|
// break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-//---------------------------------------------------------------------
|
|
|
|
-// protected methods
|
|
|
|
-//---------------------------------------------------------------------
|
|
|
|
|
|
+///////////////////// INTERFACE PERSISTENT /////////////////////
|
|
|
|
+// interface specific methods for store and restore
|
|
|
|
+///////////////////// INTERFACE PERSISTENT /////////////////////
|
|
|
|
+
|
|
void GPHIKClassifier::restore ( std::istream & is, int format )
|
|
void GPHIKClassifier::restore ( std::istream & is, int format )
|
|
{
|
|
{
|
|
- if (is.good())
|
|
|
|
|
|
+ //delete everything we knew so far...
|
|
|
|
+ this->clear();
|
|
|
|
+
|
|
|
|
+ bool b_restoreVerbose ( false );
|
|
|
|
+#ifdef B_RESTOREVERBOSE
|
|
|
|
+ b_restoreVerbose = true;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if ( is.good() )
|
|
{
|
|
{
|
|
- is.precision (numeric_limits<double>::digits10 + 1);
|
|
|
|
|
|
+ if ( b_restoreVerbose )
|
|
|
|
+ std::cerr << " restore GPHIKClassifier" << std::endl;
|
|
|
|
+
|
|
|
|
+ std::string tmp;
|
|
|
|
+ is >> tmp; //class name
|
|
|
|
|
|
- string tmp;
|
|
|
|
- is >> tmp;
|
|
|
|
- is >> confSection;
|
|
|
|
|
|
+ if ( ! this->isStartTag( tmp, "GPHIKClassifier" ) )
|
|
|
|
+ {
|
|
|
|
+ std::cerr << " WARNING - attempt to restore GPHIKClassifier, but start flag " << tmp << " does not match! Aborting... " << std::endl;
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
|
|
|
|
if (pf != NULL)
|
|
if (pf != NULL)
|
|
{
|
|
{
|
|
delete pf;
|
|
delete pf;
|
|
|
|
+ pf = NULL;
|
|
}
|
|
}
|
|
- string transform;
|
|
|
|
- is >> transform;
|
|
|
|
- if ( transform == "absexp" )
|
|
|
|
|
|
+ if ( confCopy != NULL )
|
|
{
|
|
{
|
|
- this->pf = new PFAbsExp ();
|
|
|
|
- } else if ( transform == "exp" ) {
|
|
|
|
- this->pf = new PFExp ();
|
|
|
|
- } else {
|
|
|
|
- fthrow(Exception, "Transformation type is unknown " << transform);
|
|
|
|
|
|
+ delete confCopy;
|
|
|
|
+ confCopy = NULL;
|
|
|
|
+ }
|
|
|
|
+ if (gphyper != NULL)
|
|
|
|
+ {
|
|
|
|
+ delete gphyper;
|
|
|
|
+ gphyper = NULL;
|
|
}
|
|
}
|
|
- pf->restore(is, format);
|
|
|
|
-
|
|
|
|
- //load every options we determined explicitely
|
|
|
|
- confCopy->clear();
|
|
|
|
- //we do not want to read until the end of the file
|
|
|
|
- confCopy->setIoUntilEndOfFile( false );
|
|
|
|
- confCopy->restore(is, format);
|
|
|
|
|
|
+
|
|
|
|
+ is.precision (numeric_limits<double>::digits10 + 1);
|
|
|
|
+
|
|
|
|
+ bool b_endOfBlock ( false ) ;
|
|
|
|
+
|
|
|
|
+ while ( !b_endOfBlock )
|
|
|
|
+ {
|
|
|
|
+ is >> tmp; // start of block
|
|
|
|
+
|
|
|
|
+ if ( this->isEndTag( tmp, "GPHIKClassifier" ) )
|
|
|
|
+ {
|
|
|
|
+ b_endOfBlock = true;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tmp = this->removeStartTag ( tmp );
|
|
|
|
+
|
|
|
|
+ if ( b_restoreVerbose )
|
|
|
|
+ std::cerr << " currently restore section " << tmp << " in GPHIKClassifier" << std::endl;
|
|
|
|
+
|
|
|
|
+ if ( tmp.compare("confSection") == 0 )
|
|
|
|
+ {
|
|
|
|
+ is >> confSection;
|
|
|
|
+ is >> tmp; // end of block
|
|
|
|
+ tmp = this->removeEndTag ( tmp );
|
|
|
|
+ }
|
|
|
|
+ else if ( tmp.compare("pf") == 0 )
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ is >> tmp; // start of block
|
|
|
|
+ if ( this->isEndTag( tmp, "pf" ) )
|
|
|
|
+ {
|
|
|
|
+ std::cerr << " ParameterizedFunction object can not be restored. Aborting..." << std::endl;
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::string transform = this->removeStartTag ( tmp );
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if ( transform == "PFAbsExp" )
|
|
|
|
+ {
|
|
|
|
+ this->pf = new PFAbsExp ();
|
|
|
|
+ } else if ( transform == "PFExp" ) {
|
|
|
|
+ this->pf = new PFExp ();
|
|
|
|
+ } else {
|
|
|
|
+ fthrow(Exception, "Transformation type is unknown " << transform);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pf->restore(is, format);
|
|
|
|
+
|
|
|
|
+ is >> tmp; // end of block
|
|
|
|
+ tmp = this->removeEndTag ( tmp );
|
|
|
|
+ }
|
|
|
|
+ else if ( tmp.compare("ConfigCopy") == 0 )
|
|
|
|
+ {
|
|
|
|
+ // possibly obsolete safety checks
|
|
|
|
+ if ( confCopy == NULL )
|
|
|
|
+ confCopy = new Config;
|
|
|
|
+ confCopy->clear();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //we do not want to read until the end of the file
|
|
|
|
+ confCopy->setIoUntilEndOfFile( false );
|
|
|
|
+ //load every options we determined explicitely
|
|
|
|
+ confCopy->restore(is, format);
|
|
|
|
+
|
|
|
|
+ is >> tmp; // end of block
|
|
|
|
+ tmp = this->removeEndTag ( tmp );
|
|
|
|
+ }
|
|
|
|
+ else if ( tmp.compare("gphyper") == 0 )
|
|
|
|
+ {
|
|
|
|
+ if ( gphyper == NULL )
|
|
|
|
+ gphyper = new NICE::FMKGPHyperparameterOptimization();
|
|
|
|
+
|
|
|
|
+ //then, load everything that we stored explicitely,
|
|
|
|
+ // including precomputed matrices, LUTs, eigenvalues, ... and all that stuff
|
|
|
|
+ gphyper->restore(is, format);
|
|
|
|
+
|
|
|
|
+ is >> tmp; // end of block
|
|
|
|
+ tmp = this->removeEndTag ( tmp );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cerr << "WARNING -- unexpected GPHIKClassifier object -- " << tmp << " -- for restoration... aborting" << std::endl;
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+
|
|
//load every settings as well as default options
|
|
//load every settings as well as default options
|
|
- this->init(confCopy, confSection);
|
|
|
|
-
|
|
|
|
- //first read things from the config
|
|
|
|
- gphyper->initialize ( confCopy, pf );
|
|
|
|
-
|
|
|
|
- //then, load everything that we stored explicitely,
|
|
|
|
- // including precomputed matrices, LUTs, eigenvalues, ... and all that stuff
|
|
|
|
- gphyper->restore(is, format);
|
|
|
|
|
|
+ std::cerr << "run this->init" << std::endl;
|
|
|
|
+ this->init(confCopy, confSection);
|
|
|
|
+ std::cerr << "run gphyper->initialize" << std::endl;
|
|
|
|
+ gphyper->initialize ( confCopy, pf, NULL, confSection );
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
std::cerr << "GPHIKClassifier::restore -- InStream not initialized - restoring not possible!" << std::endl;
|
|
std::cerr << "GPHIKClassifier::restore -- InStream not initialized - restoring not possible!" << std::endl;
|
|
|
|
+ throw;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void GPHIKClassifier::store ( std::ostream & os, int format ) const
|
|
void GPHIKClassifier::store ( std::ostream & os, int format ) const
|
|
{
|
|
{
|
|
|
|
+ if (gphyper == NULL)
|
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
|
+
|
|
if (os.good())
|
|
if (os.good())
|
|
{
|
|
{
|
|
|
|
+ // show starting point
|
|
|
|
+ os << this->createStartTag( "GPHIKClassifier" ) << std::endl;
|
|
|
|
+
|
|
os.precision (numeric_limits<double>::digits10 + 1);
|
|
os.precision (numeric_limits<double>::digits10 + 1);
|
|
|
|
|
|
- os << "confSection: "<< confSection << std::endl;
|
|
|
|
|
|
+ os << this->createStartTag( "confSection" ) << std::endl;
|
|
|
|
+ os << confSection << std::endl;
|
|
|
|
+ os << this->createEndTag( "confSection" ) << std::endl;
|
|
|
|
|
|
- os << pf->sayYourName() << std::endl;
|
|
|
|
|
|
+ os << this->createStartTag( "pf" ) << std::endl;
|
|
pf->store(os, format);
|
|
pf->store(os, format);
|
|
-
|
|
|
|
|
|
+ os << this->createEndTag( "pf" ) << std::endl;
|
|
|
|
+
|
|
|
|
+ os << this->createStartTag( "ConfigCopy" ) << std::endl;
|
|
//we do not want to read until end of file for restoring
|
|
//we do not want to read until end of file for restoring
|
|
confCopy->setIoUntilEndOfFile(false);
|
|
confCopy->setIoUntilEndOfFile(false);
|
|
- confCopy->store(os,format);
|
|
|
|
|
|
+ confCopy->store(os,format);
|
|
|
|
+ os << this->createEndTag( "ConfigCopy" ) << std::endl;
|
|
|
|
|
|
|
|
+ os << this->createStartTag( "gphyper" ) << std::endl;
|
|
//store the underlying data
|
|
//store the underlying data
|
|
//will be done in gphyper->store(of,format)
|
|
//will be done in gphyper->store(of,format)
|
|
//store the optimized parameter values and all that stuff
|
|
//store the optimized parameter values and all that stuff
|
|
- gphyper->store(os, format);
|
|
|
|
|
|
+ gphyper->store(os, format);
|
|
|
|
+ os << this->createEndTag( "gphyper" ) << std::endl;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // done
|
|
|
|
+ os << this->createEndTag( "GPHIKClassifier" ) << std::endl;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
@@ -379,16 +621,84 @@ void GPHIKClassifier::store ( std::ostream & os, int format ) const
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::addExample( const NICE::SparseVector * example, const double & label, const bool & performOptimizationAfterIncrement)
|
|
|
|
|
|
+void GPHIKClassifier::clear ()
|
|
{
|
|
{
|
|
- gphyper->addExample( *example, label, performOptimizationAfterIncrement );
|
|
|
|
|
|
+ if ( gphyper != NULL )
|
|
|
|
+ {
|
|
|
|
+ delete gphyper;
|
|
|
|
+ gphyper = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (pf != NULL)
|
|
|
|
+ {
|
|
|
|
+ delete pf;
|
|
|
|
+ pf = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( confCopy != NULL )
|
|
|
|
+ {
|
|
|
|
+ delete confCopy;
|
|
|
|
+ confCopy = NULL;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-void GPHIKClassifier::addMultipleExamples( const std::vector< const NICE::SparseVector *> & newExamples, const NICE::Vector & newLabels, const bool & performOptimizationAfterIncrement)
|
|
|
|
|
|
+///////////////////// INTERFACE ONLINE LEARNABLE /////////////////////
|
|
|
|
+// interface specific methods for incremental extensions
|
|
|
|
+///////////////////// INTERFACE ONLINE LEARNABLE /////////////////////
|
|
|
|
+
|
|
|
|
+void GPHIKClassifier::addExample( const NICE::SparseVector * example,
|
|
|
|
+ const double & label,
|
|
|
|
+ const bool & performOptimizationAfterIncrement
|
|
|
|
+ )
|
|
|
|
+{
|
|
|
|
+ //***done*** //TODO add option for starting with empty classifier!
|
|
|
|
+ //***done*** // -> call train() with converted input here
|
|
|
|
+ //***done*** // TODO add option to go from 2 to 3 classes! ***done***
|
|
|
|
+ //***done*** // TODO add option going from 1 to 2 classes without adding new alpha vector
|
|
|
|
+ //***done*** // TODO check variance matrices in update ***done***
|
|
|
|
+ // TODO add check option for variance update
|
|
|
|
+ //***done*** // TODO adapt code for addMultipleExamples
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if ( this->gphyper == NULL )
|
|
|
|
+ {
|
|
|
|
+ //call train method instead
|
|
|
|
+ std::cerr << "Classifier not initially trained yet -- run initial training instead of incremental extension!" << std::endl;
|
|
|
|
+
|
|
|
|
+ std::vector< const NICE::SparseVector *> examplesVec;
|
|
|
|
+ examplesVec.push_back ( example );
|
|
|
|
+
|
|
|
|
+ NICE::Vector labelsVec ( 1 , label );
|
|
|
|
+
|
|
|
|
+ this->train ( examplesVec, labelsVec );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ this->gphyper->addExample( example, label, performOptimizationAfterIncrement );
|
|
|
|
+
|
|
|
|
+ std::cerr << " --- GPHIKClassifierIL::addExample done --- " << std::endl;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void GPHIKClassifier::addMultipleExamples( const std::vector< const NICE::SparseVector * > & newExamples,
|
|
|
|
+ const NICE::Vector & newLabels,
|
|
|
|
+ const bool & performOptimizationAfterIncrement
|
|
|
|
+ )
|
|
{
|
|
{
|
|
//are new examples available? If not, nothing has to be done
|
|
//are new examples available? If not, nothing has to be done
|
|
if ( newExamples.size() < 1)
|
|
if ( newExamples.size() < 1)
|
|
return;
|
|
return;
|
|
-
|
|
|
|
- gphyper->addMultipleExamples( newExamples, newLabels, performOptimizationAfterIncrement );
|
|
|
|
-}
|
|
|
|
|
|
+
|
|
|
|
+ if ( this->gphyper == NULL )
|
|
|
|
+ {
|
|
|
|
+ //call train method instead
|
|
|
|
+
|
|
|
|
+ this->train ( newExamples, newLabels );
|
|
|
|
+
|
|
|
|
+ std::cerr << "train method successfully called in add multiple examples" << std::endl;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ this->gphyper->addMultipleExamples( newExamples, newLabels, performOptimizationAfterIncrement );
|
|
|
|
+ }
|
|
|
|
+}
|