00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __MKL_H__
00012 #define __MKL_H__
00013
00014 #ifdef USE_GLPK
00015 #include <glpk.h>
00016 #endif
00017
00018 #ifdef USE_CPLEX
00019 extern "C" {
00020 #include <ilcplex/cplex.h>
00021 }
00022 #endif
00023
00024 #include <shogun/lib/common.h>
00025 #include <shogun/lib/Time.h>
00026 #include <shogun/features/Features.h>
00027 #include <shogun/kernel/Kernel.h>
00028 #include <shogun/classifier/svm/SVM.h>
00029
00030 namespace shogun
00031 {
00093 class CMKL : public CSVM
00094 {
00095 public:
00100 CMKL(CSVM* s=NULL);
00101
00104 virtual ~CMKL();
00105
00110 inline void set_constraint_generator(CSVM* s)
00111 {
00112 set_svm(s);
00113 }
00114
00119 inline void set_svm(CSVM* s)
00120 {
00121 SG_REF(s);
00122 SG_UNREF(svm);
00123 svm=s;
00124 }
00125
00130 inline CSVM* get_svm()
00131 {
00132 SG_REF(svm);
00133 return svm;
00134 }
00135
00140 inline void set_C_mkl(float64_t C) { C_mkl = C; }
00141
00146 void set_mkl_norm(float64_t norm);
00147
00154 void set_elasticnet_lambda(float64_t elasticnet_lambda);
00155
00160 void set_mkl_block_norm(float64_t q);
00161
00167 inline void set_interleaved_optimization_enabled(bool enable)
00168 {
00169 interleaved_optimization=enable;
00170 }
00171
00176 inline bool get_interleaved_optimization_enabled()
00177 {
00178 return interleaved_optimization;
00179 }
00180
00185 inline float64_t compute_mkl_primal_objective()
00186 {
00187 return compute_svm_primal_objective();
00188 }
00189
00194 virtual float64_t compute_mkl_dual_objective();
00195
00196
00201 float64_t compute_elasticnet_dual_objective();
00202
00207 inline void set_mkl_epsilon(float64_t eps) { mkl_epsilon=eps; }
00208
00213 inline float64_t get_mkl_epsilon() { return mkl_epsilon; }
00214
00219 inline int32_t get_mkl_iterations() { return mkl_iterations; }
00220
00231 virtual bool perform_mkl_step(const float64_t* sumw, float64_t suma);
00232
00239 static bool perform_mkl_step_helper (CMKL* mkl,
00240 const float64_t* sumw, const float64_t suma)
00241 {
00242 return mkl->perform_mkl_step(sumw, suma);
00243 }
00244
00245
00249 virtual float64_t compute_sum_alpha()=0;
00250
00255 virtual void compute_sum_beta(float64_t* sumw);
00256
00258 virtual const char* get_name() const { return "MKL"; }
00259
00260 protected:
00269 virtual bool train_machine(CFeatures* data=NULL);
00270
00274 virtual void init_training()=0;
00275
00291 void perform_mkl_step(float64_t* beta, float64_t* old_beta, int num_kernels,
00292 int32_t* label, int32_t* active2dnum,
00293 float64_t* a, float64_t* lin, float64_t* sumw, int32_t& inner_iters);
00294
00295
00309 float64_t compute_optimal_betas_via_cplex(float64_t* beta, const float64_t* old_beta, int32_t num_kernels,
00310 const float64_t* sumw, float64_t suma, int32_t& inner_iters);
00311
00324 float64_t compute_optimal_betas_via_glpk(float64_t* beta, const float64_t* old_beta,
00325 int num_kernels, const float64_t* sumw, float64_t suma, int32_t& inner_iters);
00326
00338 float64_t compute_optimal_betas_elasticnet(
00339 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels,
00340 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective);
00341
00343 inline void elasticnet_transform(float64_t *beta, float64_t lmd, int32_t len)
00344 {
00345 for (int32_t i=0;i <len;i++)
00346 beta[i]=beta[i]/(1.0-lmd+lmd*beta[i]);
00347 }
00348
00350 void elasticnet_dual(float64_t *ff, float64_t *gg, float64_t *hh,
00351 const float64_t &del, const float64_t* nm, int32_t len,
00352 const float64_t &lambda);
00353
00365 float64_t compute_optimal_betas_directly(
00366 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels,
00367 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective);
00368
00380 float64_t compute_optimal_betas_block_norm(
00381 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels,
00382 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective);
00383
00395 float64_t compute_optimal_betas_newton(float64_t* beta, const float64_t* old_beta,
00396 int32_t num_kernels, const float64_t* sumw, float64_t suma, float64_t mkl_objective);
00397
00402 virtual bool converged()
00403 {
00404 return w_gap<mkl_epsilon;
00405 }
00406
00408 void init_solver();
00409
00410 #ifdef USE_CPLEX
00411
00415 bool init_cplex();
00416
00418 void set_qnorm_constraints(float64_t* beta, int32_t num_kernels);
00419
00424 bool cleanup_cplex();
00425 #endif
00426
00427 #ifdef USE_GLPK
00428
00432 bool init_glpk();
00433
00438 bool cleanup_glpk();
00439
00444 bool check_lpx_status(LPX *lp);
00445 #endif
00446
00447 protected:
00449 CSVM* svm;
00451 float64_t C_mkl;
00453 float64_t mkl_norm;
00459 float64_t ent_lambda;
00460
00463 float64_t mkl_block_norm;
00464
00466 float64_t* beta_local;
00468 int32_t mkl_iterations;
00470 float64_t mkl_epsilon;
00472 bool interleaved_optimization;
00473
00475 float64_t* W;
00476
00478 float64_t w_gap;
00480 float64_t rho;
00481
00483 CTime training_time_clock;
00484
00485 #ifdef USE_CPLEX
00486
00487 CPXENVptr env;
00489 CPXLPptr lp_cplex;
00490 #endif
00491
00492 #ifdef USE_GLPK
00493
00494 LPX* lp_glpk;
00495 #endif
00496
00497 bool lp_initialized ;
00498 };
00499 }
00500 #endif //__MKL_H__