|
@@ -0,0 +1,235 @@
|
|
|
+
|
|
|
+* @file GPHIKRawClassifier.cpp
|
|
|
+* @brief Main interface for our GP HIK classifier (similar to the feature pool classifier interface in vislearning) (Implementation)
|
|
|
+* @author Erik Rodner, Alexander Freytag
|
|
|
+* @date 02/01/2012
|
|
|
+
|
|
|
+*/
|
|
|
+
|
|
|
+
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+
|
|
|
+#include <core/basics/numerictools.h>
|
|
|
+#include <core/basics/Timer.h>
|
|
|
+
|
|
|
+#include <core/algebra/ILSConjugateGradients.h>
|
|
|
+
|
|
|
+
|
|
|
+#include "GPHIKRawClassifier.h"
|
|
|
+#include "GMHIKernelRaw.h"
|
|
|
+
|
|
|
+using namespace std;
|
|
|
+using namespace NICE;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+GPHIKRawClassifier::GPHIKRawClassifier( )
|
|
|
+{
|
|
|
+ this->b_isTrained = false;
|
|
|
+ this->confSection = "";
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ NICE::Config tmpConfEmpty ;
|
|
|
+ this->initFromConfig ( &tmpConfEmpty, this->confSection );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+GPHIKRawClassifier::GPHIKRawClassifier( const Config *_conf,
|
|
|
+ const string & _confSection
|
|
|
+ )
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ this->b_isTrained = false;
|
|
|
+ this->confSection = "";
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ this->confSection = _confSection;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if ( _conf != NULL )
|
|
|
+ {
|
|
|
+ this->initFromConfig( _conf, _confSection );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ NICE::Config tmpConfEmpty ;
|
|
|
+ this->initFromConfig ( &tmpConfEmpty, this->confSection );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+GPHIKRawClassifier::~GPHIKRawClassifier()
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+void GPHIKRawClassifier::initFromConfig(const Config *_conf,
|
|
|
+ const string & _confSection
|
|
|
+ )
|
|
|
+{
|
|
|
+ this->d_noise = _conf->gD( _confSection, "noise", 0.01);
|
|
|
+
|
|
|
+ this->confSection = _confSection;
|
|
|
+ this->b_verbose = _conf->gB( _confSection, "verbose", false);
|
|
|
+ this->b_debug = _conf->gB( _confSection, "debug", false);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+std::set<uint> GPHIKRawClassifier::getKnownClassNumbers ( ) const
|
|
|
+{
|
|
|
+ if ( ! this->b_isTrained )
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
+
|
|
|
+ fthrow(Exception, "GPHIKRawClassifier::getKnownClassNumbers() not yet implemented");
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void GPHIKRawClassifier::classify ( const SparseVector * _example,
|
|
|
+ uint & _result,
|
|
|
+ SparseVector & _scores
|
|
|
+ ) const
|
|
|
+{
|
|
|
+ if ( ! this->b_isTrained )
|
|
|
+ fthrow(Exception, "Classifier not trained yet -- aborting!" );
|
|
|
+
|
|
|
+ _scores.clear();
|
|
|
+
|
|
|
+ if ( this->b_debug )
|
|
|
+ {
|
|
|
+ std::cerr << "GPHIKRawClassifier::classify (sparse)" << std::endl;
|
|
|
+ _example->store( std::cerr );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if ( this->b_debug )
|
|
|
+ {
|
|
|
+ _scores.store ( std::cerr );
|
|
|
+ std::cerr << "_result: " << _result << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( _scores.size() == 0 ) {
|
|
|
+ fthrow(Exception, "Zero scores, something is likely to be wrong here: svec.size() = " << _example->size() );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void GPHIKRawClassifier::classify ( const NICE::Vector * _example,
|
|
|
+ uint & _result,
|
|
|
+ SparseVector & _scores
|
|
|
+ ) const
|
|
|
+{
|
|
|
+ fthrow(Exception, "GPHIKRawClassifier::classify( Vector ... ) not yet implemented");
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void GPHIKRawClassifier::train ( const std::vector< const NICE::SparseVector *> & _examples,
|
|
|
+ const NICE::Vector & _labels
|
|
|
+ )
|
|
|
+{
|
|
|
+
|
|
|
+ if ( _examples.size() != _labels.size() )
|
|
|
+ {
|
|
|
+ fthrow(Exception, "Given examples do not match label vector in size -- aborting!" );
|
|
|
+ }
|
|
|
+
|
|
|
+ set<uint> classes;
|
|
|
+ for ( uint i = 0; i < _labels.size(); i++ )
|
|
|
+ classes.insert((uint)_labels[i]);
|
|
|
+
|
|
|
+ std::map<uint, NICE::Vector> binLabels;
|
|
|
+ for ( set<uint>::const_iterator j = classes.begin(); j != classes.end(); j++ )
|
|
|
+ {
|
|
|
+ uint current_class = *j;
|
|
|
+ Vector labels_binary ( _labels.size() );
|
|
|
+ for ( uint i = 0; i < _labels.size(); i++ )
|
|
|
+ labels_binary[i] = ( _labels[i] == current_class ) ? 1.0 : -1.0;
|
|
|
+
|
|
|
+ binLabels.insert ( pair<uint, NICE::Vector>( current_class, labels_binary) );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ train ( _examples, binLabels );
|
|
|
+}
|
|
|
+
|
|
|
+void GPHIKRawClassifier::train ( const std::vector< const NICE::SparseVector *> & _examples,
|
|
|
+ std::map<uint, NICE::Vector> & _binLabels
|
|
|
+ )
|
|
|
+{
|
|
|
+
|
|
|
+ for ( std::map< uint, NICE::Vector >::const_iterator binLabIt = _binLabels.begin();
|
|
|
+ binLabIt != _binLabels.end();
|
|
|
+ binLabIt++
|
|
|
+ )
|
|
|
+ {
|
|
|
+ if ( _examples.size() != binLabIt->second.size() )
|
|
|
+ {
|
|
|
+ fthrow(Exception, "Given examples do not match label vector in size -- aborting!" );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( this->b_verbose )
|
|
|
+ std::cerr << "GPHIKRawClassifier::train" << std::endl;
|
|
|
+
|
|
|
+ Timer t;
|
|
|
+ t.start();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ GMHIKernelRaw gm ( _examples );
|
|
|
+ IterativeLinearSolver *ils = new ILSConjugateGradients();
|
|
|
+
|
|
|
+
|
|
|
+ for ( map<uint, NICE::Vector>::const_iterator i = _binLabels.begin();
|
|
|
+ i != _binLabels.end(); i++ )
|
|
|
+ {
|
|
|
+ const Vector & y = i->second;
|
|
|
+ Vector alpha;
|
|
|
+ ils->solveLin( gm, y, alpha );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ delete ils;
|
|
|
+
|
|
|
+ t.stop();
|
|
|
+ if ( this->b_verbose )
|
|
|
+ std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ this->b_isTrained = true;
|
|
|
+
|
|
|
+
|
|
|
+ if ( this->b_verbose )
|
|
|
+ std::cerr << "Learning finished" << std::endl;
|
|
|
+}
|
|
|
+
|
|
|
+
|