void svm_learn_struct(SAMPLE sample, STRUCT_LEARN_PARM *sparm, LEARN_PARM *lparm, KERNEL_PARM *kparm, STRUCTMODEL *sm, int alg_type) { int i,j; int numIt=0; long argmax_count=0; long newconstraints=0, totconstraints=0, activenum=0; int opti_round, *opti, fullround, use_shrinking; long old_totconstraints=0; double epsilon,svmCnorm; long tolerance,new_precision=1,dont_stop=0; double lossval,factor,dist; double margin=0; double slack, *slacks, slacksum, ceps; double dualitygap,modellength,alphasum; long sizePsi; double *alpha=NULL; long *alphahist=NULL,optcount=0,lastoptcount=0; CONSTSET cset; SVECTOR *diff=NULL; SVECTOR *fy, *fybar, *f, **fycache=NULL; SVECTOR *slackvec; WORD slackv[2]; MODEL *svmModel=NULL; KERNEL_CACHE *kcache=NULL; LABEL ybar; DOC *doc; long n=sample.n; EXAMPLE *ex=sample.examples; double rt_total=0, rt_opt=0, rt_init=0, rt_psi=0, rt_viol=0; double rt1,rt2; rt1=get_runtime(); init_struct_model(sample,sm,sparm,lparm,kparm); sizePsi=sm->sizePsi+1; /* sm must contain size of psi on return */ /* initialize shrinking-style example selection heuristic */ if(alg_type == NSLACK_SHRINK_ALG) use_shrinking=1; else use_shrinking=0; opti=(int*)my_malloc(n*sizeof(int)); for(i=0;i<n;i++) { opti[i]=0; } opti_round=0; /* normalize regularization parameter C by the number of training examples */ svmCnorm=sparm->C/n; if(sparm->slack_norm == 1) { lparm->svm_c=svmCnorm; /* set upper bound C */ lparm->sharedslack=1; } else if(sparm->slack_norm == 2) { lparm->svm_c=999999999999999.0; /* upper bound C must never be reached */ lparm->sharedslack=0; if(kparm->kernel_type != LINEAR_KERNEL) { printf("ERROR: Kernels are not implemented for L2 slack norm!"); fflush(stdout); exit(0); } } else { printf("ERROR: Slack norm must be L1 or L2!"); fflush(stdout); exit(0); } epsilon=100.0; /* start with low precision and increase later */ tolerance=MIN(n/3,MAX(n/100,5));/* increase precision, whenever less than that number of constraints is not fulfilled */ lparm->biased_hyperplane=0; /* set threshold to zero */ cset=init_struct_constraints(sample, sm, sparm); if(cset.m > 0) { alpha=(double *)realloc(alpha,sizeof(double)*cset.m); alphahist=(long *)realloc(alphahist,sizeof(long)*cset.m); for(i=0; i<cset.m; i++) { alpha[i]=0; alphahist[i]=-1; /* -1 makes sure these constraints are never removed */ } } /* set initial model and slack variables*/ svmModel=(MODEL *)my_malloc(sizeof(MODEL)); lparm->epsilon_crit=epsilon; if(kparm->kernel_type != LINEAR_KERNEL) kcache=kernel_cache_init(MAX(cset.m,1),lparm->kernel_cache_size); svm_learn_optimization(cset.lhs,cset.rhs,cset.m,sizePsi+n, lparm,kparm,kcache,svmModel,alpha); if(kcache) kernel_cache_cleanup(kcache); add_weight_vector_to_linear_model(svmModel); sm->svm_model=svmModel; sm->w=svmModel->lin_weights; /* short cut to weight vector */ /* create a cache of the feature vectors for the correct labels */ if(USE_FYCACHE) { fycache=(SVECTOR **)my_malloc(n*sizeof(SVECTOR *)); for(i=0;i<n;i++) { fy=psi(ex[i].x,ex[i].y,sm,sparm); if(kparm->kernel_type == LINEAR_KERNEL) { diff=add_list_ss(fy); /* store difference vector directly */ free_svector(fy); fy=diff; } fycache[i]=fy; } } rt_init+=MAX(get_runtime()-rt1,0); rt_total+=MAX(get_runtime()-rt1,0); /*****************/ /*** main loop ***/ /*****************/ do { /* iteratively increase precision */ epsilon=MAX(epsilon*0.49999999999,sparm->epsilon); new_precision=1; if(epsilon == sparm->epsilon) /* for final precision, find all SV */ tolerance=0; lparm->epsilon_crit=epsilon/2; /* svm precision must be higher than eps */ if(struct_verbosity>=1) printf("Setting current working precision to %g.\n",epsilon); do { /* iteration until (approx) all SV are found for current precision and tolerance */ opti_round++; activenum=n; dont_stop=0; old_totconstraints=totconstraints; do { /* with shrinking turned on, go through examples that keep producing new constraints */ if(struct_verbosity>=1) { printf("Iter %i (%ld active): ",++numIt,activenum); fflush(stdout); } ceps=0; fullround=(activenum == n); for(i=0; i<n; i++) { /*** example loop ***/ rt1=get_runtime(); if((!use_shrinking) || (opti[i] != opti_round)) { /* if the example is not shrunk away, then see if it is necessary to add a new constraint */ rt2=get_runtime(); argmax_count++; if(sparm->loss_type == SLACK_RESCALING) ybar=find_most_violated_constraint_slackrescaling(ex[i].x, ex[i].y,sm, sparm); else ybar=find_most_violated_constraint_marginrescaling(ex[i].x, ex[i].y,sm, sparm); rt_viol+=MAX(get_runtime()-rt2,0); if(empty_label(ybar)) { if(opti[i] != opti_round) { activenum--; opti[i]=opti_round; } if(struct_verbosity>=2) printf("no-incorrect-found(%i) ",i); continue; } /**** get psi(y)-psi(ybar) ****/ rt2=get_runtime(); if(fycache) fy=copy_svector(fycache[i]); else fy=psi(ex[i].x,ex[i].y,sm,sparm); fybar=psi(ex[i].x,ybar,sm,sparm); rt_psi+=MAX(get_runtime()-rt2,0); /**** scale feature vector and margin by loss ****/ lossval=loss(ex[i].y,ybar,sparm); if(sparm->slack_norm == 2) lossval=sqrt(lossval); if(sparm->loss_type == SLACK_RESCALING) factor=lossval; else /* do not rescale vector for */ factor=1.0; /* margin rescaling loss type */ for(f=fy;f;f=f->next) f->factor*=factor; for(f=fybar;f;f=f->next) f->factor*=-factor; margin=lossval; /**** create constraint for current ybar ****/ append_svector_list(fy,fybar);/* append the two vector lists */ doc=create_example(cset.m,0,i+1,1,fy); /**** compute slack for this example ****/ slack=0; for(j=0;j<cset.m;j++) if(cset.lhs[j]->slackid == i+1) { if(sparm->slack_norm == 2) /* works only for linear kernel */ slack=MAX(slack,cset.rhs[j] -(classify_example(svmModel,cset.lhs[j]) -sm->w[sizePsi+i]/(sqrt(2*svmCnorm)))); else slack=MAX(slack, cset.rhs[j]-classify_example(svmModel,cset.lhs[j])); } /**** if `error' add constraint and recompute ****/ dist=classify_example(svmModel,doc); ceps=MAX(ceps,margin-dist-slack); if(slack > (margin-dist+0.0001)) { printf("\nWARNING: Slack of most violated constraint is smaller than slack of working\n"); printf(" set! There is probably a bug in 'find_most_violated_constraint_*'.\n"); printf("Ex %d: slack=%f, newslack=%f\n",i,slack,margin-dist); /* exit(1); */ } if((dist+slack)<(margin-epsilon)) { if(struct_verbosity>=2) {printf("(%i,eps=%.2f) ",i,margin-dist-slack); fflush(stdout);} if(struct_verbosity==1) {printf("."); fflush(stdout);} /**** resize constraint matrix and add new constraint ****/ cset.m++; cset.lhs=(DOC **)realloc(cset.lhs,sizeof(DOC *)*cset.m); if(kparm->kernel_type == LINEAR_KERNEL) { diff=add_list_ss(fy); /* store difference vector directly */ if(sparm->slack_norm == 1) cset.lhs[cset.m-1]=create_example(cset.m-1,0,i+1,1, copy_svector(diff)); else if(sparm->slack_norm == 2) { /**** add squared slack variable to feature vector ****/ slackv[0].wnum=sizePsi+i; slackv[0].weight=1/(sqrt(2*svmCnorm)); slackv[1].wnum=0; /*terminator*/ slackvec=create_svector(slackv,NULL,1.0); cset.lhs[cset.m-1]=create_example(cset.m-1,0,i+1,1, add_ss(diff,slackvec)); free_svector(slackvec); } free_svector(diff); } else { /* kernel is used */ if(sparm->slack_norm == 1) cset.lhs[cset.m-1]=create_example(cset.m-1,0,i+1,1, copy_svector(fy)); else if(sparm->slack_norm == 2) exit(1); } cset.rhs=(double *)realloc(cset.rhs,sizeof(double)*cset.m); cset.rhs[cset.m-1]=margin; alpha=(double *)realloc(alpha,sizeof(double)*cset.m); alpha[cset.m-1]=0; alphahist=(long *)realloc(alphahist,sizeof(long)*cset.m); alphahist[cset.m-1]=optcount; newconstraints++; totconstraints++; } else { printf("+"); fflush(stdout); if(opti[i] != opti_round) { activenum--; opti[i]=opti_round; } } free_example(doc,0); free_svector(fy); /* this also free's fybar */ free_label(ybar); } /**** get new QP solution ****/ if((newconstraints >= sparm->newconstretrain) || ((newconstraints > 0) && (i == n-1)) || (new_precision && (i == n-1))) { if(struct_verbosity>=1) { printf("*");fflush(stdout); } rt2=get_runtime(); free_model(svmModel,0); svmModel=(MODEL *)my_malloc(sizeof(MODEL)); /* Always get a new kernel cache. It is not possible to use the same cache for two different training runs */ if(kparm->kernel_type != LINEAR_KERNEL) kcache=kernel_cache_init(MAX(cset.m,1),lparm->kernel_cache_size); /* Run the QP solver on cset. */ svm_learn_optimization(cset.lhs,cset.rhs,cset.m,sizePsi+n, lparm,kparm,kcache,svmModel,alpha); if(kcache) kernel_cache_cleanup(kcache); /* Always add weight vector, in case part of the kernel is linear. If not, ignore the weight vector since its content is bogus. */ add_weight_vector_to_linear_model(svmModel); sm->svm_model=svmModel; sm->w=svmModel->lin_weights; /* short cut to weight vector */ optcount++; /* keep track of when each constraint was last active. constraints marked with -1 are not updated */ for(j=0;j<cset.m;j++) if((alphahist[j]>-1) && (alpha[j] != 0)) alphahist[j]=optcount; rt_opt+=MAX(get_runtime()-rt2,0); if(new_precision && (epsilon <= sparm->epsilon)) dont_stop=1; /* make sure we take one final pass */ new_precision=0; newconstraints=0; } rt_total+=MAX(get_runtime()-rt1,0); } /* end of example loop */ rt1=get_runtime(); if(struct_verbosity>=1) printf("(NumConst=%d, SV=%ld, CEps=%.4f, QPEps=%.4f)\n",cset.m, svmModel->sv_num-1,ceps,svmModel->maxdiff); /* Check if some of the linear constraints have not been active in a while. Those constraints are then removed to avoid bloating the working set beyond necessity. */ if(struct_verbosity>=2) printf("Reducing working set...");fflush(stdout); remove_inactive_constraints(&cset,alpha,optcount,alphahist, MAX(50,optcount-lastoptcount)); lastoptcount=optcount; if(struct_verbosity>=2) printf("done. (NumConst=%d)\n",cset.m); rt_total+=MAX(get_runtime()-rt1,0); } while(use_shrinking && (activenum > 0)); /* when using shrinking, repeat until all examples produced no constraint at least once */ } while(((totconstraints - old_totconstraints) > tolerance) || dont_stop); } while((epsilon > sparm->epsilon) || finalize_iteration(ceps,0,sample,sm,cset,alpha,sparm)); if(struct_verbosity>=1) { /**** compute sum of slacks ****/ /**** WARNING: If positivity constraints are used, then the maximum slack id is larger than what is allocated below ****/ slacks=(double *)my_malloc(sizeof(double)*(n+1)); for(i=0; i<=n; i++) { slacks[i]=0; } if(sparm->slack_norm == 1) { for(j=0;j<cset.m;j++) slacks[cset.lhs[j]->slackid]=MAX(slacks[cset.lhs[j]->slackid], cset.rhs[j]-classify_example(svmModel,cset.lhs[j])); } else if(sparm->slack_norm == 2) { for(j=0;j<cset.m;j++) slacks[cset.lhs[j]->slackid]=MAX(slacks[cset.lhs[j]->slackid], cset.rhs[j] -(classify_example(svmModel,cset.lhs[j]) -sm->w[sizePsi+cset.lhs[j]->slackid-1]/(sqrt(2*svmCnorm)))); } slacksum=0; for(i=1; i<=n; i++) slacksum+=slacks[i]; free(slacks); alphasum=0; for(i=0; i<cset.m; i++) alphasum+=alpha[i]*cset.rhs[i]; modellength=model_length_s(svmModel); dualitygap=(0.5*modellength*modellength+svmCnorm*(slacksum+n*ceps)) -(alphasum-0.5*modellength*modellength); printf("Final epsilon on KKT-Conditions: %.5f\n", MAX(svmModel->maxdiff,epsilon)); printf("Upper bound on duality gap: %.5f\n", dualitygap); printf("Dual objective value: dval=%.5f\n", alphasum-0.5*modellength*modellength); printf("Total number of constraints in final working set: %i (of %i)\n",(int)cset.m,(int)totconstraints); printf("Number of iterations: %d\n",numIt); printf("Number of calls to 'find_most_violated_constraint': %ld\n",argmax_count); if(sparm->slack_norm == 1) { printf("Number of SV: %ld \n",svmModel->sv_num-1); printf("Number of non-zero slack variables: %ld (out of %ld)\n", svmModel->at_upper_bound,n); printf("Norm of weight vector: |w|=%.5f\n",modellength); } else if(sparm->slack_norm == 2){ printf("Number of SV: %ld (including %ld at upper bound)\n", svmModel->sv_num-1,svmModel->at_upper_bound); printf("Norm of weight vector (including L2-loss): |w|=%.5f\n", modellength); } printf("Norm. sum of slack variables (on working set): sum(xi_i)/n=%.5f\n",slacksum/n); printf("Norm of longest difference vector: ||Psi(x,y)-Psi(x,ybar)||=%.5f\n", length_of_longest_document_vector(cset.lhs,cset.m,kparm)); printf("Runtime in cpu-seconds: %.2f (%.2f%% for QP, %.2f%% for Argmax, %.2f%% for Psi, %.2f%% for init)\n", rt_total/100.0, (100.0*rt_opt)/rt_total, (100.0*rt_viol)/rt_total, (100.0*rt_psi)/rt_total, (100.0*rt_init)/rt_total); } if(struct_verbosity>=4) printW(sm->w,sizePsi,n,lparm->svm_c); if(svmModel) { sm->svm_model=copy_model(svmModel); sm->w=sm->svm_model->lin_weights; /* short cut to weight vector */ } print_struct_learning_stats(sample,sm,cset,alpha,sparm); if(fycache) { for(i=0;i<n;i++) free_svector(fycache[i]); free(fycache); } if(svmModel) free_model(svmModel,0); free(alpha); free(alphahist); free(opti); free(cset.rhs); for(i=0;i<cset.m;i++) free_example(cset.lhs[i],1); free(cset.lhs); }
int main_classify (int argc, char* argv[]) { DOC *doc; /* test example */ WORDSVM *words; long max_docs,max_words_doc,lld; long totdoc=0,queryid,slackid; long correct=0,incorrect=0,no_accuracy=0; long res_a=0,res_b=0,res_c=0,res_d=0,wnum,pred_format; long j; double t1,runtime=0; double dist,doc_label,costfactor; char *line,*comment; FILE *predfl,*docfl; MODEL *model; read_input_parameters(argc,argv,docfile,modelfile,predictionsfile, &verbosity,&pred_format); nol_ll(docfile,&max_docs,&max_words_doc,&lld); /* scan size of input file */ max_words_doc+=2; lld+=2; line = (char *)my_malloc(sizeof(char)*lld); words = (WORDSVM *)my_malloc(sizeof(WORDSVM)*(max_words_doc+10)); model=read_model(modelfile); if(model->kernel_parm.kernel_type == 0) { /* linear kernel */ /* compute weight vector */ add_weight_vector_to_linear_model(model); } if(verbosity>=2) { printf("Classifying test examples.."); fflush(stdout); } if ((docfl = fopen (docfile, "r")) == NULL) { perror (docfile); exit (1); } if ((predfl = fopen (predictionsfile, "w")) == NULL) { perror (predictionsfile); exit (1); } while((!feof(docfl)) && fgets(line,(int)lld,docfl)) { if(line[0] == '#') continue; /* line contains comments */ parse_document(line,words,&doc_label,&queryid,&slackid,&costfactor,&wnum, max_words_doc,&comment); totdoc++; if(model->kernel_parm.kernel_type == 0) { /* linear kernel */ for(j=0;(words[j]).wnum != 0;j++) { /* Check if feature numbers */ if((words[j]).wnum>model->totwords) /* are not larger than in */ (words[j]).wnum=0; /* model. Remove feature if */ } /* necessary. */ doc = create_example(-1,0,0,0.0,create_svector(words,comment,1.0)); t1=get_runtime(); dist=classify_example_linear(model,doc); runtime+=(get_runtime()-t1); free_example(doc,1); } else { /* non-linear kernel */ doc = create_example(-1,0,0,0.0,create_svector(words,comment,1.0)); t1=get_runtime(); dist=classify_example(model,doc); runtime+=(get_runtime()-t1); free_example(doc,1); } if(dist>0) { if(pred_format==0) { /* old weired output format */ fprintf(predfl,"%.8g:+1 %.8g:-1\n",dist,-dist); } if(doc_label>0) correct++; else incorrect++; if(doc_label>0) res_a++; else res_b++; } else { if(pred_format==0) { /* old weired output format */ fprintf(predfl,"%.8g:-1 %.8g:+1\n",-dist,dist); } if(doc_label<0) correct++; else incorrect++; if(doc_label>0) res_c++; else res_d++; } if(pred_format==1) { /* output the value of decision function */ fprintf(predfl,"%.8g\n",dist); } if((int)(0.01+(doc_label*doc_label)) != 1) { no_accuracy=1; } /* test data is not binary labeled */ if(verbosity>=2) { if(totdoc % 100 == 0) { printf("%ld..",totdoc); fflush(stdout); } } } free(line); free(words); free_model(model,1); if(verbosity>=2) { printf("done\n"); /* Note by Gary Boone Date: 29 April 2000 */ /* o Timing is inaccurate. The timer has 0.01 second resolution. */ /* Because classification of a single vector takes less than */ /* 0.01 secs, the timer was underflowing. */ printf("Runtime (without IO) in cpu-seconds: %.2f\n", (float)(runtime/100.0)); } if((!no_accuracy) && (verbosity>=1)) { printf("Accuracy on test set: %.2f%% (%ld correct, %ld incorrect, %ld total)\n",(float)(correct)*100.0/totdoc,correct,incorrect,totdoc); printf("Precision/recall on test set: %.2f%%/%.2f%%\n",(float)(res_a)*100.0/(res_a+res_b),(float)(res_a)*100.0/(res_a+res_c)); } return(0); }
SVECTOR* find_cutting_plane(EXAMPLE *ex, SVECTOR **fycache, double *margin, long m, STRUCTMODEL *sm, STRUCT_LEARN_PARM *sparm, int *valid_examples) { long i, j; SVECTOR *f, *fy, *fybar, *lhs; LABEL ybar; double lossval; double *new_constraint; long valid_count = 0; long l,k; SVECTOR *fvec; WORD *words; /* find cutting plane */ lhs = NULL; *margin = 0; for (i=0;i<m;i++) { if (valid_examples[i]) { valid_count++; } } for (i=0;i<m;i++) { if (!valid_examples[i]) { continue; } find_most_violated_constraint_marginrescaling(ex[i].x, ex[i].y, &ybar, sm, sparm); /* get difference vector */ fy = copy_svector(fycache[i]); fybar = psi(ex[i].x,ybar,sm,sparm); lossval = loss(ex[i].y,ybar,sparm); free_label(ybar); /* scale difference vector */ for (f=fy;f;f=f->next) { //f->factor*=1.0/m; //f->factor*=ex[i].x.example_cost/m; f->factor*=ex[i].x.example_cost/valid_count; } for (f=fybar;f;f=f->next) { //f->factor*=-1.0/m; //f->factor*=-ex[i].x.example_cost/m; f->factor*=-ex[i].x.example_cost/valid_count; } /* add ybar to constraint */ append_svector_list(fy,lhs); append_svector_list(fybar,fy); lhs = fybar; //*margin+=lossval/m; //*margin+=lossval*ex[i].x.example_cost/m; *margin+=lossval*ex[i].x.example_cost/valid_count; } /* compact the linear representation */ new_constraint = add_list_nn(lhs, sm->sizePsi); free_svector(lhs); l=0; for (i=1;i<sm->sizePsi+1;i++) { if (fabs(new_constraint[i])>1E-10) l++; // non-zero } words = (WORD*)my_malloc(sizeof(WORD)*(l+1)); assert(words!=NULL); k=0; for (i=1;i<sm->sizePsi+1;i++) { if (fabs(new_constraint[i])>1E-10) { words[k].wnum = i; words[k].weight = new_constraint[i]; k++; } } words[k].wnum = 0; words[k].weight = 0.0; fvec = create_svector(words,"",1); free(words); free(new_constraint); return(fvec); }
void SVMLightRunner::libraryReadDocuments ( char *docfile, DOC ***docs, double **label, long int *totwords, long int *totdoc, bool use_gmumr, SVMConfiguration &config ) { LOG( config.log, LogLevel::DEBUG_LEVEL, __debug_prefix__ + ".libraryReadDocuments() Started." ); char *line,*comment; WORD *words; long dnum=0,wpos,dpos=0,dneg=0,dunlab=0,queryid,slackid,max_docs; long max_words_doc, ll; double doc_label,costfactor; FILE *docfl; if(verbosity>=1) { C_PRINTF("Scanning examples..."); C_FFLUSH(stdout); } // GMUM.R changes { if (!use_gmumr) { nol_ll(docfile,&max_docs,&max_words_doc,&ll); /* scan size of input file */ } else { max_docs = config.target.n_rows; max_words_doc = config.getDataDim(); // ll used only for file reading } // GMUM.R changes } max_words_doc+=2; ll+=2; max_docs+=2; if(verbosity>=1) { C_PRINTF("done\n"); C_FFLUSH(stdout); } (*docs) = (DOC **)my_malloc(sizeof(DOC *)*max_docs); /* feature vectors */ (*label) = (double *)my_malloc(sizeof(double)*max_docs); /* target values */ // GMUM.R changes { if (!use_gmumr) { line = (char *)my_malloc(sizeof(char)*ll); if ((docfl = fopen (docfile, "r")) == NULL) { perror (docfile); EXIT (1); } } // GMUM.R changes } words = (WORD *)my_malloc(sizeof(WORD)*(max_words_doc+10)); if(verbosity>=1) { C_PRINTF("Reading examples into memory..."); C_FFLUSH(stdout); } dnum=0; (*totwords)=0; // GMUM.R changes { bool newline; if (!use_gmumr) { newline = (!feof(docfl)) && fgets(line,(int)ll,docfl); } else { newline = false; if (dnum < config.target.n_rows) { newline = true; std::string str = SVMConfigurationToSVMLightLearnInputLine(config, dnum); line = new char[str.size() + 1]; std::copy(str.begin(), str.end(), line); line[str.size()] = '\0'; } } while(newline) { if (use_gmumr) { std::string stringline = ""; } // GMUM.R changes } if(line[0] == '#') continue; /* line contains comments */ if(!parse_document(line,words,&doc_label,&queryid,&slackid,&costfactor, &wpos,max_words_doc,&comment)) { C_PRINTF("\nParsing error in line %ld!\n%s",dnum,line); EXIT(1); } (*label)[dnum]=doc_label; /* C_PRINTF("docnum=%ld: Class=%f ",dnum,doc_label); */ if(doc_label > 0) dpos++; if (doc_label < 0) dneg++; if (doc_label == 0) { if(config.use_transductive_learning){ dunlab++; }else{ C_PRINTF("Please for transductive learning pass use_transductive_learning\n"); EXIT(1); } } if((wpos>1) && ((words[wpos-2]).wnum>(*totwords))) (*totwords)=(words[wpos-2]).wnum; if((*totwords) > MAXFEATNUM) { C_PRINTF("\nMaximum feature number exceeds limit defined in MAXFEATNUM!\n"); EXIT(1); } (*docs)[dnum] = create_example(dnum,queryid,slackid,costfactor, create_svector(words,comment,1.0)); /* C_PRINTF("\nNorm=%f\n",((*docs)[dnum]->fvec)->twonorm_sq); */ dnum++; if(verbosity>=1) { if((dnum % 100) == 0) { C_PRINTF("%ld..",dnum); C_FFLUSH(stdout); } } // GMUM.R changes { if (!use_gmumr) { newline = (!feof(docfl)) && fgets(line,(int)ll,docfl); } else { newline = false; if (dnum < config.target.n_rows) { newline = true; std::string str = SVMConfigurationToSVMLightLearnInputLine(config, dnum); line = new char[str.size() + 1]; std::copy(str.begin(), str.end(), line); line[str.size()] = '\0'; } } // GMUM.R changes } } if (!use_gmumr) { fclose(docfl); free(line); }; free(words); if(verbosity>=1) { C_FPRINTF(stdout, "OK. (%ld examples read)\n", dnum); } (*totdoc)=dnum; }
SVECTOR *psi(PATTERN x, LABEL y, STRUCTMODEL *sm, STRUCT_LEARN_PARM *sparm) { /* Creates the feature vector \Psi(x,y) and return a pointer to sparse vector SVECTOR in SVM^light format. The dimension of the feature vector returned has to agree with the dimension in sm->sizePsi. */ SVECTOR *fvec=NULL; SVECTOR *psi1=NULL; SVECTOR *psi2=NULL; SVECTOR *temp_psi=NULL; SVECTOR *temp_sub=NULL; WORD *words = NULL; words = (WORD *) malloc(sizeof(WORD)); if(!words) die("Memory error."); words[0].wnum = 0; words[0].weight = 0; fvec = create_svector(words,"",1); psi1 = create_svector(words,"",1); psi2 = create_svector(words,"",1); free(words); int i,j = 0; for (i = 0; i < (x.n_pos+x.n_neg); i++){ if(y.labels[i] == 1){ temp_psi = add_ss(psi1, x.x_is[i].phi1phi2_pos); } else{ temp_psi = add_ss(psi1, x.x_is[i].phi1phi2_neg); } free_svector(psi1); psi1 = temp_psi; for (j=(i+1); j < (x.n_pos+x.n_neg); j++){ if(x.neighbors[i][j]){ if(y.labels[i] != y.labels[j]){ temp_sub = sub_ss_sq(x.x_is[i].phi1phi2_pos, x.x_is[j].phi1phi2_pos); temp_psi = add_ss(psi2, temp_sub); free_svector(temp_sub); free_svector(psi2); psi2 = temp_psi; } } } } // scale w1 by 1/n temp_psi = smult_s(psi1, (float)1/(float)(x.n_pos+x.n_neg)); free_svector(psi1); psi1 = temp_psi; // scale w2 by 1/n^2 if (x.n_neighbors){ temp_psi = smult_s(psi2, (float)1/(float)x.n_neighbors); free_svector(psi2); psi2 = temp_psi; } // concatenate psi1, psi2 temp_psi = create_svector_with_index(psi2->words, "", 1, (sparm->phi1_size+sparm->phi2_size)*2); free_svector(psi2); fvec = add_ss(psi1, temp_psi); free_svector(temp_psi); free_svector(psi1); return(fvec); }
MODEL *read_model(char *modelfile) { FILE *modelfl; long i,queryid,slackid; double costfactor; long max_sv,max_words,ll,wpos; char *line,*comment; WORD *words; char version_buffer[100]; MODEL *model; if(verbosity>=1) { printf("Reading model..."); fflush(stdout); } nol_ll(modelfile,&max_sv,&max_words,&ll); /* scan size of model file */ max_words+=2; ll+=2; words = (WORD *)my_malloc(sizeof(WORD)*(max_words+10)); line = (char *)my_malloc(sizeof(char)*ll); model = (MODEL *)my_malloc(sizeof(MODEL)); if ((modelfl = fopen (modelfile, "r")) == NULL) { perror (modelfile); exit (1); } fscanf(modelfl,"SVM-light Version %s\n",version_buffer); if(strcmp(version_buffer,VERSION)) { perror ("Version of model-file does not match version of svm_classify!"); exit (1); } fscanf(modelfl,"%ld%*[^\n]\n", &model->kernel_parm.kernel_type); fscanf(modelfl,"%ld%*[^\n]\n", &model->kernel_parm.poly_degree); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.rbf_gamma); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.coef_lin); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.coef_const); fscanf(modelfl,"%[^#]%*[^\n]\n", model->kernel_parm.custom); fscanf(modelfl,"%ld%*[^\n]\n", &model->totwords); fscanf(modelfl,"%ld%*[^\n]\n", &model->totdoc); fscanf(modelfl,"%ld%*[^\n]\n", &model->sv_num); fscanf(modelfl,"%lf%*[^\n]\n", &model->b); model->supvec = (DOC **)my_malloc(sizeof(DOC *)*model->sv_num); model->alpha = (double *)my_malloc(sizeof(double)*model->sv_num); model->index=NULL; model->lin_weights=NULL; for(i=1;i<model->sv_num;i++) { fgets(line,(int)ll,modelfl); if(!parse_document(line,words,&(model->alpha[i]),&queryid,&slackid, &costfactor,&wpos,max_words,&comment)) { printf("\nParsing error while reading model file in SV %ld!\n%s", i,line); exit(1); } model->supvec[i] = create_example(-1, 0,0, 0.0, create_svector(words,comment,1.0)); } fclose(modelfl); free(line); free(words); if(verbosity>=1) { fprintf(stdout, "OK. (%d support vectors read)\n",(int)(model->sv_num-1)); } return(model); }
STRUCTMODEL read_struct_model(char *file, STRUCT_LEARN_PARM *sparm) { /* Reads structural model sm from file file. This function is used only in the prediction module, not in the learning module. */ FILE *modelfl; STRUCTMODEL sm; long i,queryid,slackid; double costfactor; long max_sv,max_words,ll,wpos; char *line,*comment; TOKEN *words; char version_buffer[100]; MODEL *model; nol_ll(file,&max_sv,&max_words,&ll); /* scan size of model file */ max_words+=2; ll+=2; words = (TOKEN *)my_malloc(sizeof(TOKEN)*(max_words+10)); line = (char *)my_malloc(sizeof(char)*ll); model = (MODEL *)my_malloc(sizeof(MODEL)); if ((modelfl = fopen (file, "r")) == NULL) { perror (file); exit (1); } fscanf(modelfl,"SVM-multiclass Version %s\n",version_buffer); if(strcmp(version_buffer,INST_VERSION)) { perror ("Version of model-file does not match version of svm_struct_classify!"); exit (1); } fscanf(modelfl,"%d%*[^\n]\n", &sparm->num_classes); fscanf(modelfl,"%d%*[^\n]\n", &sparm->num_features); fscanf(modelfl,"%d%*[^\n]\n", &sparm->loss_function); fscanf(modelfl,"%ld%*[^\n]\n", &model->kernel_parm.kernel_type); fscanf(modelfl,"%ld%*[^\n]\n", &model->kernel_parm.poly_degree); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.rbf_gamma); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.coef_lin); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.coef_const); fscanf(modelfl,"%[^#]%*[^\n]\n", model->kernel_parm.custom); fscanf(modelfl,"%ld%*[^\n]\n", &model->totwords); fscanf(modelfl,"%ld%*[^\n]\n", &model->totdoc); fscanf(modelfl,"%ld%*[^\n]\n", &model->sv_num); fscanf(modelfl,"%lf%*[^\n]\n", &model->b); model->supvec = (DOC **)my_malloc(sizeof(DOC *)*model->sv_num); model->alpha = (double *)my_malloc(sizeof(double)*model->sv_num); model->index=NULL; model->lin_weights=NULL; for(i=1;i<model->sv_num;i++) { fgets(line,(int)ll,modelfl); if(!parse_document(line,words,&(model->alpha[i]),&queryid,&slackid, &costfactor,&wpos,max_words,&comment, true)) { printf("\nParsing error while reading model file in SV %ld!\n%s", i,line); exit(1); } model->supvec[i] = create_example(-1,0,0,0.0, create_svector(words,comment,1.0)); model->supvec[i]->fvec->kernel_id=queryid; } fclose(modelfl); free(line); free(words); if(verbosity>=1) { fprintf(stdout, " (%d support vectors read) ",(int)(model->sv_num-1)); } sm.svm_model=model; sm.sizePsi=model->totwords; sm.w=NULL; return(sm); }
SVECTOR* add_list_sort_ss_r(SVECTOR *a, double min_non_zero) /* Like add_list_sort_ss(SVECTOR *a), but rounds values smaller than min_non_zero to zero. */ { SVECTOR *sum,*f; WORD empty[2],*ai,*concat,*concati,*concat_read,*concat_write; long length,i; double weight; if(a){ /* count number or entries over all vectors */ length=0; for(f=a;f;f=f->next) { ai=f->words; while (ai->wnum) { length++; ai++; } } /* write all entries into one long array and sort by feature number */ concat=(WORD *)my_malloc(sizeof(WORD)*(length+1)); concati=concat; for(f=a;f;f=f->next) { ai=f->words; while (ai->wnum) { (*concati)=(*ai); concati->weight*=f->factor; concati++; ai++; } } qsort(concat,length,sizeof(WORD),compareup_word); concat_read=concat+1; concat_write=concat; for(i=0;(i<length-1) && (concat_write->wnum != concat_read->wnum);i++) { concat_write++; concat_read++; } weight=concat_write->weight; for(i=i;(i<length-1);i++) { if(concat_write->wnum == concat_read->wnum) { weight+=(double)concat_read->weight; concat_read++; } else { if((weight > min_non_zero) || (weight < -min_non_zero)) { concat_write->weight=weight; concat_write++; } (*concat_write)=(*concat_read); weight=concat_write->weight; concat_read++; } } if((length>0) && ((weight > min_non_zero) || (weight < -min_non_zero))) { concat_write->weight=weight; concat_write++; } concat_write->wnum=0; if(1) { /* this wastes some memory, but saves malloc'ing */ sum=create_svector_shallow(concat,NULL,1.0); } else { /* this is more memory efficient */ sum=create_svector(concat,NULL,1.0); free(concat); } } else { empty[0].wnum=0; sum=create_svector(empty,NULL,1.0); } return(sum); }
/* save constraints in structmodel for training the full model in the future */ void save_constraints(STRUCT_LEARN_PARM *sparm, STRUCTMODEL *sm) { int i, count; CONSTSET c; /* read the constraints */ c = read_constraints(sparm->confile, sm); count = 0; for(i = 0; i < c.m; i++) { sparm->cset.lhs = (DOC**)realloc(sparm->cset.lhs, sizeof(DOC*)*(sparm->cset.m+1)); sparm->cset.lhs[sparm->cset.m] = create_example(sparm->cset.m, 0, 1000000+sparm->cset.m, 1, create_svector(c.lhs[i]->fvec->words, "", 1.0)); sparm->cset.rhs = (double*)realloc(sparm->cset.rhs, sizeof(double)*(sparm->cset.m+1)); sparm->cset.rhs[sparm->cset.m] = c.rhs[i]; sparm->cset.m++; count++; } /* clean up */ free(c.rhs); for(i = 0; i < c.m; i++) free_example(c.lhs[i], 1); free(c.lhs); printf("%d constraints added, totally %d constraints\n", count, sparm->cset.m); }
double cutting_plane_algorithm(double *w, long m, int MAX_ITER, double C, /*double epsilon,*/ SVECTOR **fycache, EXAMPLE *ex, STRUCTMODEL *sm, STRUCT_LEARN_PARM *sparm) { long i,j; double *alpha; double **G; /* Gram matrix */ DOC **dXc; /* constraint matrix */ double *delta; /* rhs of constraints */ SVECTOR *new_constraint; double dual_obj/*, alphasum*/; int iter, size_active, no_violation_iter; double value; //int r; //int *idle; /* for cleaning up */ double margin; //double primal_obj; double lower_bound, approx_upper_bound; double *proximal_rhs; //double *gammaG0=NULL; //double min_rho = 0.001; //double max_rho; //double serious_counter=0; //double rho = 1.0; //double expected_descent, primal_obj_b=-1, reg_master_obj; //int null_step=1; //double *w_b; //double kappa=0.01; //double temp_var; //double proximal_term, primal_lower_bound; //double v_k; //double obj_difference; // double *cut_error; // cut_error[i] = alpha_{k,i} at current center x_k //double sigma_k; //double m2 = 0.2; //double m3 = 0.9; //double gTd; //double last_sigma_k=0; //double initial_primal_obj; //int suff_decrease_cond=0; //double decrease_proportion = 0.2; // start from 0.2 first //double z_k_norm; //double last_z_k_norm=0; /* w_b = create_nvector(sm->sizePsi); clear_nvector(w_b,sm->sizePsi); // warm start for (i=1;i<sm->sizePsi+1;i++) { w_b[i] = w[i]; }*/ iter = 0; no_violation_iter = 0; size_active = 0; alpha = NULL; G = NULL; dXc = NULL; delta = NULL; //idle = NULL; proximal_rhs = NULL; //cut_error = NULL; new_constraint = find_cutting_plane(ex, fycache, &margin, m, sm, sparm); value = margin - sprod_ns(w, new_constraint); //primal_obj_b = 0.5*sprod_nn(w_b,w_b,sm->sizePsi)+C*value; //primal_obj = 0.5*sprod_nn(w,w,sm->sizePsi)+C*value; //primal_lower_bound = 0; //expected_descent = -primal_obj_b; //initial_primal_obj = primal_obj_b; //max_rho = C; // Non negative weight constraints int nNonNeg = sm->sizePsi - sm->firstNonNegWeightIndex + 1; G = (double**)malloc(sizeof(double*)*nNonNeg); for (j=0; j<nNonNeg; j++) { G[j] = (double*)malloc(sizeof(double)*nNonNeg); for (int k=0; k<nNonNeg; k++) { G[j][k] = 0; } G[j][j] = 1.0; } double* alphabeta = NULL; while (/*(!suff_decrease_cond)&&(expected_descent<-epsilon)&&*/(iter<MAX_ITER)&&(no_violation_iter<MAX_INNER_ITER_NO_VIOLATION)) { LearningTracker::NextInnerIteration(); iter+=1; size_active+=1; #if (DEBUG_LEVEL>0) printf("INNER ITER %d\n", iter); #endif /* add constraint */ dXc = (DOC**)realloc(dXc, sizeof(DOC*)*size_active); assert(dXc!=NULL); dXc[size_active-1] = (DOC*)malloc(sizeof(DOC)); dXc[size_active-1]->fvec = new_constraint; dXc[size_active-1]->slackid = 1; // only one common slackid (one-slack) dXc[size_active-1]->costfactor = 1.0; delta = (double*)realloc(delta, sizeof(double)*size_active); assert(delta!=NULL); delta[size_active-1] = margin; alphabeta = (double*)realloc(alphabeta, sizeof(double)*(size_active+nNonNeg)); assert(alphabeta!=NULL); alphabeta[size_active+nNonNeg-1] = 0.0; /*idle = (int*)realloc(idle, sizeof(int)*size_active); assert(idle!=NULL); idle[size_active-1] = 0;*/ /* proximal point */ proximal_rhs = (double*)realloc(proximal_rhs, sizeof(double)*(size_active+nNonNeg)); assert(proximal_rhs!=NULL); /*cut_error = (double*)realloc(cut_error, sizeof(double)*size_active); assert(cut_error!=NULL); // note g_i = - new_constraint cut_error[size_active-1] = C*(sprod_ns(w_b, new_constraint) - sprod_ns(w, new_constraint)); cut_error[size_active-1] += (primal_obj_b - 0.5*sprod_nn(w_b,w_b,sm->sizePsi)); cut_error[size_active-1] -= (primal_obj - 0.5*sprod_nn(w,w,sm->sizePsi)); */ /*gammaG0 = (double*)realloc(gammaG0, sizeof(double)*size_active); assert(gammaG0!=NULL);*/ /* update Gram matrix */ G = (double**)realloc(G, sizeof(double*)*(size_active+nNonNeg)); assert(G!=NULL); G[size_active+nNonNeg-1] = NULL; for (j=0; j<size_active+nNonNeg; j++) { G[j] = (double*)realloc(G[j], sizeof(double)*(size_active+nNonNeg)); assert(G[j]!=NULL); } for (j=0; j<size_active-1; j++) { G[size_active+nNonNeg-1][j+nNonNeg] = sprod_ss(dXc[size_active-1]->fvec, dXc[j]->fvec); G[j+nNonNeg][size_active+nNonNeg-1] = G[size_active+nNonNeg-1][j+nNonNeg]; } G[size_active+nNonNeg-1][size_active+nNonNeg-1] = sprod_ss(dXc[size_active-1]->fvec,dXc[size_active-1]->fvec); for (j=0; j<nNonNeg; j++) { WORD indicator[2]; indicator[0].wnum = j + sm->firstNonNegWeightIndex; indicator[0].weight = 1.0; indicator[1].wnum = 0; indicator[1].weight = 0.0; SVECTOR* indicator_vec = create_svector(indicator, NULL, 1.0); G[size_active+nNonNeg-1][j] = sprod_ss(dXc[size_active-1]->fvec, indicator_vec); G[j][size_active+nNonNeg-1] = G[size_active+nNonNeg-1][j]; free_svector(indicator_vec); } /* update gammaG0 */ /*if (null_step==1) { gammaG0[size_active-1] = sprod_ns(w_b, dXc[size_active-1]->fvec); } else { for (i=0;i<size_active;i++) { gammaG0[i] = sprod_ns(w_b, dXc[i]->fvec); } }*/ /* update proximal_rhs */ for (i=0; i<size_active; i++) { proximal_rhs[i+nNonNeg] = -delta[i]; //(1+rho) * (rho * gammaG0[i] - (1 + rho) * delta[i]); } for (i=0; i<nNonNeg; i++) { proximal_rhs[i] = 0; //w_b[i + 1]*rho * (1+rho); } /* DEBUG */ /* for (i = 0; i < size_active + nNonNeg; ++i) { printf("G[%d]=", i); for (j = 0; j < size_active + nNonNeg; ++j) { printf("%.4f ", G[i][j]); } printf("\n"); } printf("\n"); for (i = 0; i < size_active + nNonNeg; ++i) printf("proximal_rhs[%d]=%.4f\n", i, proximal_rhs[i]); */ /* solve QP to update alpha */ dual_obj = 0; mosek_qp_optimize(G, proximal_rhs, alphabeta, (long) size_active+nNonNeg, C, &dual_obj, nNonNeg); printf("dual_obj=%.4lf\n", dual_obj); alpha = alphabeta + nNonNeg; clear_nvector(w,sm->sizePsi); for (i = 0; i < nNonNeg; i++) { w[sm->firstNonNegWeightIndex + i] = alphabeta[i];//alphabeta[i]/(1+rho); // add betas } for (j=0; j<size_active; j++) { if (alpha[j]>C*ALPHA_THRESHOLD) { //add_vector_ns(w,dXc[j]->fvec,alpha[j]/(1+rho)); add_vector_ns(w,dXc[j]->fvec,alpha[j]); } } //z_k_norm = sqrt(sprod_nn(w,w,sm->sizePsi)); //add_vector_nn(w, w_b, sm->sizePsi, rho/(1+rho)); LearningTracker::ReportWeights(w, sm->sizePsi); /* detect if step size too small */ /* sigma_k = 0; alphasum = 0; for (j=0;j<size_active;j++) { sigma_k += alpha[j]*cut_error[j]; alphasum+=alpha[j]; } sigma_k/=C; gTd = -C*(sprod_ns(w,new_constraint) - sprod_ns(w_b,new_constraint)); #if (DEBUG_LEVEL>0) for (j=0;j<size_active;j++) { printf("alpha[%d]: %.8g, cut_error[%d]: %.8g\n", j, alpha[j], j, cut_error[j]); } printf("sigma_k: %.8g\n", sigma_k); printf("alphasum: %.8g\n", alphasum); printf("g^T d: %.8g\n", gTd); fflush(stdout); #endif */ /* update cleanup information */ /* for (j=0;j<size_active;j++) { if (alpha[j]<ALPHA_THRESHOLD*C) { idle[j]++; } else { idle[j]=0; } } */ // update lower bound double xi = -1e+20; for (i = 0; i < size_active; ++i) { xi = MAX(xi, delta[i] - sprod_ns(w, dXc[i]->fvec)); } lower_bound = 0.5*sprod_nn(w,w,sm->sizePsi)+C*xi; printf("lower_bound=%.4lf\n", lower_bound); assert(fabs(lower_bound + dual_obj) < 1e-6); LearningTracker::ReportLowerBound(lower_bound); // find new constraint new_constraint = find_cutting_plane(ex, fycache, &margin, m, sm, sparm); value = margin - sprod_ns(w, new_constraint); double violation = value - xi; if (violation > CUTTING_PLANE_EPS) { printf("New constraint is violated by %.4lf\n", violation); no_violation_iter = 0; } else { ++no_violation_iter; printf("New constraint is underviolated by %.4lf\n", violation); printf("%d more such constraints to stop\n", MAX_INNER_ITER_NO_VIOLATION - no_violation_iter); } // update upper bound approx_upper_bound = 0.5*sprod_nn(w,w,sm->sizePsi)+C*value; printf("approx_upper_bound=%.4lf\n", approx_upper_bound); LearningTracker::ReportUpperBound(approx_upper_bound); /* temp_var = sprod_nn(w_b,w_b,sm->sizePsi); proximal_term = 0.0; for (i=1;i<sm->sizePsi+1;i++) { proximal_term += (w[i]-w_b[i])*(w[i]-w_b[i]); } reg_master_obj = -dual_obj+0.5*rho*temp_var/(1+rho); expected_descent = reg_master_obj - primal_obj_b; v_k = (reg_master_obj - proximal_term*rho/2) - primal_obj_b; primal_lower_bound = MAX(primal_lower_bound, reg_master_obj - 0.5*rho*(1+rho)*proximal_term); LearningTracker::ReportLowerBoundValue(reg_master_obj); #if (DEBUG_LEVEL>0) printf("ITER REG_MASTER_OBJ: %.4f\n", reg_master_obj); printf("ITER EXPECTED_DESCENT: %.4f\n", expected_descent); printf("ITER PRIMAL_OBJ_B: %.4f\n", primal_obj_b); printf("ITER RHO: %.4f\n", rho); printf("ITER ||w-w_b||^2: %.4f\n", proximal_term); printf("ITER PRIMAL_LOWER_BOUND: %.4f\n", primal_lower_bound); printf("ITER V_K: %.4f\n", v_k); #endif obj_difference = primal_obj - primal_obj_b; if (primal_obj<primal_obj_b+kappa*expected_descent) { // extra condition to be met if ((gTd>m2*v_k)||(rho<min_rho+1E-8)) { #if (DEBUG_LEVEL>0) printf("SERIOUS STEP\n"); #endif // update cut_error for (i=0;i<size_active;i++) { cut_error[i] -= (primal_obj_b - 0.5*sprod_nn(w_b,w_b,sm->sizePsi)); cut_error[i] -= C*sprod_ns(w_b, dXc[i]->fvec); cut_error[i] += (primal_obj - 0.5*sprod_nn(w,w,sm->sizePsi)); cut_error[i] += C*sprod_ns(w, dXc[i]->fvec); } primal_obj_b = primal_obj; for (i=1;i<sm->sizePsi+1;i++) { w_b[i] = w[i]; } null_step = 0; serious_counter++; } else { // increase step size #if (DEBUG_LEVEL>0) printf("NULL STEP: SS(ii) FAILS.\n"); #endif serious_counter--; rho = MAX(rho/10,min_rho); } } else { // no sufficient decrease serious_counter--; if ((cut_error[size_active-1]>m3*last_sigma_k)&&(fabs(obj_difference)>last_z_k_norm+last_sigma_k)) { #if (DEBUG_LEVEL>0) printf("NULL STEP: NS(ii) FAILS.\n"); #endif rho = MIN(10*rho,max_rho); } #if (DEBUG_LEVEL>0) else printf("NULL STEP\n"); #endif } // update last_sigma_k last_sigma_k = sigma_k; last_z_k_norm = z_k_norm; // break away from while loop if more than certain proportioal decrease in primal objective if (primal_obj_b/initial_primal_obj<1-decrease_proportion) { suff_decrease_cond = 1; } // clean up if (iter % CLEANUP_CHECK == 0) { size_active = resize_cleanup(size_active, idle, alpha, delta, gammaG0, proximal_rhs, G, dXc, cut_error); } */ } // end cutting plane while loop printf("Inner loop optimization finished.\n"); fflush(stdout); /* free memory */ for (j=0; j<size_active; j++) { free(G[j]); free_example(dXc[j],0); } free(G); free(dXc); free(alphabeta); free(delta); free_svector(new_constraint); //free(idle); //free(gammaG0); free(proximal_rhs); //free(cut_error); /* copy and free */ /*for (i=1;i<sm->sizePsi+1;i++) { w[i] = w_b[i]; } free(w_b);*/ //return(primal_obj_b); return lower_bound; }
SVECTOR* multadd_ss_r(SVECTOR *a,SVECTOR *b,double fa, double fb, double min_non_zero) /* compute fa*a+fb*b of two sparse vectors */ /* Note: SVECTOR lists are not followed, but only the first SVECTOR is used */ { SVECTOR *vec; register WORD *sum,*sumi; register WORD *ai,*bj; long veclength; double weight; ai=a->words; bj=b->words; veclength=0; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { veclength++; bj++; } else if (ai->wnum < bj->wnum) { veclength++; ai++; } else { veclength++; ai++; bj++; } } while (bj->wnum) { veclength++; bj++; } while (ai->wnum) { veclength++; ai++; } veclength++; sum=(WORD *)my_malloc(sizeof(WORD)*veclength); sumi=sum; ai=a->words; bj=b->words; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { (*sumi)=(*bj); sumi->weight*=fb; sumi++; bj++; } else if (ai->wnum < bj->wnum) { (*sumi)=(*ai); sumi->weight*=fa; sumi++; ai++; } else { weight=fa*(double)ai->weight+fb*(double)bj->weight; if((weight<-min_non_zero) || (weight>min_non_zero)) { sumi->wnum=ai->wnum; sumi->weight=weight; sumi++; } ai++; bj++; } } while (bj->wnum) { (*sumi)=(*bj); sumi->weight*=fb; sumi++; bj++; } while (ai->wnum) { (*sumi)=(*ai); sumi->weight*=fa; sumi++; ai++; } sumi->wnum=0; if(1) { /* potentially this wastes some memory, but saves malloc'ing */ vec=create_svector_shallow(sum,NULL,1.0); } else { /* this is more memory efficient */ vec=create_svector(sum,NULL,1.0); free(sum); } return(vec); }
SVECTOR *psi(PATTERN x, LABEL y, STRUCTMODEL *sm, STRUCT_LEARN_PARM *sparm) { /* Returns a feature vector describing the match between pattern x and label y. The feature vector is returned as a list of SVECTOR's. Each SVECTOR is in a sparse representation of pairs <featurenumber:featurevalue>, where the last pair has featurenumber 0 as a terminator. Featurenumbers start with 1 and end with sizePsi. Featuresnumbers that are not specified default to value 0. As mentioned before, psi() actually returns a list of SVECTOR's. Each SVECTOR has a field 'factor' and 'next'. 'next' specifies the next element in the list, terminated by a NULL pointer. The list can be though of as a linear combination of vectors, where each vector is weighted by its 'factor'. This linear combination of feature vectors is multiplied with the learned (kernelized) weight vector to score label y for pattern x. Without kernels, there will be one weight in sm.w for each feature. Note that psi has to match find_most_violated_constraint_???(x, y, sm) and vice versa. In particular, find_most_violated_constraint_???(x, y, sm) finds that ybar!=y that maximizes psi(x,ybar,sm)*sm.w (where * is the inner vector product) and the appropriate function of the loss + margin/slack rescaling method. See that paper for details. */ //cout << "psi_1\n"; SVECTOR *fvec = NULL; WORD words[sm->sizePsi+1]; /* insert code for computing the feature vector for x and y here */ int i, j; for (i = 0; i < sm->sizePsi; i++) { words[i].wnum = i+1; words[i].weight = 0.0; } words[sm->sizePsi].wnum = 0; // for terminator /*for (int i= 0; i < y.frame_num; i++){ cout << i<<":"; cout << y.state_object[i] << " "; } cout << endl;*/ // build psi_observation put into psi_feature[label] for (i = 0; i < x.frame_num; i++) { for (j = 0; j < OBSERVE_ELEMENT_DIM; j++) { words[y.state_object[i]*OBSERVE_ELEMENT_DIM + j].weight += x.observe_object[i][j]; } } //cout << "psi_2\n"; /*cout << x.frame_num << y.frame_num<< endl; if (y.frame_num == 474){ cout << "yee" <<endl; cout << y.state_object[359]; }*/ //cout << endl; //cerr << "psi_fuck\n"; //cout << "sizePsi:" << sm->sizePsi <<endl; // build psi_transition put 1 into psi_feature[labeli->labelj] if i->j //cerr<<OBSERVE_ELEMENT_DIM*STATE_TYPES + y.state_object[0]*STATE_TYPES + y.state_object[1]; for (i = 1; i < x.frame_num; i++) { cerr << i << " "; words[OBSERVE_ELEMENT_DIM*STATE_TYPES + y.state_object[i-1]*STATE_TYPES + y.state_object[i]].weight += 1.0; } //cout << "psi_3\n"; fvec = create_svector(words, 0, 1.0); //printf("psi function is finished.\n"); //cout << "psi_4\n"; return(fvec); }
SVECTOR* multadd_ss(SVECTOR *a, SVECTOR *b, double factor) /* compute a+factor*b of two sparse vectors */ /* Note: SVECTOR lists are not followed, but only the first SVECTOR is used */ { SVECTOR *vec; register SVM_WORD *sum,*sumi; register SVM_WORD *ai,*bj; long veclength; ai=a->words; bj=b->words; veclength=0; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { veclength++; bj++; } else if (ai->wnum < bj->wnum) { veclength++; ai++; } else { veclength++; ai++; bj++; } } while (bj->wnum) { veclength++; bj++; } while (ai->wnum) { veclength++; ai++; } veclength++; sum=(SVM_WORD *)my_malloc(sizeof(SVM_WORD)*veclength); sumi=sum; ai=a->words; bj=b->words; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { (*sumi)=(*bj); sumi->weight*=factor; sumi++; bj++; } else if (ai->wnum < bj->wnum) { (*sumi)=(*ai); sumi++; ai++; } else { (*sumi)=(*ai); sumi->weight+=factor*bj->weight; if(sumi->weight != 0) sumi++; ai++; bj++; } } while (bj->wnum) { (*sumi)=(*bj); sumi->weight*=factor; sumi++; bj++; } while (ai->wnum) { (*sumi)=(*ai); sumi++; ai++; } sumi->wnum=0; vec=create_svector(sum,"",1.0); free(sum); return(vec); }
int Classifier::getZone(IplImage* frame, double& confidence, FrameAnnotation& fa) { if (!leftEye || !rightEye || !nose) { string err = "Classifier::getZone. Location extractors malformed."; throw (err); } // the roi offset CvPoint offset; // LOIs CvPoint leftEyeLocation; CvPoint rightEyeLocation; CvPoint noseLocation; // computing the confidence of the location identification double leftPSR; double rightPSR; double nosePSR; CvPoint center = fa.getLOI(Annotations::Face); if (!center.x || !center.y) { center.x = Globals::imgWidth / 2; center.y = Globals::imgHeight / 2; fa.setFace(center); } offset.x = offset.y = 0; IplImage* roi = (roiFunction)? roiFunction(frame, fa, offset, Annotations::Face) : 0; // all location extractors do identical preprocessing. Therefore, preprocess // once using say the left eye extractor and re-use it for all three extractors fftw_complex* preprocessedImage = leftEye->getPreprocessedImage((roi)? roi : frame); #pragma omp parallel sections num_threads(2) { #pragma omp section { leftEye->setImage(preprocessedImage); leftEye->apply(); leftEye->getMaxLocation(leftEyeLocation, leftPSR); leftEyeLocation.x += offset.x; leftEyeLocation.y += offset.y; } #pragma omp section { // get the location of the right eye rightEye->setImage(preprocessedImage); rightEye->apply(); rightEye->getMaxLocation(rightEyeLocation, rightPSR); rightEyeLocation.x += offset.x; rightEyeLocation.y += offset.y; } } if (roi) cvReleaseImage(&roi); center.x = (leftEyeLocation.x + rightEyeLocation.x) / 2; center.y = leftEyeLocation.y + Globals::noseDrop; fa.setNose(center); offset.x = offset.y = 0; roi = (roiFunction)? roiFunction(frame, fa, offset, Annotations::Nose) : 0; // free the preprocessed image fftw_free(preprocessedImage); // all location extractors do identical preprocessing. Therefore, preprocess // once using say the left eye extractor and re-use it for all three extractors preprocessedImage = nose->getPreprocessedImage((roi)? roi : frame); // get the location of the nose nose->setImage(preprocessedImage); nose->apply(); nose->getMaxLocation(noseLocation, nosePSR); noseLocation.x += offset.x; noseLocation.y += offset.y; // free the preprocessed image fftw_free(preprocessedImage); fa.setLeftIris(leftEyeLocation); fa.setRightIris(rightEyeLocation); fa.setNose(noseLocation); // we are done with the images at this point. Free roi if not zero if (roi) cvReleaseImage(&roi); // cout << "Confidence (L, R, N) = (" << leftPSR << ", " << // rightPSR << ")" << endl; // extract features vector vector<double> data; for (int i = 0; i < nFeatures; i++) { double value = featureExtractors[i]->extract(&fa); data.push_back(value); } // normalize normalize(data); // create SVM Light objects to classify DOC* doc; WORD* words = (WORD*)malloc(sizeof(WORD) * (nFeatures + 1)); for (int i = 0; i < nFeatures; i++) { words[i].wnum = featureExtractors[i]->getId(); words[i].weight = data[i]; } // SVM Light expects that the features vector has a zero element // to indicate termination and hence words[nFeatures].wnum = 0; words[nFeatures].weight = 0.0; // create doc string comment = "Gaze SVM"; doc = create_example(-1, 0, 0, 0.0, create_svector(words, (char*)comment.c_str(), 1.0)); int maxIndex = 0; confidence = -FLT_MAX; double dists[Globals::numZones]; // classify using each zone model #pragma omp parallel for num_threads(Globals::numZones) for (unsigned int i = 0; i < Globals::numZones; i++) { if (kernelType == Trainer::Linear) dists[i] = classify_example_linear(models[i], doc); else dists[i] = classify_example(models[i], doc); } for (unsigned int i = 0; i < Globals::numZones; i++) { if (confidence < dists[i]) { confidence = dists[i]; maxIndex = i + 1; } } free_example(doc, 1); free(words); return maxIndex; }
IMP_S32 ipProcessTargetClassifierInternal( IpTargetClassifier *pstClassifier ) { IpTrackedTarget *pstTarget; IpTargetPosition *pstPos0; IMP_U8 *value1,*value2; IMP_S32 i,j,m,n,cnt,c,targetType; IpClassFeature *astClassFeature; WORDSVM words[15]; svm_node x[15]; DOC *doc; IMP_RECT_S *rc; IMP_RECT_S pstRectImg; IMP_S32 j13;//=blobObjCur.pt.y+blobObjCur.blobHeight/2-blobObjCur.blobHeight/3; IMP_S32 j23;//=blobObjCur.pt.y+blobObjCur.blobHeight/2-2*blobObjCur.blobHeight/3; IMP_S32 is_possible_human,is_possible_vehicle; IMP_FLOAT type; IMP_S32 m13,m23,mBG,mFG,mPerimeter; PEA_RESULT_S *pstResult = pstClassifier->pstResult; PEA_DETECTED_REGIONSET_S *pstRegions = &pstResult->stDRegionSet; GRAY_IMAGE_S *pstImgFgOrg = pstRegions->pstImgFgOrg; GRAY_IMAGE_S *pstImgMediate = pstRegions->pstImgMediate; IMP_S32 s32Width = pstImgFgOrg->s32W; IMP_S32 s32Height = pstImgFgOrg->s32H; IMP_S32 blobWidth,blobHeight; IpClassifierPara *pstParams=&pstClassifier->stPara; IMP_S32 s32UseBorderConstrain=pstParams->s32UseBorderConstrain; IMP_S32 s32SceneMode = 0; pstTarget = pstResult->stTrackedTargetSet.astTargets; cnt = pstResult->stTrackedTargetSet.s32UsedTotal; astClassFeature=pstResult->stTrackedTargetSet.astClassFeature; if (pstParams->pstRule->stEvrmentTgtPara.stScenePara.s32SceneLmt) { s32SceneMode = pstParams->pstRule->stEvrmentTgtPara.stScenePara.s32SceneMode; } if (pstParams->s8SvmFuncType==DISABLE) { return -1; } IMP_GrayImageClone(pstImgFgOrg,pstImgMediate); for( i=0, j=0; i<IMP_MAX_TGT_CNT; i++ ) { if (ipTrackedTargetIsActive(pstTarget)) { #if 0 {//added by mzhang, just for debug. pstTarget->stTargetInfo.s32HumanLikehood = 100; pstTarget->stTargetInfo.s32VehicleLikehood = -1; pstTarget->stTargetInfo.u32Type=IMP_TGT_TYPE_HUMAN; continue; } #endif { targetType = 0; if(!targetType) { pstPos0 = ipTargetTrajectoryGetPosition( &pstTarget->stTrajectory, 0 ); rc=&pstPos0->stRg; if( s32UseBorderConstrain ) { pstRectImg.s16X1 = 0; pstRectImg.s16Y1 = 0; pstRectImg.s16X2 = s32Width - 1; pstRectImg.s16Y2 = s32Height - 1; } if (!s32UseBorderConstrain || s32UseBorderConstrain && !ipBoundaryConditionsJudgment( rc, &pstRectImg, s32UseBorderConstrain )//加入了限定要求并且满足边界条件 ) { m13=0; m23=0; mBG=0; mFG=0; mPerimeter=0; j13=rc->s16Y2-(rc->s16Y2-rc->s16Y1)/3; j23=rc->s16Y2-2*(rc->s16Y2-rc->s16Y1)/3; for (m=rc->s16X1;m<rc->s16X2;m++) { value1=pstImgFgOrg->pu8Data+ s32Width*j13 + m; value2=pstImgFgOrg->pu8Data+ s32Width*j23 + m; if(*value1>0) { m13++; } if(*value2>0) { m23++; } } for (m=rc->s16Y1;m<rc->s16Y2;m++) { for (n=rc->s16X1;n<rc->s16X2;n++) { value1=pstImgFgOrg->pu8Data+ s32Width*m + n; if (*value1==0) { mBG++; } } } for (m=rc->s16Y1;m<rc->s16Y2;m++) { for (n=rc->s16X1;n<rc->s16X2;n++) { value1=pstImgMediate->pu8Data+ s32Width*m + n; if (*value1>0) { mPerimeter++; *value1=100; break; } } for (n=rc->s16X2;n<rc->s16X1;n--) { value1=pstImgMediate->pu8Data+ s32Width*m + n; if (*value1==100) { break; } else if (*value1>0) { mPerimeter++; *value1=100; break; } } } for (n=rc->s16X1;n<rc->s16X2;n++) { for (m=rc->s16Y1;m<rc->s16Y2;m++) { value1=pstImgMediate->pu8Data+ s32Width*m + n; if (*value1==100) break; if (*value1>0) { mPerimeter++; *value1=100; break; } } for (m=rc->s16Y2;m<rc->s16Y1;m--) { value1=pstImgMediate->pu8Data+ s32Width*m + n; if (*value1==100) break; if (*value1>0) { mPerimeter++; *value1=100; break; } } } blobWidth=rc->s16X2-rc->s16X1+1; blobHeight=rc->s16Y2-rc->s16Y1+1; mFG=blobWidth*blobHeight-mBG; astClassFeature->_P=(IMP_DOUBLE)(blobWidth)/blobHeight; astClassFeature->_P13=(IMP_DOUBLE)(m13)/blobHeight; astClassFeature->_P23=(IMP_DOUBLE)(m23)/blobHeight; astClassFeature->_I=(IMP_DOUBLE)(mBG)/(blobWidth*blobHeight); astClassFeature->_D=(IMP_DOUBLE)mPerimeter/mFG; ipComputeHuMomentInvariants(pstImgFgOrg,rc,s32Width,s32Height,astClassFeature->_Hu,&astClassFeature->_Axis); astClassFeature->_Delta=0; astClassFeature->label=pstParams->s32ClassType; if (pstParams->s8SvmFuncType==CLASSIFY) { for (i=0;i<=13;i++) { x[i].index = i+1; } x[14].index = -1; c=-1; x[0].value = astClassFeature->_Axis; x[1].value = astClassFeature->_D; x[2].value = astClassFeature->_Delta; x[3].value = astClassFeature->_Hu[0]; x[4].value = astClassFeature->_Hu[1]; x[5].value = astClassFeature->_Hu[2]; x[6].value = astClassFeature->_Hu[3]; x[7].value = astClassFeature->_Hu[4]; x[8].value = astClassFeature->_Hu[5]; x[9].value = astClassFeature->_Hu[6]; x[10].value = astClassFeature->_I; x[11].value = astClassFeature->_P; x[12].value = astClassFeature->_P13; x[13].value = astClassFeature->_P23; // (*label)[i]=classFeatureTemp.label; // (queryid)=0; // (slackid)=0; // (costfactor)=1; words[0].wnum = 1; words[0].weight = (float)astClassFeature->_Axis; words[1].wnum = 2; words[1].weight = (float)astClassFeature->_D; words[2].wnum = 3; words[2].weight = (float)astClassFeature->_Delta; words[3].wnum = 4; words[3].weight = (float)astClassFeature->_Hu[0]; words[4].wnum = 5; words[4].weight = (float)astClassFeature->_Hu[1]; words[5].wnum = 6; words[5].weight = (float)astClassFeature->_Hu[2]; words[6].wnum = 7; words[6].weight = (float)astClassFeature->_Hu[3]; words[7].wnum = 8; words[7].weight = (float)astClassFeature->_Hu[4]; words[8].wnum = 9; words[8].weight = (float)astClassFeature->_Hu[5]; words[9].wnum = 10; words[9].weight = (float)astClassFeature->_Hu[6]; words[10].wnum = 11; words[10].weight = (float)astClassFeature->_I; words[11].wnum = 12; words[11].weight = (float)astClassFeature->_P; words[12].wnum = 13; words[12].weight = (float)astClassFeature->_P13; words[13].wnum = 14; words[13].weight = (float)astClassFeature->_P23; words[14].wnum=0; //c= (IMP_S32)svm_predict(pstParams->m_model, x); doc = create_example(-1,0,0,0.0,create_svector(words,"",1.0)); type=(float)classify_example(pstParams->pstModel,doc); if (type>0 && type <2) { c=IMP_TGT_TYPE_HUMAN; pstTarget->stTargetInfo.s32HumanLikehood++; pstTarget->stTargetInfo.s32VehicleLikehood--; } else if (type>2 && type <4) { c=IMP_TGT_TYPE_VEHICLE; pstTarget->stTargetInfo.s32VehicleLikehood++; pstTarget->stTargetInfo.s32HumanLikehood--; } free_example(doc,1); } } } } if (pstTarget->stTargetInfo.s32VehicleLikehood>100) { pstTarget->stTargetInfo.s32VehicleLikehood=100; } else if(pstTarget->stTargetInfo.s32VehicleLikehood<-1) { pstTarget->stTargetInfo.s32VehicleLikehood=-1; } if (pstTarget->stTargetInfo.s32VehicleLikehood>100) { pstTarget->stTargetInfo.s32VehicleLikehood=100; } else if(pstTarget->stTargetInfo.s32VehicleLikehood<-1) { pstTarget->stTargetInfo.s32VehicleLikehood=-1; } if (pstTarget->stTargetInfo.s32HumanLikehood && pstTarget->stTargetInfo.s32HumanLikehood >= pstTarget->stTargetInfo.s32VehicleLikehood ) { pstTarget->stTargetInfo.u32Type=IMP_TGT_TYPE_HUMAN; //printf("target Type is HUMAN\n"); } else if (pstTarget->stTargetInfo.s32VehicleLikehood && pstTarget->stTargetInfo.s32VehicleLikehood >= pstTarget->stTargetInfo.s32HumanLikehood ) { pstTarget->stTargetInfo.u32Type=IMP_TGT_TYPE_VEHICLE; //printf("target Type is VEHICLE\n"); } else { pstTarget->stTargetInfo.u32Type=IMP_TGT_TYPE_UNKNOWN; //printf("target Type is UNKNOWN\n"); } } j += pstTarget->s32Used ? 1 : 0; if( j>=cnt ) break; astClassFeature++; pstTarget++; } return 1; }
int SVMLightRunner::librarySVMClassifyMain( int argc, char **argv, bool use_gmumr, SVMConfiguration &config ) { LOG( config.log, LogLevel::DEBUG_LEVEL, __debug_prefix__ + ".librarySVMClassifyMain() Started." ); DOC *doc; /* test example */ WORD *words; long max_docs,max_words_doc,lld; long totdoc=0,queryid,slackid; long correct=0,incorrect=0,no_accuracy=0; long res_a=0,res_b=0,res_c=0,res_d=0,wnum,pred_format; long j; double t1,runtime=0; double dist,doc_label,costfactor; char *line,*comment; FILE *predfl,*docfl; MODEL *model; // GMUM.R changes { librarySVMClassifyReadInputParameters( argc, argv, docfile, modelfile, predictionsfile, &verbosity, &pred_format, use_gmumr, config); if (!use_gmumr) { nol_ll(docfile,&max_docs,&max_words_doc,&lld); /* scan size of input file */ lld+=2; line = (char *)my_malloc(sizeof(char)*lld); } else { max_docs = config.target.n_rows; max_words_doc = config.getDataDim(); config.result = arma::zeros<arma::vec>(max_docs); // Prevent writing to the file pred_format = -1; // lld used only for file reading } max_words_doc+=2; words = (WORD *)my_malloc(sizeof(WORD)*(max_words_doc+10)); // GMUM.R changes } model=libraryReadModel(modelfile, use_gmumr, config); // GMUM.R changes } if(model->kernel_parm.kernel_type == 0) { /* linear kernel */ /* compute weight vector */ add_weight_vector_to_linear_model(model); } if(verbosity>=2) { C_PRINTF("Classifying test examples.."); C_FFLUSH(stdout); } // GMUM.R changes { bool newline; if (!use_gmumr) { if ((predfl = fopen (predictionsfile, "w")) == NULL) { perror (predictionsfile); EXIT (1); } if ((docfl = fopen (docfile, "r")) == NULL) { perror (docfile); EXIT (1); } newline = (!feof(docfl)) && fgets(line,(int)lld,docfl); } else { newline = false; if (totdoc < config.getDataExamplesNumber()) { newline = true; std::string str = SVMConfigurationToSVMLightLearnInputLine(config, totdoc); line = new char[str.size() + 1]; std::copy(str.begin(), str.end(), line); line[str.size()] = '\0'; } } while(newline) { if (use_gmumr) { std::string stringline = ""; } // GMUM.R changes } if(line[0] == '#') continue; /* line contains comments */ parse_document(line,words,&doc_label,&queryid,&slackid,&costfactor,&wnum, max_words_doc,&comment); totdoc++; if(model->kernel_parm.kernel_type == 0) { /* linear kernel */ for(j=0;(words[j]).wnum != 0;j++) { /* Check if feature numbers */ if((words[j]).wnum>model->totwords) /* are not larger than in */ (words[j]).wnum=0; /* model. Remove feature if */ } /* necessary. */ doc = create_example(-1,0,0,0.0,create_svector(words,comment,1.0)); t1=get_runtime(); dist=classify_example_linear(model,doc); runtime+=(get_runtime()-t1); free_example(doc,1); } else { /* non-linear kernel */ doc = create_example(-1,0,0,0.0,create_svector(words,comment,1.0)); t1=get_runtime(); dist=classify_example(model,doc); runtime+=(get_runtime()-t1); free_example(doc,1); } if(dist>0) { if(pred_format==0) { /* old weired output format */ C_FPRINTF(predfl,"%.8g:+1 %.8g:-1\n",dist,-dist); } if(doc_label>0) correct++; else incorrect++; if(doc_label>0) res_a++; else res_b++; } else { if(pred_format==0) { /* old weired output format */ C_FPRINTF(predfl,"%.8g:-1 %.8g:+1\n",-dist,dist); } if(doc_label<0) correct++; else incorrect++; if(doc_label>0) res_c++; else res_d++; } if(pred_format==1) { /* output the value of decision function */ C_FPRINTF(predfl,"%.8g\n",dist); } if((int)(0.01+(doc_label*doc_label)) != 1) { no_accuracy=1; } /* test data is not binary labeled */ if(verbosity>=2) { if(totdoc % 100 == 0) { C_PRINTF("%ld..",totdoc); C_FFLUSH(stdout); } } // GMUM.R changes { if (!use_gmumr) { newline = (!feof(docfl)) && fgets(line,(int)lld,docfl); } else { newline = false; // Store prediction result in config config.result[totdoc-1] = dist; // Read next line if (totdoc < config.getDataExamplesNumber()) { newline = true; std::string str = SVMConfigurationToSVMLightLearnInputLine(config, totdoc); line = new char[str.size() + 1]; std::copy(str.begin(), str.end(), line); line[str.size()] = '\0'; } } } if (!use_gmumr) { fclose(predfl); fclose(docfl); free(line); } // GMUM.R changes } free(words); free_model(model,1); if(verbosity>=2) { C_PRINTF("done\n"); /* Note by Gary Boone Date: 29 April 2000 */ /* o Timing is inaccurate. The timer has 0.01 second resolution. */ /* Because classification of a single vector takes less than */ /* 0.01 secs, the timer was underflowing. */ C_PRINTF("Runtime (without IO) in cpu-seconds: %.2f\n", (float)(runtime/100.0)); } if((!no_accuracy) && (verbosity>=1)) { C_PRINTF("Accuracy on test set: %.2f%% (%ld correct, %ld incorrect, %ld total)\n",(float)(correct)*100.0/totdoc,correct,incorrect,totdoc); C_PRINTF("Precision/recall on test set: %.2f%%/%.2f%%\n",(float)(res_a)*100.0/(res_a+res_b),(float)(res_a)*100.0/(res_a+res_c)); } return(0); }
SVECTOR* add_ss(SVECTOR *a, SVECTOR *b) /* compute the sum a+b of two sparse vectors */ /* Note: SVECTOR lists are not followed, but only the first SVECTOR is used */ { SVECTOR *vec; register WORD *sum,*sumi; register WORD *ai,*bj; long veclength; ai=a->words; bj=b->words; veclength=0; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { veclength++; bj++; } else if (ai->wnum < bj->wnum) { veclength++; ai++; } else { veclength++; ai++; bj++; } } while (bj->wnum) { veclength++; bj++; } while (ai->wnum) { veclength++; ai++; } veclength++; /*** is veclength=lengSequence(a)+lengthSequence(b)? ***/ sum=(WORD *)my_malloc(sizeof(WORD)*veclength); sumi=sum; ai=a->words; bj=b->words; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { (*sumi)=(*bj); sumi++; bj++; } else if (ai->wnum < bj->wnum) { (*sumi)=(*ai); sumi++; ai++; } else { (*sumi)=(*ai); sumi->weight+=bj->weight; if(sumi->weight != 0) sumi++; ai++; bj++; } } while (bj->wnum) { (*sumi)=(*bj); sumi++; bj++; } while (ai->wnum) { (*sumi)=(*ai); sumi++; ai++; } sumi->wnum=0; vec=create_svector(sum,"",1.0); free(sum); return(vec); }
MODEL * SVMLightRunner::libraryReadModel( char *modelfile, bool use_gmumr, SVMConfiguration &config ) { LOG( config.log, LogLevel::DEBUG_LEVEL, __debug_prefix__ + ".libraryReadModel() Started." ); FILE *modelfl; long i,queryid,slackid; double costfactor; long max_sv,max_words,ll,wpos; char *line,*comment; WORD *words; char version_buffer[100]; MODEL *model; if(verbosity>=1) { C_PRINTF("Reading model..."); C_FFLUSH(stdout); } // GMUM.R changes { model = (MODEL *)my_malloc(sizeof(MODEL)); if (!use_gmumr) { nol_ll(modelfile,&max_sv,&max_words,&ll); /* scan size of model file */ max_words+=2; ll+=2; words = (WORD *)my_malloc(sizeof(WORD)*(max_words+10)); line = (char *)my_malloc(sizeof(char)*ll); if ((modelfl = fopen (modelfile, "r")) == NULL) { perror (modelfile); EXIT (1); } fscanf(modelfl,"SVM-light Version %s\n",version_buffer); if(strcmp(version_buffer,VERSION)) { perror ("Version of model-file does not match version of svm_classify!"); EXIT (1); } fscanf(modelfl,"%ld%*[^\n]\n", &model->kernel_parm.kernel_type); fscanf(modelfl,"%ld%*[^\n]\n", &model->kernel_parm.poly_degree); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.rbf_gamma); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.coef_lin); fscanf(modelfl,"%lf%*[^\n]\n", &model->kernel_parm.coef_const); fscanf(modelfl,"%[^#]%*[^\n]\n", model->kernel_parm.custom); fscanf(modelfl,"%ld%*[^\n]\n", &model->totwords); fscanf(modelfl,"%ld%*[^\n]\n", &model->totdoc); fscanf(modelfl,"%ld%*[^\n]\n", &model->sv_num); fscanf(modelfl,"%lf%*[^\n]\n", &model->b); } else { // use_gmumr max_words = config.getDataDim(); words = (WORD *)my_malloc(sizeof(WORD)*(max_words+10)); LOG( config.log, LogLevel::DEBUG_LEVEL, __debug_prefix__ + ".libraryReadModel() Converting config to model..." ); /* 0=linear, 1=poly, 2=rbf, 3=sigmoid, 4=custom -- same as GMUM.R! */ model->kernel_parm.kernel_type = static_cast<long int>(config.kernel_type); // -d int -> parameter d in polynomial kernel model->kernel_parm.poly_degree = config.degree; // -g float -> parameter gamma in rbf kernel model->kernel_parm.rbf_gamma = config.gamma; // -s float -> parameter s in sigmoid/poly kernel model->kernel_parm.coef_lin = config.gamma; // -r float -> parameter c in sigmoid/poly kernel model->kernel_parm.coef_const = config.coef0; // -u string -> parameter of user defined kernel char kernel_parm_custom[50] = "empty"; char * model_kernel_parm_custom = model->kernel_parm.custom; model_kernel_parm_custom = kernel_parm_custom; // highest feature index model->totwords = config.getDataDim(); // number of training documents model->totdoc = config.target.n_rows; // number of support vectors plus 1 (!) model->sv_num = config.l + 1; /* Threshold b (has opposite sign than SVMClient::predict()) * In svm_common.c:57 in double classify_example_linear(): * return(sum-model->b); */ model->b = - config.b; LOG( config.log, LogLevel::DEBUG_LEVEL, __debug_prefix__ + ".libraryReadModel() Converting config done." ); } // GMUM.R changes } model->supvec = (DOC **)my_malloc(sizeof(DOC *)*model->sv_num); model->alpha = (double *)my_malloc(sizeof(double)*model->sv_num); model->index=NULL; model->lin_weights=NULL; // GMUM.R changes { if (!use_gmumr) { for(i=1;i<model->sv_num;i++) { fgets(line,(int)ll,modelfl); if(!parse_document(line,words,&(model->alpha[i]),&queryid,&slackid, &costfactor,&wpos,max_words,&comment)) { C_PRINTF("\nParsing error while reading model file in SV %ld!\n%s", i,line); EXIT(1); } model->supvec[i] = create_example(-1, 0,0, 0.0, create_svector(words,comment,1.0)); } fclose(modelfl); free(line); } else { for(i = 1; i < model->sv_num; ++i) { line = SVMConfigurationToSVMLightModelSVLine(config, i-1); if(!parse_document(line,words,&(model->alpha[i]),&queryid,&slackid, &costfactor,&wpos,max_words,&comment)) { C_PRINTF("\nParsing error while reading model file in SV %ld!\n%s", i,line); EXIT(1); } model->supvec[i] = create_example(-1, 0,0, 0.0, create_svector(words,comment,1.0)); free(line); } } // GMUM.R changes } free(words); if(verbosity>=1) { C_FPRINTF(stdout, "OK. (%d support vectors read)\n",(int)(model->sv_num-1)); } LOG( config.log, LogLevel::DEBUG_LEVEL, __debug_prefix__ + ".libraryReadModel() Done." ); return(model); }
void read_documents(char *docfile, DOC ***docs, double **label, long int *totwords, long int *totdoc) { char *line,*comment; WORD *words; long dnum=0,wpos,dpos=0,dneg=0,dunlab=0,queryid,slackid,max_docs; long max_words_doc, ll; double doc_label,costfactor; FILE *docfl; if(verbosity>=1) { printf("Scanning examples..."); fflush(stdout); } nol_ll(docfile,&max_docs,&max_words_doc,&ll); /* scan size of input file */ max_words_doc+=2; ll+=2; max_docs+=2; if(verbosity>=1) { printf("done\n"); fflush(stdout); } (*docs) = (DOC **)my_malloc(sizeof(DOC *)*max_docs); /* feature vectors */ (*label) = (double *)my_malloc(sizeof(double)*max_docs); /* target values */ line = (char *)my_malloc(sizeof(char)*ll); if ((docfl = fopen (docfile, "r")) == NULL) { perror (docfile); exit (1); } words = (WORD *)my_malloc(sizeof(WORD)*(max_words_doc+10)); if(verbosity>=1) { printf("Reading examples into memory..."); fflush(stdout); } dnum=0; (*totwords)=0; while((!feof(docfl)) && fgets(line,(int)ll,docfl)) { if(line[0] == '#') continue; /* line contains comments */ if(!parse_document(line,words,&doc_label,&queryid,&slackid,&costfactor, &wpos,max_words_doc,&comment)) { printf("\nParsing error in line %ld!\n%s",dnum,line); exit(1); } (*label)[dnum]=doc_label; /* printf("docnum=%ld: Class=%f ",dnum,doc_label); */ if(doc_label > 0) dpos++; if (doc_label < 0) dneg++; if (doc_label == 0) dunlab++; if((wpos>1) && ((words[wpos-2]).wnum>(*totwords))) (*totwords)=(words[wpos-2]).wnum; if((*totwords) > MAXFEATNUM) { printf("\nMaximum feature number exceeds limit defined in MAXFEATNUM!\n"); printf("LINE: %s\n",line); exit(1); } (*docs)[dnum] = create_example(dnum,queryid,slackid,costfactor, create_svector(words,comment,1.0)); /* printf("\nNorm=%f\n",((*docs)[dnum]->fvec)->twonorm_sq); */ dnum++; if(verbosity>=1) { if((dnum % 100) == 0) { printf("%ld..",dnum); fflush(stdout); } } } fclose(docfl); free(line); free(words); if(verbosity>=1) { fprintf(stdout, "OK. (%ld examples read)\n", dnum); } (*totdoc)=dnum; }
SVECTOR* find_cutting_plane(EXAMPLE *ex, SVECTOR **fycache, double *margin, long m, STRUCTMODEL *sm, STRUCT_LEARN_PARM *sparm, char* tmpdir, char *trainfile, double frac_sim, double Fweight, char *dataset_stats_file, double rho_admm, long isExhaustive, long isLPrelaxation, double *margin2, int datasetStartIdx, int chunkSz, int eid, int chunkid) { long i; SVECTOR *f, *fy, *fybar, *lhs; LABEL ybar; LATENT_VAR hbar; double lossval; double *new_constraint; long l,k; SVECTOR *fvec; WORD *words; LABEL *ybar_all = (LABEL*) malloc(sizeof(LABEL) * m); LATENT_VAR *hbar_all = (LATENT_VAR*) malloc (sizeof(LATENT_VAR) * m); time_t mv_start, mv_end; time(&mv_start); find_most_violated_constraint_marginrescaling_all_online(ybar_all, hbar_all, sm, sparm, m, tmpdir, trainfile, frac_sim, dataset_stats_file, rho_admm, isExhaustive, isLPrelaxation, Fweight, datasetStartIdx, chunkSz, eid, chunkid); time(&mv_end); #if (DEBUG_LEVEL==1) print_time(mv_start, mv_end, "Max violators"); #endif /* find cutting plane */ lhs = NULL; lossval = lossF1(ex, m, ybar_all, sparm, Fweight); *margin = lossval; *margin2 = 0; for (i=0;i<m;i++) { //find_most_violated_constraint_marginrescaling(ex[i].x, ex[i].y, &ybar, &hbar, sm, sparm); ybar = ybar_all[i]; hbar = hbar_all[i]; /* get difference vector */ fy = copy_svector(fycache[i]); fybar = psi(ex[i].x,ybar,hbar,sm,sparm); lossval = loss(ex[i].y,ybar,hbar,sparm); free_label(ybar); free_latent_var(hbar); /* scale difference vector */ for (f=fy;f;f=f->next) { f->factor*=1.0/m; //f->factor*=ex[i].x.example_cost/m; } for (f=fybar;f;f=f->next) { f->factor*=-1.0/m; //f->factor*=-ex[i].x.example_cost/m; } /* add ybar to constraint */ append_svector_list(fy,lhs); append_svector_list(fybar,fy); lhs = fybar; *margin2+=lossval/m; //*margin+=lossval*ex[i].x.example_cost/m; } free(ybar_all); free(hbar_all); /* compact the linear representation */ new_constraint = add_list_nn(lhs, sm->sizePsi); // printf("After this segfault ? \n");fflush(stdout); // printf("%x\n",new_constraint); free_svector(lhs); l=0; for (i=1;i<sm->sizePsi+1;i++) { if (fabs(new_constraint[i])>1E-10) l++; // non-zero } words = (WORD*)my_malloc(sizeof(WORD)*(l+1)); assert(words!=NULL); k=0; for (i=1;i<sm->sizePsi+1;i++) { if (fabs(new_constraint[i])>1E-10) { words[k].wnum = i; words[k].weight = new_constraint[i]; k++; } } words[k].wnum = 0; words[k].weight = 0.0; fvec = create_svector(words,"",1); free(words); free(new_constraint); return(fvec); }