[pktools] 291/375: working on pkfssvm, linker error
Bas Couwenberg
sebastic at xs4all.nl
Wed Dec 3 21:54:23 UTC 2014
This is an automated email from the git hooks/post-receive script.
sebastic-guest pushed a commit to branch upstream-master
in repository pktools.
commit a9fa5019faa5f818e34713f13426e0dbc4f49b5b
Author: user <user at osgeolive.(none)>
Date: Mon Jun 23 21:18:21 2014 +0200
working on pkfssvm, linker error
---
src/algorithms/FeatureSelector.h | 59 ++++++-----
src/algorithms/Makefile.am | 2 +-
src/apps/Makefile.am | 13 +--
src/apps/pkfssvm.cc | 204 +++++++++++++++++++++++----------------
4 files changed, 163 insertions(+), 115 deletions(-)
diff --git a/src/algorithms/FeatureSelector.h b/src/algorithms/FeatureSelector.h
index 0b6f2bb..5c0e596 100644
--- a/src/algorithms/FeatureSelector.h
+++ b/src/algorithms/FeatureSelector.h
@@ -30,25 +30,34 @@ along with pktools. If not, see <http://www.gnu.org/licenses/>.
#include "base/IndexValue.h"
#include "base/Vector2d.h"
#include "gsl/gsl_combination.h"
+#include "CostFactory.h"
class FeatureSelector
{
public:
FeatureSelector(){};
~FeatureSelector(){};
- template<class T> double forwardUnivariate(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures, short verbose=0);
- template<class T> double forward(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures, short verbose=0);
- template<class T> double backward(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int minFeatures, short verbose=0);
- template<class T> double floating(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures=0, double epsilon=0.001, short verbose=0);
- template<class T> double bruteForce(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures=0, short verbose=0);
+ template<class T> double forward(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures, short verbose=0);
+ template<class T> double backward(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int minFeatures, short verbose=0);
+ template<class T> double floating(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures=0, double epsilon=0.001, short verbose=0);
+ template<class T> double bruteForce(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures=0, short verbose=0);
private:
- template<class T> double addFeature(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, short verbose=0);
- template<class T> double removeFeature(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int& r, short verbose=0);
+ template<class T> double addFeature(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, short verbose=0);
+ template<class T> double removeFeature(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int& r, short verbose=0);
+ template<class T> double forwardUnivariate(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures, short verbose=0);
+ /* template<class T> double forward(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures, short verbose=0); */
+ /* template<class T> double backward(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int minFeatures, short verbose=0); */
+ /* template<class T> double floating(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures=0, double epsilon=0.001, short verbose=0); */
+ /* template<class T> double bruteForce(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures=0, short verbose=0); */
+
+ /* private: */
+ /* template<class T> double addFeature(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, short verbose=0); */
+ /* template<class T> double removeFeature(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int& r, short verbose=0); */
};
//sequential forward selection Univariate (N single best features)
-template<class T> double FeatureSelector::forwardUnivariate(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures=0, short verbose){
+template<class T> double FeatureSelector::forwardUnivariate(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures=0, short verbose){
int maxLevels=v[0][0].size();
if(!maxFeatures)
maxFeatures=maxLevels;
@@ -68,7 +77,7 @@ template<class T> double FeatureSelector::forwardUnivariate(std::vector< Vector2
try{
IndexValue pv;
pv.position=ilevel;
- pv.value=getCost(tmp);
+ pv.value=theCostFactory.getCost(tmp);
cost[ilevel]=pv;
}
catch(...){
@@ -96,7 +105,7 @@ template<class T> double FeatureSelector::forwardUnivariate(std::vector< Vector2
v[iclass].selectCols(subset,tmp[iclass]);
}
try{
- maxCost=getCost(tmp);
+ maxCost=theCostFactory.getCost(tmp);
}
catch(...){
subset.pop_back();
@@ -107,14 +116,14 @@ template<class T> double FeatureSelector::forwardUnivariate(std::vector< Vector2
}
//sequential forward selection Multivariate (Combination of N best features)
-template<class T> double FeatureSelector::forward(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures=0, short verbose){
+template<class T> double FeatureSelector::forward(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures=0, short verbose){
//Select feature with the best value (get maximal cost for 1 feature)
double maxCost=0;
int maxLevels=v[0][0].size();
if(!maxFeatures)
maxFeatures=maxLevels;
while(subset.size()<maxFeatures){
- maxCost=addFeature(v,*getCost,subset,verbose);
+ maxCost=addFeature(v,theCostFactory,subset,verbose);
if(verbose){
for(std::list<int>::const_iterator lit=subset.begin();lit!=subset.end();++lit)
std::cout << *lit << " ";
@@ -126,7 +135,7 @@ template<class T> double FeatureSelector::forward(std::vector< Vector2d<T> >& v,
}
//sequential backward selection
-template<class T> double FeatureSelector::backward(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int minFeatures, short verbose){
+template<class T> double FeatureSelector::backward(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int minFeatures, short verbose){
//Select features with least effect on cost when removed (obtain minFeatures eventually)
double maxCost=0;
int removedFeature;
@@ -135,9 +144,9 @@ template<class T> double FeatureSelector::backward(std::vector< Vector2d<T> >& v
subset.push_back(iFeature);
}
if(subset.size()==minFeatures)
- maxCost=getCost(v);
+ maxCost=theCostFactory.getCost(v);
while(subset.size()>minFeatures){
- maxCost=removeFeature(v,*getCost,subset,removedFeature,verbose);
+ maxCost=removeFeature(v,theCostFactory,subset,removedFeature,verbose);
if(verbose){
for(std::list<int>::const_iterator lit=subset.begin();lit!=subset.end();++lit)
std::cout << *lit << " ";
@@ -149,7 +158,7 @@ template<class T> double FeatureSelector::backward(std::vector< Vector2d<T> >& v
}
//floating search
-template<class T> double FeatureSelector::floating(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures, double epsilon, short verbose){
+template<class T> double FeatureSelector::floating(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures, double epsilon, short verbose){
std::vector<T> cost;
int maxLevels=v[0][0].size();
if(maxFeatures<1)
@@ -159,7 +168,7 @@ template<class T> double FeatureSelector::floating(std::vector< Vector2d<T> >& v
return -1;
while(cost.size()<subset.size())
cost.push_back(1);//init original features as cost 1
- cost.push_back(addFeature(v,*getCost,subset,verbose));
+ cost.push_back(addFeature(v,theCostFactory,subset,verbose));
++k;
if(verbose>1)
std::cout << "added " << subset.back() << ", " << subset.size() << "/" << maxFeatures << " features selected with cost: " << cost.back() << std::endl;
@@ -169,7 +178,7 @@ template<class T> double FeatureSelector::floating(std::vector< Vector2d<T> >& v
std::cout << std::endl;
}
while(k<maxFeatures){
- cost.push_back(addFeature(v,*getCost,subset,verbose));
+ cost.push_back(addFeature(v,theCostFactory,subset,verbose));
++k;
if(verbose>1)
std::cout << "added " << subset.back() << ", " << subset.size() << "/" << maxFeatures << " features selected with cost: " << cost.back() << std::endl;
@@ -181,7 +190,7 @@ template<class T> double FeatureSelector::floating(std::vector< Vector2d<T> >& v
while(k>1){
int x_r;
- double cost_r=removeFeature(v,*getCost,subset,x_r,verbose);
+ double cost_r=removeFeature(v,theCostFactory,subset,x_r,verbose);
if(cost_r>cost[k-1]+epsilon){
--k;
cost[k]=cost_r;
@@ -208,7 +217,7 @@ template<class T> double FeatureSelector::floating(std::vector< Vector2d<T> >& v
}
//brute force search (search for all possible combinations and select best)
-template<class T> double FeatureSelector::bruteForce(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int maxFeatures, short verbose){
+template<class T> double FeatureSelector::bruteForce(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int maxFeatures, short verbose){
int maxLevels=v[0][0].size();
if(maxFeatures<1)
maxFeatures=maxLevels;
@@ -234,7 +243,7 @@ template<class T> double FeatureSelector::bruteForce(std::vector< Vector2d<T> >&
for(int iclass=0;iclass<v.size();++iclass)
v[iclass].selectCols(tmpset,tmpv[iclass]);
try{
- cost=getCost(tmpv);
+ cost=theCostFactory.getCost(tmpv);
}
catch(...){ //singular matrix encountered
catchset=tmpset;//this tmpset resulted in failure of getCost
@@ -264,7 +273,7 @@ template<class T> double FeatureSelector::bruteForce(std::vector< Vector2d<T> >&
return maxCost;
}
-template<class T> double FeatureSelector::addFeature(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, short verbose){
+template<class T> double FeatureSelector::addFeature(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, short verbose){
//select feature with the best value (get maximal cost for 1 feature)
std::list<int> tmpset=subset;//temporary set of selected features (levels)
std::vector< Vector2d<T> > tmp(v.size());
@@ -284,7 +293,7 @@ template<class T> double FeatureSelector::addFeature(std::vector< Vector2d<T> >&
v[iclass].selectCols(tmpset,tmp[iclass]);
}
try{
- cost=getCost(tmp);
+ cost=theCostFactory.getCost(tmp);
}
catch(...){
catchset=tmpset;//this tmpset resulted in singular matrix
@@ -309,7 +318,7 @@ template<class T> double FeatureSelector::addFeature(std::vector< Vector2d<T> >&
return maxCost;
}
-template<class T> double FeatureSelector::removeFeature(std::vector< Vector2d<T> >& v, double (*getCost)(const std::vector< Vector2d<T> >&), std::list<int>& subset, int& r, short verbose){
+template<class T> double FeatureSelector::removeFeature(std::vector< Vector2d<T> >& v, CostFactory& theCostFactory, std::list<int>& subset, int& r, short verbose){
//find the feature that has the least effect on the cost when it is removed from subset
std::list<int> tmpset=subset;//temporary set of selected features (levels)
std::vector< Vector2d<T> > tmp(v.size());
@@ -332,7 +341,7 @@ template<class T> double FeatureSelector::removeFeature(std::vector< Vector2d<T>
v[iclass].selectCols(tmpset,tmp[iclass]);
}
try{
- cost=getCost(tmp);
+ cost=theCostFactory.getCost(tmp);
}
catch(...){
catchset=tmpset;//this tmpset resulted in singular matrix
diff --git a/src/algorithms/Makefile.am b/src/algorithms/Makefile.am
index f06c8ff..ab568ab 100644
--- a/src/algorithms/Makefile.am
+++ b/src/algorithms/Makefile.am
@@ -25,7 +25,7 @@ libalgorithms_ladir = $(includedir)/pktools/algorithms
libalgorithms_la_LDFLAGS = -version-info $(PKTOOLS_SO_VERSION) $(AM_LDFLAGS)
# the list of header files that belong to the library (to be installed later)
-libalgorithms_la_HEADERS = Egcs.h Filter2d.h Filter.h StatFactory.h ConfusionMatrix.h svm.h FeatureSelector.h
+libalgorithms_la_HEADERS = Egcs.h Filter2d.h Filter.h StatFactory.h ConfusionMatrix.h svm.h CostFactory.h FeatureSelector.h
if USE_FANN
libalgorithms_la_HEADERS += myfann_cpp.h
diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
index 1d4875e..b0b0d47 100644
--- a/src/apps/Makefile.am
+++ b/src/apps/Makefile.am
@@ -12,13 +12,14 @@ bin_PROGRAMS = pkinfo pkcrop pkreclass pkgetmask pksetmask pkcreatect pkdumpimg
#noinst_PROGRAMS = pkxcorimg pkgeom
if USE_FANN
-bin_PROGRAMS += pkann pkfsann pkregann
+#bin_PROGRAMS += pkann pkfsann pkregann
+bin_PROGRAMS += pkann pkregann
pkann_SOURCES = $(top_srcdir)/src/algorithms/myfann_cpp.h pkann.cc
pkann_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/base $(FANN_CFLAGS) -I$(top_srcdir)/src/algorithms $(AM_CXXFLAGS)
pkann_LDADD = $(FANN_LIBS) $(FANN_CFLAGS) $(AM_LDFLAGS)
-pkfsann_SOURCES = $(top_srcdir)/src/algorithms/myfann_cpp.h pkfsann.cc
-pkfsann_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/base $(FANN_CFLAGS) -I$(top_srcdir)/src/algorithms $(AM_CXXFLAGS)
-pkfsann_LDADD = $(GSL_LIBS) $(FANN_LIBS) $(FANN_CFLAGS) $(AM_LDFLAGS)
+#pkfsann_SOURCES = $(top_srcdir)/src/algorithms/myfann_cpp.h pkfsann.cc
+#pkfsann_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/base $(FANN_CFLAGS) -I$(top_srcdir)/src/algorithms $(AM_CXXFLAGS)
+#pkfsann_LDADD = $(GSL_LIBS) $(FANN_LIBS) $(FANN_CFLAGS) $(AM_LDFLAGS)
pkregann_SOURCES = $(top_srcdir)/src/algorithms/myfann_cpp.h pkregann.cc
pkregann_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/base $(FANN_CFLAGS) -I$(top_srcdir)/src/algorithms $(AM_CXXFLAGS)
pkregann_LDADD = $(GSL_LIBS) $(FANN_LIBS) $(FANN_CFLAGS) $(AM_LDFLAGS)
@@ -65,8 +66,8 @@ pkcomposite_SOURCES = pkcomposite.cc
pkndvi_SOURCES = pkndvi.cc
pkpolygonize_SOURCES = pkpolygonize.cc
pksvm_SOURCES = $(top_srcdir)/src/algorithms/svm.h $(top_srcdir)/src/algorithms/svm.cpp pksvm.cc
-pkfssvm_SOURCES = $(top_srcdir)/src/algorithms/svm.h $(top_srcdir)/src/algorithms/svm.cpp pkfssvm.cc
-pkfssvm_LDADD = $(GSL_LIBS) $(AM_LDFLAGS)
+pkfssvm_SOURCES = $(top_srcdir)/src/algorithms/svm.h $(top_srcdir)/src/algorithms/FeatureSelector.h $(top_srcdir)/src/algorithms/CostFactory.h $(top_srcdir)/src/algorithms/svm.cpp pkfssvm.cc
+pkfssvm_LDADD = -lalgorithms $(GSL_LIBS) $(AM_LDFLAGS) -lalgorithms
pkascii2img_SOURCES = pkascii2img.cc
pkascii2ogr_SOURCES = pkascii2ogr.cc
pkeditogr_SOURCES = pkeditogr.cc
diff --git a/src/apps/pkfssvm.cc b/src/apps/pkfssvm.cc
index 3b2dff0..20818b1 100644
--- a/src/apps/pkfssvm.cc
+++ b/src/apps/pkfssvm.cc
@@ -24,6 +24,7 @@ along with pktools. If not, see <http://www.gnu.org/licenses/>.
#include <algorithm>
#include "base/Optionpk.h"
#include "algorithms/ConfusionMatrix.h"
+#include "algorithms/CostFactory.h"
#include "algorithms/FeatureSelector.h"
#include "algorithms/svm.h"
#include "imageclasses/ImgReaderOgr.h"
@@ -43,31 +44,40 @@ using namespace std;
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
+class CostFactorySVM : public CostFactory
+{
+public:
+ CostFactorySVM()
+ : CostFactory(2,0), m_svm_type("C_SVC"), m_kernel_type("radial"), m_kernel_degree(3), m_gamma(1.0), m_coef0(0), m_ccost(1000), m_nu(0.5), m_epsilon_loss(100), m_cache(100), m_epsilon_tol(0.001), m_shrinking(false), m_prob_est(true){};
+ // ~CostFactorySVM(){};
+ CostFactorySVM(std::string svm_type, std::string kernel_type, unsigned short kernel_degree, float gamma, float coef0, float ccost, float nu, float epsilon_loss, int cache, float epsilon_tol, bool shrinking, bool prob_est, unsigned short cv, bool verbose)
+ : CostFactory(cv,verbose), m_svm_type(svm_type), m_kernel_type(kernel_type), m_kernel_degree(kernel_degree), m_gamma(gamma), m_coef0(coef0), m_ccost(ccost), m_nu(nu), m_epsilon_loss(epsilon_loss), m_cache(cache), m_epsilon_tol(epsilon_tol), m_shrinking(shrinking), m_prob_est(prob_est){};
+ ~CostFactorySVM();
+ double getCost(const vector<Vector2d<float> > &trainingFeatures);
+
+private:
+ string m_svm_type;
+ string m_kernel_type;
+ unsigned short m_kernel_degree;
+ float m_gamma;
+ float m_coef0;
+ float m_ccost;
+ float m_nu;
+ float m_epsilon_loss;
+ int m_cache;
+ float m_epsilon_tol;
+ bool m_shrinking;
+ bool m_prob_est;
+};
+
//global parameters used in cost function getCost
-ConfusionMatrix cm;
-map<string,short> classValueMap;
-vector<std::string> nameVector;
-vector<unsigned int> nctraining;
-vector<unsigned int> nctest;
-Optionpk<std::string> svm_type_opt("svmt", "svmtype", "type of SVM (C_SVC, nu_SVC,one_class, epsilon_SVR, nu_SVR)","C_SVC");
-Optionpk<std::string> kernel_type_opt("kt", "kerneltype", "type of kernel function (linear,polynomial,radial,sigmoid) ","radial");
-Optionpk<unsigned short> kernel_degree_opt("kd", "kd", "degree in kernel function",3);
-Optionpk<float> gamma_opt("g", "gamma", "gamma in kernel function",1.0);
-Optionpk<float> coef0_opt("c0", "coef0", "coef0 in kernel function",0);
-Optionpk<float> ccost_opt("cc", "ccost", "the parameter C of C-SVC, epsilon-SVR, and nu-SVR",1000);
-Optionpk<float> nu_opt("nu", "nu", "the parameter nu of nu-SVC, one-class SVM, and nu-SVR",0.5);
-Optionpk<float> epsilon_loss_opt("eloss", "eloss", "the epsilon in loss function of epsilon-SVR",0.1);
-Optionpk<int> cache_opt("cache", "cache", "cache memory size in MB",100);
-Optionpk<float> epsilon_tol_opt("etol", "etol", "the tolerance of termination criterion",0.001);
-Optionpk<bool> shrinking_opt("shrink", "shrink", "whether to use the shrinking heuristics",false);
-Optionpk<bool> prob_est_opt("pe", "probest", "whether to train a SVC or SVR model for probability estimates",true,2);
-// Optionpk<bool> weight_opt("wi", "wi", "set the parameter C of class i to weight*C, for C-SVC",true);
-Optionpk<unsigned short> cv_opt("cv", "cv", "n-fold cross validation mode",2);
-Optionpk<string> classname_opt("c", "class", "list of class names.");
-Optionpk<short> classvalue_opt("r", "reclass", "list of class values (use same order as in classname opt.");
-Optionpk<short> verbose_opt("v", "verbose", "set to: 0 (results only), 1 (confusion matrix), 2 (debug)",0);
-
-double getCost(const vector<Vector2d<float> > &trainingFeatures)
+// ConfusionMatrix cm;
+// map<string,short> classValueMap;
+// vector<std::string> nameVector;
+// vector<unsigned int> nctraining;
+// vector<unsigned int> nctest;
+
+double CostFactorySVM::getCost(const vector<Vector2d<float> > &trainingFeatures)
{
std::map<std::string, svm::SVM_TYPE> svmMap;
@@ -88,32 +98,32 @@ double getCost(const vector<Vector2d<float> > &trainingFeatures)
unsigned int ntraining=0;
unsigned int ntest=0;
for(int iclass=0;iclass<nclass;++iclass){
- ntraining+=nctraining[iclass];
- ntest+=nctest[iclass];
+ ntraining+=m_nctraining[iclass];
+ ntest+=m_nctest[iclass];
}
if(ntest)
- assert(!cv_opt[0]);
- if(!cv_opt[0])
+ assert(!m_cv);
+ if(!m_cv)
assert(ntest);
unsigned short nFeatures=trainingFeatures[0][0].size();
struct svm_parameter param;
- param.svm_type = svmMap[svm_type_opt[0]];
- param.kernel_type = kernelMap[kernel_type_opt[0]];
- param.degree = kernel_degree_opt[0];
- param.gamma = (gamma_opt[0]>0)? gamma_opt[0] : 1.0/nFeatures;
- param.coef0 = coef0_opt[0];
- param.nu = nu_opt[0];
- param.cache_size = cache_opt[0];
- param.C = ccost_opt[0];
- param.eps = epsilon_tol_opt[0];
- param.p = epsilon_loss_opt[0];
- param.shrinking = (shrinking_opt[0])? 1 : 0;
- param.probability = (prob_est_opt[0])? 1 : 0;
+ param.svm_type = svmMap[m_svm_type];
+ param.kernel_type = kernelMap[m_kernel_type];
+ param.degree = m_kernel_degree;
+ param.gamma = (m_gamma>0)? m_gamma : 1.0/nFeatures;
+ param.coef0 = m_coef0;
+ param.nu = m_nu;
+ param.cache_size = m_cache;
+ param.C = m_ccost;
+ param.eps = m_epsilon_tol;
+ param.p = m_epsilon_loss;
+ param.shrinking = (m_shrinking)? 1 : 0;
+ param.probability = (m_prob_est)? 1 : 0;
param.nr_weight = 0;//not used: I use priors and balancing
param.weight_label = NULL;
param.weight = NULL;
- param.verbose=(verbose_opt[0]>1)? true:false;
+ param.verbose=(m_verbose>1)? true:false;
struct svm_model* svm;
struct svm_problem prob;
struct svm_node* x_space;
@@ -126,7 +136,7 @@ double getCost(const vector<Vector2d<float> > &trainingFeatures)
int lIndex=0;
for(int iclass=0;iclass<nclass;++iclass){
// for(int isample=0;isample<trainingFeatures[iclass].size();++isample){
- for(int isample=0;isample<nctraining[iclass];++isample){
+ for(int isample=0;isample<m_nctraining[iclass];++isample){
prob.x[lIndex]=&(x_space[spaceIndex]);
for(int ifeature=0;ifeature<nFeatures;++ifeature){
x_space[spaceIndex].index=ifeature+1;
@@ -140,26 +150,26 @@ double getCost(const vector<Vector2d<float> > &trainingFeatures)
}
assert(lIndex==prob.l);
- if(verbose_opt[0]>2)
+ if(m_verbose>2)
std::cout << "checking parameters" << std::endl;
svm_check_parameter(&prob,¶m);
- if(verbose_opt[0]>2)
+ if(m_verbose>2)
std::cout << "parameters ok, training" << std::endl;
svm=svm_train(&prob,¶m);
- if(verbose_opt[0]>2)
+ if(m_verbose>2)
std::cout << "SVM is now trained" << std::endl;
- if(cv_opt[0]>1){
+ if(m_cv>1){
double *target = Malloc(double,prob.l);
- svm_cross_validation(&prob,¶m,cv_opt[0],target);
+ svm_cross_validation(&prob,¶m,m_cv,target);
assert(param.svm_type != EPSILON_SVR&¶m.svm_type != NU_SVR);//only for regression
for(int i=0;i<prob.l;i++){
- string refClassName=nameVector[prob.y[i]];
- string className=nameVector[target[i]];
- if(classValueMap.size())
- cm.incrementResult(type2string<short>(classValueMap[refClassName]),type2string<short>(classValueMap[className]),1.0);
+ string refClassName=m_nameVector[prob.y[i]];
+ string className=m_nameVector[target[i]];
+ if(m_classValueMap.size())
+ m_cm.incrementResult(type2string<short>(m_classValueMap[refClassName]),type2string<short>(m_classValueMap[className]),1.0);
else
- cm.incrementResult(cm.getClass(prob.y[i]),cm.getClass(target[i]),1.0);
+ m_cm.incrementResult(m_cm.getClass(prob.y[i]),m_cm.getClass(target[i]),1.0);
}
free(target);
}
@@ -168,35 +178,35 @@ double getCost(const vector<Vector2d<float> > &trainingFeatures)
vector<double> result(nclass);
x_test = Malloc(struct svm_node,(nFeatures+1));
for(int iclass=0;iclass<nclass;++iclass){
- for(int isample=0;isample<nctest[iclass];++isample){
+ for(int isample=0;isample<m_nctest[iclass];++isample){
for(int ifeature=0;ifeature<nFeatures;++ifeature){
x_test[ifeature].index=ifeature+1;
- x_test[ifeature].value=trainingFeatures[iclass][nctraining[iclass]+isample][ifeature];
+ x_test[ifeature].value=trainingFeatures[iclass][m_nctraining[iclass]+isample][ifeature];
}
x_test[nFeatures].index=-1;
double predict_label=0;
assert(svm_check_probability_model(svm));
predict_label = svm_predict_probability(svm,x_test,&(result[0]));
// predict_label = svm_predict(svm,x_test);
- string refClassName=nameVector[iclass];
- string className=nameVector[static_cast<short>(predict_label)];
- if(classValueMap.size())
- cm.incrementResult(type2string<short>(classValueMap[refClassName]),type2string<short>(classValueMap[className]),1.0);
+ string refClassName=m_nameVector[iclass];
+ string className=m_nameVector[static_cast<short>(predict_label)];
+ if(m_classValueMap.size())
+ m_cm.incrementResult(type2string<short>(m_classValueMap[refClassName]),type2string<short>(m_classValueMap[className]),1.0);
else
- cm.incrementResult(refClassName,className,1.0);
+ m_cm.incrementResult(refClassName,className,1.0);
}
}
free(x_test);
}
- if(verbose_opt[0]>1)
- std::cout << cm << std::endl;
- assert(cm.nReference());
- // if(verbose_opt[0])
- // std::cout << cm << std::endl;
- // std::cout << "Kappa: " << cm.kappa() << std::endl;
+ if(m_verbose>1)
+ std::cout << m_cm << std::endl;
+ assert(m_cm.nReference());
+ // if(m_verbose)
+ // std::cout << m_cm << std::endl;
+ // std::cout << "Kappa: " << m_cm.kappa() << std::endl;
// double se95_oa=0;
// double doa=0;
- // doa=cm.oa_pct(&se95_oa);
+ // doa=m_cm.oa_pct(&se95_oa);
// std::cout << "Overall Accuracy: " << doa << " (" << se95_oa << ")" << std::endl;
// *NOTE* Because svm_model contains pointers to svm_problem, you can
@@ -208,7 +218,7 @@ double getCost(const vector<Vector2d<float> > &trainingFeatures)
free(x_space);
svm_free_and_destroy_model(&(svm));
- return(cm.kappa());
+ return(m_cm.kappa());
}
int main(int argc, char *argv[])
@@ -232,6 +242,23 @@ int main(int argc, char *argv[])
Optionpk<string> selector_opt("sm", "sm", "feature selection method (sffs=sequential floating forward search,sfs=sequential forward search, sbs, sequential backward search ,bfs=brute force search)","sffs");
Optionpk<float> epsilon_cost_opt("ecost", "ecost", "epsilon for stopping criterion in cost function to determine optimal number of features",0.001);
+ Optionpk<std::string> svm_type_opt("svmt", "svmtype", "type of SVM (C_SVC, nu_SVC,one_class, epsilon_SVR, nu_SVR)","C_SVC");
+ Optionpk<std::string> kernel_type_opt("kt", "kerneltype", "type of kernel function (linear,polynomial,radial,sigmoid) ","radial");
+ Optionpk<unsigned short> kernel_degree_opt("kd", "kd", "degree in kernel function",3);
+ Optionpk<float> gamma_opt("g", "gamma", "gamma in kernel function",1.0);
+ Optionpk<float> coef0_opt("c0", "coef0", "coef0 in kernel function",0);
+ Optionpk<float> ccost_opt("cc", "ccost", "the parameter C of C-SVC, epsilon-SVR, and nu-SVR",1000);
+ Optionpk<float> nu_opt("nu", "nu", "the parameter nu of nu-SVC, one-class SVM, and nu-SVR",0.5);
+ Optionpk<float> epsilon_loss_opt("eloss", "eloss", "the epsilon in loss function of epsilon-SVR",0.1);
+ Optionpk<int> cache_opt("cache", "cache", "cache memory size in MB",100);
+ Optionpk<float> epsilon_tol_opt("etol", "etol", "the tolerance of termination criterion",0.001);
+ Optionpk<bool> shrinking_opt("shrink", "shrink", "whether to use the shrinking heuristics",false);
+ Optionpk<bool> prob_est_opt("pe", "probest", "whether to train a SVC or SVR model for probability estimates",true,2);
+ Optionpk<unsigned short> cv_opt("cv", "cv", "n-fold cross validation mode",2);
+ Optionpk<string> classname_opt("c", "class", "list of class names.");
+ Optionpk<short> classvalue_opt("r", "reclass", "list of class values (use same order as in classname opt.");
+ Optionpk<short> verbose_opt("v", "verbose", "set to: 0 (results only), 1 (confusion matrix), 2 (debug)",0);
+
bool doProcess;//stop process when program was invoked with help option (-h --help)
try{
doProcess=input_opt.retrieveOption(argc,argv);
@@ -276,10 +303,11 @@ int main(int argc, char *argv[])
exit(0);//help was invoked, stop processing
}
+ CostFactorySVM costfactory(svm_type_opt[0], kernel_type_opt[0], kernel_degree_opt[0], gamma_opt[0], coef0_opt[0], ccost_opt[0], nu_opt[0], epsilon_loss_opt[0], cache_opt[0], epsilon_tol_opt[0], shrinking_opt[0], prob_est_opt[0], cv_opt[0], verbose_opt[0]);
+
assert(training_opt.size());
if(input_opt.size())
- cv_opt[0]=0;
-
+ costfactory.setCv(0);
if(verbose_opt[0]>=1){
if(input_opt.size())
std::cout << "input filename: " << input_opt[0] << std::endl;
@@ -323,7 +351,7 @@ int main(int argc, char *argv[])
if(classname_opt.size()){
assert(classname_opt.size()==classvalue_opt.size());
for(int iclass=0;iclass<classname_opt.size();++iclass)
- classValueMap[classname_opt[iclass]]=classvalue_opt[iclass];
+ costfactory.setClassValueMap(classname_opt[iclass],classvalue_opt[iclass]);
}
//----------------------------------- Training -------------------------------
@@ -398,7 +426,7 @@ int main(int argc, char *argv[])
trainingMap.erase(mapit);
continue;
}
- nameVector.push_back(mapit->first);
+ costfactory.pushBackName(mapit->first);
trainingPixels.push_back(mapit->second);
if(verbose_opt[0]>1)
std::cout << mapit->first << ": " << (mapit->second).size() << " samples" << std::endl;
@@ -411,9 +439,10 @@ int main(int argc, char *argv[])
mapit=testMap.begin();
while(mapit!=testMap.end()){
- if(classValueMap.size()){
+ if(costfactory.getClassValueMap().size()){
+ // if(classValueMap.size()){
//check if name in test is covered by classname_opt (values can not be 0)
- if(classValueMap[mapit->first]>0){
+ if((costfactory.getClassValueMap())[mapit->first]>0){
;//ok, no need to print to std::cout
}
else{
@@ -510,11 +539,15 @@ int main(int argc, char *argv[])
}
//set names in confusion matrix using nameVector
+ vector<string> nameVector=costfactory.getNameVector();
for(int iname=0;iname<nameVector.size();++iname){
- if(classValueMap.empty())
- cm.pushBackClassName(nameVector[iname]);
- else if(cm.getClassIndex(type2string<short>(classValueMap[nameVector[iname]]))<0)
- cm.pushBackClassName(type2string<short>(classValueMap[nameVector[iname]]));
+ if(costfactory.getClassValueMap().empty())
+ costfactory.pushBackClassName(nameVector[iname]);
+ // cm.pushBackClassName(nameVector[iname]);
+ else if(costfactory.getClassIndex(type2string<short>((costfactory.getClassValueMap())[nameVector[iname]]))<0)
+ costfactory.pushBackClassName(type2string<short>((costfactory.getClassValueMap())[nameVector[iname]]));
+ // else if(cm.getClassIndex(type2string<short>((costfactory.getClassValueMap())[nameVector[iname]]))<0)
+ // cm.pushBackClassName(type2string<short>((costfactory.getClassValueMap())[nameVector[iname]]));
}
// // map<string,Vector2d<float> >::iterator mapit=trainingMap.begin();
@@ -554,6 +587,9 @@ int main(int argc, char *argv[])
// }
//Calculate features of training (and test) set
+
+ vector<unsigned int> nctraining;
+ vector<unsigned int> nctest;
nctraining.resize(nclass);
nctest.resize(nclass);
vector< Vector2d<float> > trainingFeatures(nclass);
@@ -598,7 +634,9 @@ int main(int argc, char *argv[])
}
assert(trainingFeatures[iclass].size()==nctraining[iclass]+nctest[iclass]);
}
-
+
+ costfactory.setNcTraining(nctraining);
+ costfactory.setNcTest(nctest);
int nFeatures=trainingFeatures[0][0].size();
int maxFeatures=(maxFeatures_opt[0])? maxFeatures_opt[0] : 1;
double previousCost=-1;
@@ -610,7 +648,7 @@ int main(int argc, char *argv[])
subset.clear();
for(int ifeature=0;ifeature<nFeatures;++ifeature)
subset.push_back(ifeature);
- cost=getCost(trainingFeatures);
+ cost=costfactory.getCost(trainingFeatures);
}
else{
while(fabs(cost-previousCost)>=epsilon_cost_opt[0]){
@@ -618,17 +656,17 @@ int main(int argc, char *argv[])
switch(selMap[selector_opt[0]]){
case(SFFS):
subset.clear();//needed to clear in case of floating and brute force search
- cost=selector.floating(trainingFeatures,&getCost,subset,maxFeatures,epsilon_cost_opt[0],verbose_opt[0]);
+ cost=selector.floating(trainingFeatures,costfactory,subset,maxFeatures,epsilon_cost_opt[0],verbose_opt[0]);
break;
case(SFS):
- cost=selector.forward(trainingFeatures,&getCost,subset,maxFeatures,verbose_opt[0]);
+ cost=selector.forward(trainingFeatures,costfactory,subset,maxFeatures,verbose_opt[0]);
break;
case(SBS):
- cost=selector.backward(trainingFeatures,&getCost,subset,maxFeatures,verbose_opt[0]);
+ cost=selector.backward(trainingFeatures,costfactory,subset,maxFeatures,verbose_opt[0]);
break;
case(BFS):
subset.clear();//needed to clear in case of floating and brute force search
- cost=selector.bruteForce(trainingFeatures,&getCost,subset,maxFeatures,verbose_opt[0]);
+ cost=selector.bruteForce(trainingFeatures,costfactory,subset,maxFeatures,verbose_opt[0]);
break;
default:
std::cout << "Error: selector not supported, please use sffs, sfs, sbs or bfs" << std::endl;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pktools.git
More information about the Pkg-grass-devel
mailing list