SHOGUN
v1.1.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2009 Soeren Sonnenburg 00008 * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 * Copyright (C) 2010 Ryota Tomioka (University of Tokyo) 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 inline 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__