SHOGUN v0.9.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 "lib/common.h" 00025 #include "features/Features.h" 00026 #include "kernel/Kernel.h" 00027 #include "classifier/svm/SVM.h" 00028 00029 namespace shogun 00030 { 00092 class CMKL : public CSVM 00093 { 00094 public: 00099 CMKL(CSVM* s=NULL); 00100 00103 virtual ~CMKL(); 00104 00109 inline void set_constraint_generator(CSVM* s) 00110 { 00111 set_svm(s); 00112 } 00113 00118 inline void set_svm(CSVM* s) 00119 { 00120 SG_REF(s); 00121 SG_UNREF(svm); 00122 svm=s; 00123 } 00124 00129 inline CSVM* get_svm() 00130 { 00131 SG_REF(svm); 00132 return svm; 00133 } 00134 00135 00144 virtual bool train(CFeatures* data=NULL); 00145 00150 inline void set_C_mkl(float64_t C) { C_mkl = C; } 00151 00156 void set_mkl_norm(float64_t norm); 00157 00164 void set_elasticnet_lambda(float64_t lambda); 00165 00171 inline void set_interleaved_optimization_enabled(bool enable) 00172 { 00173 interleaved_optimization=enable; 00174 } 00175 00180 inline bool get_interleaved_optimization_enabled() 00181 { 00182 return interleaved_optimization; 00183 } 00184 00189 inline float64_t compute_mkl_primal_objective() 00190 { 00191 return compute_svm_primal_objective(); 00192 } 00193 00198 virtual float64_t compute_mkl_dual_objective(); 00199 00200 00205 float64_t compute_elasticnet_dual_objective(); 00206 00211 inline void set_mkl_epsilon(float64_t eps) { mkl_epsilon=eps; } 00212 00217 inline float64_t get_mkl_epsilon() { return mkl_epsilon; } 00218 00223 inline int32_t get_mkl_iterations() { return mkl_iterations; } 00224 00235 virtual bool perform_mkl_step(const float64_t* sumw, float64_t suma); 00236 00243 static bool perform_mkl_step_helper (CMKL* mkl, 00244 const float64_t* sumw, const float64_t suma) 00245 { 00246 return mkl->perform_mkl_step(sumw, suma); 00247 } 00248 00249 00253 virtual float64_t compute_sum_alpha()=0; 00254 00259 virtual void compute_sum_beta(float64_t* sumw); 00260 00261 protected: 00265 virtual void init_training()=0; 00266 00282 void perform_mkl_step(float64_t* beta, float64_t* old_beta, int num_kernels, 00283 int32_t* label, int32_t* active2dnum, 00284 float64_t* a, float64_t* lin, float64_t* sumw, int32_t& inner_iters); 00285 00286 00300 float64_t compute_optimal_betas_via_cplex(float64_t* beta, const float64_t* old_beta, int32_t num_kernels, 00301 const float64_t* sumw, float64_t suma, int32_t& inner_iters); 00302 00315 float64_t compute_optimal_betas_via_glpk(float64_t* beta, const float64_t* old_beta, 00316 int num_kernels, const float64_t* sumw, float64_t suma, int32_t& inner_iters); 00317 00329 float64_t compute_optimal_betas_elasticnet( 00330 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels, 00331 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective); 00332 00334 inline void elasticnet_transform(float64_t *beta, float64_t lmd, int32_t len) 00335 { 00336 for (int32_t i=0;i <len;i++) 00337 beta[i]=beta[i]/(1.0-lmd+lmd*beta[i]); 00338 } 00339 00341 void elasticnet_dual(float64_t *ff, float64_t *gg, float64_t *hh, 00342 const float64_t &del, const float64_t* nm, int32_t len, 00343 const float64_t &lambda); 00344 00356 float64_t compute_optimal_betas_directly( 00357 float64_t* beta, const float64_t* old_beta, const int32_t num_kernels, 00358 const float64_t* sumw, const float64_t suma, const float64_t mkl_objective); 00359 00371 float64_t compute_optimal_betas_newton(float64_t* beta, const float64_t* old_beta, 00372 int32_t num_kernels, const float64_t* sumw, float64_t suma, float64_t mkl_objective); 00373 00378 virtual bool converged() 00379 { 00380 return w_gap<mkl_epsilon; 00381 } 00382 00384 void init_solver(); 00385 00386 #ifdef USE_CPLEX 00387 00391 bool init_cplex(); 00392 00394 void set_qnorm_constraints(float64_t* beta, int32_t num_kernels); 00395 00400 bool cleanup_cplex(); 00401 #endif 00402 00403 #ifdef USE_GLPK 00404 00408 bool init_glpk(); 00409 00414 bool cleanup_glpk(); 00415 00420 bool check_lpx_status(LPX *lp); 00421 #endif 00422 00424 inline virtual const char* get_name() const { return "MKL"; } 00425 00426 protected: 00428 CSVM* svm; 00430 float64_t C_mkl; 00432 float64_t mkl_norm; 00438 float64_t ent_lambda; 00439 00441 float64_t* beta_local; 00443 int32_t mkl_iterations; 00445 float64_t mkl_epsilon; 00447 bool interleaved_optimization; 00448 00450 float64_t* W; 00451 00453 float64_t w_gap; 00455 float64_t rho; 00456 00457 #ifdef USE_CPLEX 00458 00459 CPXENVptr env; 00461 CPXLPptr lp_cplex; 00462 #endif 00463 00464 #ifdef USE_GLPK 00465 00466 LPX* lp_glpk; 00467 #endif 00468 00469 bool lp_initialized ; 00470 }; 00471 } 00472 #endif //__MKL_H__