SHOGUN
v3.2.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 #include <shogun/lib/config.h> 00015 00016 #ifdef USE_GLPK 00017 #include <glpk.h> 00018 #endif 00019 00020 #ifdef USE_CPLEX 00021 extern "C" { 00022 #include <ilcplex/cplex.h> 00023 } 00024 #endif 00025 00026 #include <shogun/lib/common.h> 00027 #include <shogun/lib/Time.h> 00028 #include <shogun/features/Features.h> 00029 #include <shogun/kernel/Kernel.h> 00030 #include <shogun/classifier/svm/SVM.h> 00031 00032 namespace shogun 00033 { 00095 class CMKL : public CSVM 00096 { 00097 public: 00102 CMKL(CSVM* s=NULL); 00103 00106 virtual ~CMKL(); 00107 00112 inline void set_constraint_generator(CSVM* s) 00113 { 00114 set_svm(s); 00115 } 00116 00121 inline void set_svm(CSVM* s) 00122 { 00123 SG_REF(s); 00124 SG_UNREF(svm); 00125 svm=s; 00126 } 00127 00132 inline CSVM* get_svm() 00133 { 00134 SG_REF(svm); 00135 return svm; 00136 } 00137 00142 inline void set_C_mkl(float64_t C) { C_mkl = C; } 00143 00148 void set_mkl_norm(float64_t norm); 00149 00156 void set_elasticnet_lambda(float64_t elasticnet_lambda); 00157 00162 void set_mkl_block_norm(float64_t q); 00163 00169 inline void set_interleaved_optimization_enabled(bool enable) 00170 { 00171 interleaved_optimization=enable; 00172 } 00173 00178 inline bool get_interleaved_optimization_enabled() 00179 { 00180 return interleaved_optimization; 00181 } 00182 00187 inline float64_t compute_mkl_primal_objective() 00188 { 00189 return compute_svm_primal_objective(); 00190 } 00191 00196 virtual float64_t compute_mkl_dual_objective(); 00197 00198 00203 float64_t compute_elasticnet_dual_objective(); 00204 00209 inline void set_mkl_epsilon(float64_t eps) { mkl_epsilon=eps; } 00210 00215 inline float64_t get_mkl_epsilon() { return mkl_epsilon; } 00216 00221 inline int32_t get_mkl_iterations() { return mkl_iterations; } 00222 00233 virtual bool perform_mkl_step(const float64_t* sumw, float64_t suma); 00234 00241 static bool perform_mkl_step_helper (CMKL* mkl, 00242 const float64_t* sumw, const float64_t suma) 00243 { 00244 return mkl->perform_mkl_step(sumw, suma); 00245 } 00246 00247 00251 virtual float64_t compute_sum_alpha()=0; 00252 00257 virtual void compute_sum_beta(float64_t* sumw); 00258 00260 virtual const char* get_name() const { return "MKL"; } 00261 00262 protected: 00271 virtual bool train_machine(CFeatures* data=NULL); 00272 00276 virtual void init_training()=0; 00277 00293 void perform_mkl_step(float64_t* beta, float64_t* old_beta, int num_kernels, 00294 int32_t* label, int32_t* active2dnum, 00295 float64_t* a, float64_t* lin, float64_t* sumw, int32_t& inner_iters); 00296 00297 00311 float64_t compute_optimal_betas_via_cplex(float64_t* beta, const float64_t* old_beta, int32_t num_kernels, 00312 const float64_t* sumw, float64_t suma, int32_t& inner_iters); 00313 00326 float64_t compute_optimal_betas_via_glpk(float64_t* beta, const float64_t* old_beta, 00327 int num_kernels, const float64_t* sumw, float64_t suma, int32_t& inner_iters); 00328 00340 float64_t compute_optimal_betas_elasticnet( 00341 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels, 00342 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective); 00343 00345 inline void elasticnet_transform(float64_t *beta, float64_t lmd, int32_t len) 00346 { 00347 for (int32_t i=0;i <len;i++) 00348 beta[i]=beta[i]/(1.0-lmd+lmd*beta[i]); 00349 } 00350 00352 void elasticnet_dual(float64_t *ff, float64_t *gg, float64_t *hh, 00353 const float64_t &del, const float64_t* nm, int32_t len, 00354 const float64_t &lambda); 00355 00367 float64_t compute_optimal_betas_directly( 00368 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels, 00369 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective); 00370 00382 float64_t compute_optimal_betas_block_norm( 00383 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels, 00384 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective); 00385 00397 float64_t compute_optimal_betas_newton(float64_t* beta, const float64_t* old_beta, 00398 int32_t num_kernels, const float64_t* sumw, float64_t suma, float64_t mkl_objective); 00399 00404 virtual bool converged() 00405 { 00406 return w_gap<mkl_epsilon; 00407 } 00408 00410 void init_solver(); 00411 00412 #ifdef USE_CPLEX 00413 00417 bool init_cplex(); 00418 00420 void set_qnorm_constraints(float64_t* beta, int32_t num_kernels); 00421 00426 bool cleanup_cplex(); 00427 #endif 00428 00429 #ifdef USE_GLPK 00430 00434 bool init_glpk(); 00435 00440 bool cleanup_glpk(); 00441 00446 bool check_glp_status(glp_prob *lp); 00447 #endif 00448 00449 protected: 00451 CSVM* svm; 00453 float64_t C_mkl; 00455 float64_t mkl_norm; 00461 float64_t ent_lambda; 00462 00465 float64_t mkl_block_norm; 00466 00468 float64_t* beta_local; 00470 int32_t mkl_iterations; 00472 float64_t mkl_epsilon; 00474 bool interleaved_optimization; 00475 00477 float64_t* W; 00478 00480 float64_t w_gap; 00482 float64_t rho; 00483 00485 CTime training_time_clock; 00486 00487 #ifdef USE_CPLEX 00488 00489 CPXENVptr env; 00491 CPXLPptr lp_cplex; 00492 #endif 00493 00494 #ifdef USE_GLPK 00495 00496 glp_prob* lp_glpk; 00497 00499 glp_smcp* lp_glpk_parm; 00500 #endif 00501 00502 bool lp_initialized ; 00503 }; 00504 } 00505 #endif //__MKL_H__