PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/shogun/regression/svr/SVRLight.cpp

https://code.google.com/
C++ | 775 lines | 616 code | 111 blank | 48 comment | 124 complexity | 5c07df9063b55bfb04741632557e6251 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, BSD-3-Clause
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 3 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * Written (W) 1999-2009 Soeren Sonnenburg
  8. * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
  9. */
  10. #include <shogun/lib/config.h>
  11. #ifdef USE_SVMLIGHT
  12. #include <shogun/io/SGIO.h>
  13. #include <shogun/mathematics/lapack.h>
  14. #include <shogun/lib/Signal.h>
  15. #include <shogun/mathematics/Math.h>
  16. #include <shogun/regression/svr/SVRLight.h>
  17. #include <shogun/machine/KernelMachine.h>
  18. #include <shogun/kernel/CombinedKernel.h>
  19. #include <shogun/labels/RegressionLabels.h>
  20. #include <unistd.h>
  21. #ifdef USE_CPLEX
  22. extern "C" {
  23. #include <ilcplex/cplex.h>
  24. }
  25. #endif
  26. #include <shogun/base/Parallel.h>
  27. #ifdef HAVE_PTHREAD
  28. #include <pthread.h>
  29. #endif
  30. using namespace shogun;
  31. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  32. struct S_THREAD_PARAM_SVRLIGHT
  33. {
  34. float64_t* lin;
  35. int32_t start, end;
  36. int32_t* active2dnum;
  37. int32_t* docs;
  38. CKernel* kernel;
  39. int32_t num_vectors;
  40. };
  41. #endif // DOXYGEN_SHOULD_SKIP_THIS
  42. CSVRLight::CSVRLight(float64_t C, float64_t eps, CKernel* k, CLabels* lab)
  43. : CSVMLight(C, k, lab)
  44. {
  45. set_tube_epsilon(eps);
  46. }
  47. CSVRLight::CSVRLight()
  48. : CSVMLight()
  49. {
  50. }
  51. /** default destructor */
  52. CSVRLight::~CSVRLight()
  53. {
  54. }
  55. EMachineType CSVRLight::get_classifier_type()
  56. {
  57. return CT_SVRLIGHT;
  58. }
  59. bool CSVRLight::train_machine(CFeatures* data)
  60. {
  61. //certain setup params
  62. verbosity=1;
  63. init_margin=0.15;
  64. init_iter=500;
  65. precision_violations=0;
  66. opt_precision=DEF_PRECISION;
  67. strcpy (learn_parm->predfile, "");
  68. learn_parm->biased_hyperplane=1;
  69. learn_parm->sharedslack=0;
  70. learn_parm->remove_inconsistent=0;
  71. learn_parm->skip_final_opt_check=1;
  72. learn_parm->svm_maxqpsize=get_qpsize();
  73. learn_parm->svm_newvarsinqp=learn_parm->svm_maxqpsize-1;
  74. learn_parm->maxiter=100000;
  75. learn_parm->svm_iter_to_shrink=100;
  76. learn_parm->svm_c=get_C1();
  77. learn_parm->transduction_posratio=0.33;
  78. learn_parm->svm_costratio=get_C2()/get_C1();
  79. learn_parm->svm_costratio_unlab=1.0;
  80. learn_parm->svm_unlabbound=1E-5;
  81. learn_parm->epsilon_crit=epsilon; // GU: better decrease it ... ??
  82. learn_parm->epsilon_a=1E-15;
  83. learn_parm->compute_loo=0;
  84. learn_parm->rho=1.0;
  85. learn_parm->xa_depth=0;
  86. if (!kernel)
  87. {
  88. SG_ERROR("SVR_light can not proceed without kernel!\n")
  89. return false ;
  90. }
  91. if (!m_labels)
  92. {
  93. SG_ERROR("SVR_light can not proceed without labels!\n")
  94. return false;
  95. }
  96. if (data)
  97. {
  98. if (m_labels->get_num_labels() != data->get_num_vectors())
  99. SG_ERROR("Number of training vectors does not match number of labels\n")
  100. kernel->init(data, data);
  101. }
  102. if (kernel->has_property(KP_LINADD) && get_linadd_enabled())
  103. kernel->clear_normal();
  104. // output some info
  105. SG_DEBUG("qpsize = %i\n", learn_parm->svm_maxqpsize)
  106. SG_DEBUG("epsilon = %1.1e\n", learn_parm->epsilon_crit)
  107. SG_DEBUG("kernel->has_property(KP_LINADD) = %i\n", kernel->has_property(KP_LINADD))
  108. SG_DEBUG("kernel->has_property(KP_KERNCOMBINATION) = %i\n", kernel->has_property(KP_KERNCOMBINATION))
  109. SG_DEBUG("get_linadd_enabled() = %i\n", get_linadd_enabled())
  110. SG_DEBUG("kernel->get_num_subkernels() = %i\n", kernel->get_num_subkernels())
  111. use_kernel_cache = !((kernel->get_kernel_type() == K_CUSTOM) ||
  112. (get_linadd_enabled() && kernel->has_property(KP_LINADD)));
  113. SG_DEBUG("use_kernel_cache = %i\n", use_kernel_cache)
  114. // train the svm
  115. svr_learn();
  116. // brain damaged svm light work around
  117. create_new_model(model->sv_num-1);
  118. set_bias(-model->b);
  119. for (int32_t i=0; i<model->sv_num-1; i++)
  120. {
  121. set_alpha(i, model->alpha[i+1]);
  122. set_support_vector(i, model->supvec[i+1]);
  123. }
  124. if (kernel->has_property(KP_LINADD) && get_linadd_enabled())
  125. kernel->clear_normal() ;
  126. return true ;
  127. }
  128. void CSVRLight::svr_learn()
  129. {
  130. int32_t *inconsistent, i, j;
  131. int32_t upsupvecnum;
  132. float64_t maxdiff, *lin, *c, *a;
  133. int32_t iterations;
  134. float64_t *xi_fullset; /* buffer for storing xi on full sample in loo */
  135. float64_t *a_fullset; /* buffer for storing alpha on full sample in loo */
  136. TIMING timing_profile;
  137. SHRINK_STATE shrink_state;
  138. int32_t* label;
  139. int32_t* docs;
  140. ASSERT(m_labels)
  141. int32_t totdoc=m_labels->get_num_labels();
  142. num_vectors=totdoc;
  143. // set up regression problem in standard form
  144. docs=SG_MALLOC(int32_t, 2*totdoc);
  145. label=SG_MALLOC(int32_t, 2*totdoc);
  146. c = SG_MALLOC(float64_t, 2*totdoc);
  147. for(i=0;i<totdoc;i++) {
  148. docs[i]=i;
  149. j=2*totdoc-1-i;
  150. label[i]=+1;
  151. c[i]=((CRegressionLabels*) m_labels)->get_label(i);
  152. docs[j]=j;
  153. label[j]=-1;
  154. c[j]=((CRegressionLabels*) m_labels)->get_label(i);
  155. }
  156. totdoc*=2;
  157. //prepare kernel cache for regression (i.e. cachelines are twice of current size)
  158. kernel->resize_kernel_cache( kernel->get_cache_size(), true);
  159. if (kernel->get_kernel_type() == K_COMBINED)
  160. {
  161. CCombinedKernel* k = (CCombinedKernel*) kernel;
  162. CKernel* kn = k->get_first_kernel();
  163. while (kn)
  164. {
  165. kn->resize_kernel_cache( kernel->get_cache_size(), true);
  166. SG_UNREF(kn);
  167. kn = k->get_next_kernel();
  168. }
  169. }
  170. timing_profile.time_kernel=0;
  171. timing_profile.time_opti=0;
  172. timing_profile.time_shrink=0;
  173. timing_profile.time_update=0;
  174. timing_profile.time_model=0;
  175. timing_profile.time_check=0;
  176. timing_profile.time_select=0;
  177. SG_FREE(W);
  178. W=NULL;
  179. if (kernel->has_property(KP_KERNCOMBINATION) && callback)
  180. {
  181. W = SG_MALLOC(float64_t, totdoc*kernel->get_num_subkernels());
  182. for (i=0; i<totdoc*kernel->get_num_subkernels(); i++)
  183. W[i]=0;
  184. }
  185. /* make sure -n value is reasonable */
  186. if((learn_parm->svm_newvarsinqp < 2)
  187. || (learn_parm->svm_newvarsinqp > learn_parm->svm_maxqpsize)) {
  188. learn_parm->svm_newvarsinqp=learn_parm->svm_maxqpsize;
  189. }
  190. init_shrink_state(&shrink_state,totdoc,(int32_t)MAXSHRINK);
  191. inconsistent = SG_MALLOC(int32_t, totdoc);
  192. a = SG_MALLOC(float64_t, totdoc);
  193. a_fullset = SG_MALLOC(float64_t, totdoc);
  194. xi_fullset = SG_MALLOC(float64_t, totdoc);
  195. lin = SG_MALLOC(float64_t, totdoc);
  196. learn_parm->svm_cost = SG_MALLOC(float64_t, totdoc);
  197. if (m_linear_term.vlen>0)
  198. learn_parm->eps=get_linear_term_array();
  199. else
  200. {
  201. learn_parm->eps=SG_MALLOC(float64_t, totdoc); /* equivalent regression epsilon for classification */
  202. SGVector<float64_t>::fill_vector(learn_parm->eps, totdoc, tube_epsilon);
  203. }
  204. SG_FREE(model->supvec);
  205. SG_FREE(model->alpha);
  206. SG_FREE(model->index);
  207. model->supvec = SG_MALLOC(int32_t, totdoc+2);
  208. model->alpha = SG_MALLOC(float64_t, totdoc+2);
  209. model->index = SG_MALLOC(int32_t, totdoc+2);
  210. model->at_upper_bound=0;
  211. model->b=0;
  212. model->supvec[0]=0; /* element 0 reserved and empty for now */
  213. model->alpha[0]=0;
  214. model->totdoc=totdoc;
  215. model->kernel=kernel;
  216. model->sv_num=1;
  217. model->loo_error=-1;
  218. model->loo_recall=-1;
  219. model->loo_precision=-1;
  220. model->xa_error=-1;
  221. model->xa_recall=-1;
  222. model->xa_precision=-1;
  223. for(i=0;i<totdoc;i++) { /* various inits */
  224. inconsistent[i]=0;
  225. a[i]=0;
  226. lin[i]=0;
  227. if(label[i] > 0) {
  228. learn_parm->svm_cost[i]=learn_parm->svm_c*learn_parm->svm_costratio*
  229. fabs((float64_t)label[i]);
  230. }
  231. else if(label[i] < 0) {
  232. learn_parm->svm_cost[i]=learn_parm->svm_c*fabs((float64_t)label[i]);
  233. }
  234. else
  235. ASSERT(false)
  236. }
  237. if(verbosity==1) {
  238. SG_DEBUG("Optimizing...\n")
  239. }
  240. /* train the svm */
  241. SG_DEBUG("num_train: %d\n", totdoc)
  242. iterations=optimize_to_convergence(docs,label,totdoc,
  243. &shrink_state,inconsistent,a,lin,
  244. c,&timing_profile,
  245. &maxdiff,(int32_t)-1,
  246. (int32_t)1);
  247. if(verbosity>=1) {
  248. SG_DONE()
  249. SG_INFO("(%ld iterations)\n",iterations)
  250. SG_INFO("Optimization finished (maxdiff=%.8f).\n",maxdiff)
  251. SG_INFO("obj = %.16f, rho = %.16f\n",get_objective(),model->b)
  252. upsupvecnum=0;
  253. SG_DEBUG("num sv: %d\n", model->sv_num)
  254. for(i=1;i<model->sv_num;i++)
  255. {
  256. if(fabs(model->alpha[i]) >=
  257. (learn_parm->svm_cost[model->supvec[i]]-
  258. learn_parm->epsilon_a))
  259. upsupvecnum++;
  260. }
  261. SG_INFO("Number of SV: %ld (including %ld at upper bound)\n",
  262. model->sv_num-1,upsupvecnum);
  263. }
  264. /* this makes sure the model we return does not contain pointers to the
  265. temporary documents */
  266. for(i=1;i<model->sv_num;i++) {
  267. j=model->supvec[i];
  268. if(j >= (totdoc/2)) {
  269. j=totdoc-j-1;
  270. }
  271. model->supvec[i]=j;
  272. }
  273. shrink_state_cleanup(&shrink_state);
  274. SG_FREE(label);
  275. SG_FREE(inconsistent);
  276. SG_FREE(c);
  277. SG_FREE(a);
  278. SG_FREE(a_fullset);
  279. SG_FREE(xi_fullset);
  280. SG_FREE(lin);
  281. SG_FREE(learn_parm->svm_cost);
  282. SG_FREE(docs);
  283. }
  284. float64_t CSVRLight::compute_objective_function(
  285. float64_t *a, float64_t *lin, float64_t *c, float64_t* eps, int32_t *label,
  286. int32_t totdoc)
  287. {
  288. /* calculate value of objective function */
  289. float64_t criterion=0;
  290. for(int32_t i=0;i<totdoc;i++)
  291. criterion+=(eps[i]-(float64_t)label[i]*c[i])*a[i]+0.5*a[i]*label[i]*lin[i];
  292. /* float64_t check=0;
  293. for(int32_t i=0;i<totdoc;i++)
  294. {
  295. check+=a[i]*eps-a[i]*label[i]*c[i];
  296. for(int32_t j=0;j<totdoc;j++)
  297. check+= 0.5*a[i]*label[i]*a[j]*label[j]*compute_kernel(i,j);
  298. }
  299. SG_INFO("REGRESSION OBJECTIVE %f vs. CHECK %f (diff %f)\n", criterion, check, criterion-check) */
  300. return(criterion);
  301. }
  302. void* CSVRLight::update_linear_component_linadd_helper(void *params_)
  303. {
  304. S_THREAD_PARAM_SVRLIGHT * params = (S_THREAD_PARAM_SVRLIGHT*) params_ ;
  305. int32_t jj=0, j=0 ;
  306. for(jj=params->start;(jj<params->end) && (j=params->active2dnum[jj])>=0;jj++)
  307. params->lin[j]+=params->kernel->compute_optimized(CSVRLight::regression_fix_index2(params->docs[j], params->num_vectors));
  308. return NULL ;
  309. }
  310. int32_t CSVRLight::regression_fix_index(int32_t i)
  311. {
  312. if (i>=num_vectors)
  313. i=2*num_vectors-1-i;
  314. return i;
  315. }
  316. int32_t CSVRLight::regression_fix_index2(
  317. int32_t i, int32_t num_vectors)
  318. {
  319. if (i>=num_vectors)
  320. i=2*num_vectors-1-i;
  321. return i;
  322. }
  323. float64_t CSVRLight::compute_kernel(int32_t i, int32_t j)
  324. {
  325. i=regression_fix_index(i);
  326. j=regression_fix_index(j);
  327. return kernel->kernel(i, j);
  328. }
  329. void CSVRLight::update_linear_component(
  330. int32_t* docs, int32_t* label, int32_t *active2dnum, float64_t *a,
  331. float64_t *a_old, int32_t *working2dnum, int32_t totdoc, float64_t *lin,
  332. float64_t *aicache, float64_t* c)
  333. /* keep track of the linear component */
  334. /* lin of the gradient etc. by updating */
  335. /* based on the change of the variables */
  336. /* in the current working set */
  337. {
  338. register int32_t i=0,ii=0,j=0,jj=0;
  339. if (kernel->has_property(KP_LINADD) && get_linadd_enabled())
  340. {
  341. if (callback)
  342. {
  343. update_linear_component_mkl_linadd(docs, label, active2dnum, a, a_old, working2dnum,
  344. totdoc, lin, aicache, c) ;
  345. }
  346. else
  347. {
  348. kernel->clear_normal();
  349. int32_t num_working=0;
  350. for(ii=0;(i=working2dnum[ii])>=0;ii++) {
  351. if(a[i] != a_old[i]) {
  352. kernel->add_to_normal(regression_fix_index(docs[i]), (a[i]-a_old[i])*(float64_t)label[i]);
  353. num_working++;
  354. }
  355. }
  356. if (num_working>0)
  357. {
  358. if (parallel->get_num_threads() < 2)
  359. {
  360. for(jj=0;(j=active2dnum[jj])>=0;jj++) {
  361. lin[j]+=kernel->compute_optimized(regression_fix_index(docs[j]));
  362. }
  363. }
  364. #ifdef HAVE_PTHREAD
  365. else
  366. {
  367. int32_t num_elem = 0 ;
  368. for(jj=0;(j=active2dnum[jj])>=0;jj++) num_elem++ ;
  369. pthread_t* threads = SG_MALLOC(pthread_t, parallel->get_num_threads()-1);
  370. S_THREAD_PARAM_SVRLIGHT* params = SG_MALLOC(S_THREAD_PARAM_SVRLIGHT, parallel->get_num_threads()-1);
  371. int32_t start = 0 ;
  372. int32_t step = num_elem/parallel->get_num_threads() ;
  373. int32_t end = step ;
  374. for (int32_t t=0; t<parallel->get_num_threads()-1; t++)
  375. {
  376. params[t].kernel = kernel ;
  377. params[t].lin = lin ;
  378. params[t].docs = docs ;
  379. params[t].active2dnum=active2dnum ;
  380. params[t].start = start ;
  381. params[t].end = end ;
  382. params[t].num_vectors=num_vectors ;
  383. start=end ;
  384. end+=step ;
  385. pthread_create(&threads[t], NULL, update_linear_component_linadd_helper, (void*)&params[t]) ;
  386. }
  387. for(jj=params[parallel->get_num_threads()-2].end;(j=active2dnum[jj])>=0;jj++) {
  388. lin[j]+=kernel->compute_optimized(regression_fix_index(docs[j]));
  389. }
  390. void* ret;
  391. for (int32_t t=0; t<parallel->get_num_threads()-1; t++)
  392. pthread_join(threads[t], &ret) ;
  393. SG_FREE(params);
  394. SG_FREE(threads);
  395. }
  396. #endif
  397. }
  398. }
  399. }
  400. else
  401. {
  402. if (callback)
  403. {
  404. update_linear_component_mkl(docs, label, active2dnum,
  405. a, a_old, working2dnum, totdoc, lin, aicache, c) ;
  406. }
  407. else {
  408. for(jj=0;(i=working2dnum[jj])>=0;jj++) {
  409. if(a[i] != a_old[i]) {
  410. kernel->get_kernel_row(i,active2dnum,aicache);
  411. for(ii=0;(j=active2dnum[ii])>=0;ii++)
  412. lin[j]+=(a[i]-a_old[i])*aicache[j]*(float64_t)label[i];
  413. }
  414. }
  415. }
  416. }
  417. }
  418. void CSVRLight::update_linear_component_mkl(
  419. int32_t* docs, int32_t* label, int32_t *active2dnum, float64_t *a,
  420. float64_t *a_old, int32_t *working2dnum, int32_t totdoc, float64_t *lin,
  421. float64_t *aicache, float64_t* c)
  422. {
  423. int32_t num = totdoc;
  424. int32_t num_weights = -1;
  425. int32_t num_kernels = kernel->get_num_subkernels() ;
  426. const float64_t* old_beta = kernel->get_subkernel_weights(num_weights);
  427. ASSERT(num_weights==num_kernels)
  428. if ((kernel->get_kernel_type()==K_COMBINED) &&
  429. (!((CCombinedKernel*)kernel)->get_append_subkernel_weights()))// for combined kernel
  430. {
  431. CCombinedKernel* k = (CCombinedKernel*) kernel;
  432. CKernel* kn = k->get_first_kernel() ;
  433. int32_t n = 0, i, j ;
  434. while (kn!=NULL)
  435. {
  436. for(i=0;i<num;i++)
  437. {
  438. if(a[i] != a_old[i])
  439. {
  440. kn->get_kernel_row(i,NULL,aicache, true);
  441. for(j=0;j<num;j++)
  442. W[j*num_kernels+n]+=(a[i]-a_old[i])*aicache[regression_fix_index(j)]*(float64_t)label[i];
  443. }
  444. }
  445. SG_UNREF(kn);
  446. kn = k->get_next_kernel();
  447. n++ ;
  448. }
  449. }
  450. else // hope the kernel is fast ...
  451. {
  452. float64_t* w_backup = SG_MALLOC(float64_t, num_kernels);
  453. float64_t* w1 = SG_MALLOC(float64_t, num_kernels);
  454. // backup and set to zero
  455. for (int32_t i=0; i<num_kernels; i++)
  456. {
  457. w_backup[i] = old_beta[i] ;
  458. w1[i]=0.0 ;
  459. }
  460. for (int32_t n=0; n<num_kernels; n++)
  461. {
  462. w1[n]=1.0 ;
  463. kernel->set_subkernel_weights(SGVector<float64_t>(w1, num_weights)) ;
  464. for(int32_t i=0;i<num;i++)
  465. {
  466. if(a[i] != a_old[i])
  467. {
  468. for(int32_t j=0;j<num;j++)
  469. W[j*num_kernels+n]+=(a[i]-a_old[i])*compute_kernel(i,j)*(float64_t)label[i];
  470. }
  471. }
  472. w1[n]=0.0 ;
  473. }
  474. // restore old weights
  475. kernel->set_subkernel_weights(SGVector<float64_t>(w_backup,num_weights));
  476. SG_FREE(w_backup);
  477. SG_FREE(w1);
  478. }
  479. call_mkl_callback(a, label, lin, c, totdoc);
  480. }
  481. void CSVRLight::update_linear_component_mkl_linadd(
  482. int32_t* docs, int32_t* label, int32_t *active2dnum, float64_t *a,
  483. float64_t *a_old, int32_t *working2dnum, int32_t totdoc, float64_t *lin,
  484. float64_t *aicache, float64_t* c)
  485. {
  486. // kernel with LP_LINADD property is assumed to have
  487. // compute_by_subkernel functions
  488. int32_t num_weights = -1;
  489. int32_t num_kernels = kernel->get_num_subkernels() ;
  490. const float64_t* old_beta = kernel->get_subkernel_weights(num_weights);
  491. ASSERT(num_weights==num_kernels)
  492. float64_t* w_backup=SG_MALLOC(float64_t, num_kernels);
  493. float64_t* w1=SG_MALLOC(float64_t, num_kernels);
  494. // backup and set to one
  495. for (int32_t i=0; i<num_kernels; i++)
  496. {
  497. w_backup[i] = old_beta[i] ;
  498. w1[i]=1.0 ;
  499. }
  500. // set the kernel weights
  501. kernel->set_subkernel_weights(SGVector<float64_t>(w1, num_weights));
  502. // create normal update (with changed alphas only)
  503. kernel->clear_normal();
  504. for(int32_t ii=0, i=0;(i=working2dnum[ii])>=0;ii++) {
  505. if(a[i] != a_old[i]) {
  506. kernel->add_to_normal(regression_fix_index(docs[i]), (a[i]-a_old[i])*(float64_t)label[i]);
  507. }
  508. }
  509. // determine contributions of different kernels
  510. for (int32_t i=0; i<num_vectors; i++)
  511. kernel->compute_by_subkernel(i,&W[i*num_kernels]) ;
  512. // restore old weights
  513. kernel->set_subkernel_weights(SGVector<float64_t>(w_backup,num_weights));
  514. call_mkl_callback(a, label, lin, c, totdoc);
  515. }
  516. void CSVRLight::call_mkl_callback(float64_t* a, int32_t* label, float64_t* lin, float64_t* c, int32_t totdoc)
  517. {
  518. int32_t num = totdoc;
  519. int32_t num_kernels = kernel->get_num_subkernels() ;
  520. float64_t sumalpha = 0;
  521. float64_t* sumw=SG_MALLOC(float64_t, num_kernels);
  522. for (int32_t i=0; i<num; i++)
  523. sumalpha-=a[i]*(learn_parm->eps[i]-label[i]*c[i]);
  524. #ifdef HAVE_LAPACK
  525. int nk = (int) num_kernels; // calling external lib
  526. double* alphay = SG_MALLOC(double, num);
  527. for (int32_t i=0; i<num; i++)
  528. alphay[i]=a[i]*label[i];
  529. for (int32_t i=0; i<num_kernels; i++)
  530. sumw[i]=0;
  531. cblas_dgemv(CblasColMajor, CblasNoTrans, nk, (int) num, 0.5, (double*) W,
  532. nk, (double*) alphay, 1, 1.0, (double*) sumw, 1);
  533. SG_FREE(alphay);
  534. #else
  535. for (int32_t d=0; d<num_kernels; d++)
  536. {
  537. sumw[d]=0;
  538. for(int32_t i=0; i<num; i++)
  539. sumw[d] += 0.5*a[i]*label[i]*W[i*num_kernels+d];
  540. }
  541. #endif
  542. if (callback)
  543. mkl_converged=callback(mkl, sumw, sumalpha);
  544. const float64_t* new_beta = kernel->get_subkernel_weights(num_kernels);
  545. // update lin
  546. #ifdef HAVE_LAPACK
  547. cblas_dgemv(CblasColMajor, CblasTrans, nk, (int) num, 1.0, (double*) W,
  548. nk, (double*) new_beta, 1, 0.0, (double*) lin, 1);
  549. #else
  550. for(int32_t i=0; i<num; i++)
  551. lin[i]=0 ;
  552. for (int32_t d=0; d<num_kernels; d++)
  553. if (new_beta[d]!=0)
  554. for(int32_t i=0; i<num; i++)
  555. lin[i] += new_beta[d]*W[i*num_kernels+d] ;
  556. #endif
  557. SG_FREE(sumw);
  558. }
  559. void CSVRLight::reactivate_inactive_examples(
  560. int32_t* label, float64_t *a, SHRINK_STATE *shrink_state, float64_t *lin,
  561. float64_t *c, int32_t totdoc, int32_t iteration, int32_t *inconsistent,
  562. int32_t* docs, float64_t *aicache, float64_t *maxdiff)
  563. /* Make all variables active again which had been removed by
  564. shrinking. */
  565. /* Computes lin for those variables from scratch. */
  566. {
  567. register int32_t i=0,j,ii=0,jj,t,*changed2dnum,*inactive2dnum;
  568. int32_t *changed,*inactive;
  569. register float64_t *a_old,dist;
  570. float64_t ex_c,target;
  571. if (kernel->has_property(KP_LINADD) && get_linadd_enabled()) { /* special linear case */
  572. a_old=shrink_state->last_a;
  573. kernel->clear_normal();
  574. int32_t num_modified=0;
  575. for(i=0;i<totdoc;i++) {
  576. if(a[i] != a_old[i]) {
  577. kernel->add_to_normal(regression_fix_index(docs[i]), ((a[i]-a_old[i])*(float64_t)label[i]));
  578. a_old[i]=a[i];
  579. num_modified++;
  580. }
  581. }
  582. if (num_modified>0)
  583. {
  584. for(i=0;i<totdoc;i++) {
  585. if(!shrink_state->active[i]) {
  586. lin[i]=shrink_state->last_lin[i]+kernel->compute_optimized(regression_fix_index(docs[i]));
  587. }
  588. shrink_state->last_lin[i]=lin[i];
  589. }
  590. }
  591. }
  592. else
  593. {
  594. changed=SG_MALLOC(int32_t, totdoc);
  595. changed2dnum=SG_MALLOC(int32_t, totdoc+11);
  596. inactive=SG_MALLOC(int32_t, totdoc);
  597. inactive2dnum=SG_MALLOC(int32_t, totdoc+11);
  598. for(t=shrink_state->deactnum-1;(t>=0) && shrink_state->a_history[t];t--) {
  599. if(verbosity>=2) {
  600. SG_INFO("%ld..",t)
  601. }
  602. a_old=shrink_state->a_history[t];
  603. for(i=0;i<totdoc;i++) {
  604. inactive[i]=((!shrink_state->active[i])
  605. && (shrink_state->inactive_since[i] == t));
  606. changed[i]= (a[i] != a_old[i]);
  607. }
  608. compute_index(inactive,totdoc,inactive2dnum);
  609. compute_index(changed,totdoc,changed2dnum);
  610. for(ii=0;(i=changed2dnum[ii])>=0;ii++) {
  611. CKernelMachine::kernel->get_kernel_row(i,inactive2dnum,aicache);
  612. for(jj=0;(j=inactive2dnum[jj])>=0;jj++)
  613. lin[j]+=(a[i]-a_old[i])*aicache[j]*(float64_t)label[i];
  614. }
  615. }
  616. SG_FREE(changed);
  617. SG_FREE(changed2dnum);
  618. SG_FREE(inactive);
  619. SG_FREE(inactive2dnum);
  620. }
  621. (*maxdiff)=0;
  622. for(i=0;i<totdoc;i++) {
  623. shrink_state->inactive_since[i]=shrink_state->deactnum-1;
  624. if(!inconsistent[i]) {
  625. dist=(lin[i]-model->b)*(float64_t)label[i];
  626. target=-(learn_parm->eps[i]-(float64_t)label[i]*c[i]);
  627. ex_c=learn_parm->svm_cost[i]-learn_parm->epsilon_a;
  628. if((a[i]>learn_parm->epsilon_a) && (dist > target)) {
  629. if((dist-target)>(*maxdiff)) /* largest violation */
  630. (*maxdiff)=dist-target;
  631. }
  632. else if((a[i]<ex_c) && (dist < target)) {
  633. if((target-dist)>(*maxdiff)) /* largest violation */
  634. (*maxdiff)=target-dist;
  635. }
  636. if((a[i]>(0+learn_parm->epsilon_a))
  637. && (a[i]<ex_c)) {
  638. shrink_state->active[i]=1; /* not at bound */
  639. }
  640. else if((a[i]<=(0+learn_parm->epsilon_a)) && (dist < (target+learn_parm->epsilon_shrink))) {
  641. shrink_state->active[i]=1;
  642. }
  643. else if((a[i]>=ex_c)
  644. && (dist > (target-learn_parm->epsilon_shrink))) {
  645. shrink_state->active[i]=1;
  646. }
  647. else if(learn_parm->sharedslack) { /* make all active when sharedslack */
  648. shrink_state->active[i]=1;
  649. }
  650. }
  651. }
  652. if (use_kernel_cache) { /* update history for non-linear */
  653. for(i=0;i<totdoc;i++) {
  654. (shrink_state->a_history[shrink_state->deactnum-1])[i]=a[i];
  655. }
  656. for(t=shrink_state->deactnum-2;(t>=0) && shrink_state->a_history[t];t--) {
  657. SG_FREE(shrink_state->a_history[t]);
  658. shrink_state->a_history[t]=0;
  659. }
  660. }
  661. }
  662. #endif //USE_SVMLIGHT