예제 #1
0
int _svm_struct_learn (int argc, char* argv[])
{  
  SAMPLE sample;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;

  svm_struct_learn_api_init(argc,argv);

  _svm_struct_learn_read_input_parameters(argc,argv,trainfile,modelfile,&verbosity,
			&struct_verbosity,&struct_parm,&learn_parm,
			&kernel_parm,&alg_type);

   if(struct_verbosity>=1) {
    printf("Reading training examples..."); fflush(stdout);
  }
  /* read the training examples */
  sample=read_struct_examples(trainfile,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n"); fflush(stdout);
  }
  
  /* Do the learning and return structmodel. */
  if(alg_type == 0)
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_ALG);
  else if(alg_type == 1)
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_SHRINK_ALG);
  else if(alg_type == 2)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_PRIMAL_ALG);
  else if(alg_type == 3)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_ALG);
  else if(alg_type == 4)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_CACHE_ALG);
  else if(alg_type == 9)
    svm_learn_struct_joint_custom(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel);
  else
    exit(1);

  /* Warning: The model contains references to the original data 'docs'.
     If you want to free the original data, and only keep the model, you 
     have to make a deep copy of 'model'. */
  if(struct_verbosity>=1) {
    printf("Writing learned model...");fflush(stdout);
  }
  write_struct_model(modelfile,&structmodel,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n");fflush(stdout);
  }

  free_struct_sample(sample);
  free_struct_model(structmodel);

  svm_struct_learn_api_exit();

  return 0;
}
예제 #2
0
int _svm_struct_learn (int argc, char* argv[])
{  
  char trainfile[200];           /* file with training examples */
  char modelfile[200];           /* file for resulting classifier */
  SAMPLE sample;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;

  HIDEO_ENV *hideo_env=create_env();

  svm_struct_learn_api_init(argc,argv);

  svm_struct_main_read_input_parameters(argc,argv,trainfile,modelfile,&verbosity,
			&struct_verbosity,&struct_parm,&learn_parm,
			&kernel_parm,&alg_type);

  if(struct_verbosity>=1) {
    printf("Reading training examples..."); fflush(stdout);
  }
  /* read the training examples */
  sample=read_struct_examples(trainfile,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n"); fflush(stdout);
  }
  
  /* Do the learning and return structmodel. */
  if(alg_type == 1)
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,hideo_env);
  else if(alg_type == 2)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,PRIMAL_ALG,hideo_env);
  else if(alg_type == 3)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,DUAL_ALG,hideo_env);
  else if(alg_type == 4)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,DUAL_CACHE_ALG,hideo_env);
  else
    exit(1);

  /* Warning: The model contains references to the original data 'docs'.
     If you want to free the original data, and only keep the model, you 
     have to make a deep copy of 'model'. */
  if(struct_verbosity>=1) {
    printf("Writing learned model...");fflush(stdout);
  }
  write_struct_model(modelfile,&structmodel,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n");fflush(stdout);
  }

  free_struct_sample(sample);
  free_struct_model(structmodel);

  svm_struct_learn_api_exit();

  return 0;
}
int main (int argc, char* argv[])
{  
  SAMPLE sample;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;

  /* Allow the API to perform whatever initialization is required. */
  api_initialize(argv[0]);

  read_input_parameters(argc,argv,trainfile,modelfile,&verbosity,
			&struct_verbosity,&struct_parm,&learn_parm,
			&kernel_parm,&alg_type);

  if(struct_verbosity>=1) {
    printf("Reading training examples..."); fflush(stdout);
  }
  /* read the training examples */
  sample=read_struct_examples(trainfile,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n"); fflush(stdout);
  }
  
  /* Do the learning and return structmodel. */
  if(alg_type == 1)
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel);
  else if(alg_type == 2)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,PRIMAL_ALG);
  else if(alg_type == 3)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,DUAL_ALG);
  else if(alg_type == 4)
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,DUAL_CACHE_ALG);
  else
    exit(1);

  /* Warning: The model contains references to the original data 'docs'.
     If you want to free the original data, and only keep the model, you 
     have to make a deep copy of 'model'. */
  if(struct_verbosity>=1) {
    printf("Writing learned model...");fflush(stdout);
  }
  write_struct_model(modelfile,&structmodel,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n");fflush(stdout);
  }

  free_struct_sample(sample);
  free_struct_model(structmodel);

  /* Allow the API to perform whatever cleanup is required. */
  api_finalize();

  return 0;
}
int main (int argc, char* argv[])
{  
  SAMPLE sample;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;

  svm_struct_learn_api_init(argc,argv);

  read_input_parameters(argc,argv,trainfile,modelfile,&verbosity,
			&struct_verbosity,&struct_parm,&learn_parm,
			&kernel_parm,&alg_type);

  if(struct_verbosity>=1) {
    //verbose = true;
    printf("Reading training examples..."); fflush(stdout);
  }
  /* read the training examples */
  sample=read_struct_examples(trainfile,&struct_parm);
  if(struct_verbosity>=1) {
    printf("done\n"); fflush(stdout);
  }

  string config_tmp;
  bool update_loss_function = false;
  if(Config::Instance()->getParameter("update_loss_function", config_tmp)) {
    update_loss_function = config_tmp.c_str()[0] == '1';
  }
  printf("[Main] update_loss_function=%d\n", (int)update_loss_function);
  if(!update_loss_function) {
    printf("update_loss_function should be true\n");
    exit(-1);
  }  

  eUpdateType updateType = UPDATE_NODE_EDGE;
  if(Config::Instance()->getParameter("update_type", config_tmp)) {
    updateType = (eUpdateType)atoi(config_tmp.c_str());
  }
  printf("[Main] update_type=%d\n", (int)updateType);

  mkdir(loss_dir, 0777);

  // check if parameter vector files exist
  const char* parameter_vector_dir = "parameter_vector";
  int idx = 0;
  string parameter_vector_dir_last = findLastFile(parameter_vector_dir, "", &idx);
  string parameter_vector_file_pattern = parameter_vector_dir_last + "/iteration_";
  int idx_1 = 1;
  string parameter_vector_file_last = findLastFile(parameter_vector_file_pattern, ".txt", &idx_1);
  printf("[Main] Checking parameter vector file %s\n", parameter_vector_file_last.c_str());

  // vectors used to store RF weights
  vector<double>* alphas = new vector<double>[sample.n];
  vector<double>* alphas_edge = 0;
  if(updateType == UPDATE_NODE_EDGE) {
    alphas_edge = new vector<double>[sample.n];
  }
  int alphas_idx = 0;

  if(fileExists("alphas.txt") && fileExists(parameter_vector_file_last)) {

    // Loading alpha coefficients
    ifstream ifs("alphas.txt");
    string line;
    int lineIdx = 0;
    while(lineIdx < sample.n && getline(ifs, line)) {
      vector<string> tokens;
      splitString(line, tokens);
      for(vector<string>::iterator it = tokens.begin();
          it != tokens.end(); ++it) {
        alphas[lineIdx].push_back(atoi(it->c_str()));
      }
      ++lineIdx;
    }
    ifs.close();
    if(lineIdx > 0) {
      alphas_idx = alphas[0].size();
    }

    // Loading parameters
    printf("[Main] Found parameter vector file %s\n", parameter_vector_file_last.c_str());
    struct_parm.ssvm_iteration = idx + 1;
    update_output_dir(struct_parm.ssvm_iteration);

    //EnergyParam param(parameter_vector_file_last.c_str());
    //updateCoeffs(sample, param, struct_parm, updateType, alphas, alphas_idx);
    //alphas_idx = 1;

  } else {
    struct_parm.ssvm_iteration = 0;

    // insert alpha coefficients for first iteration
    for(int i = 0; i < sample.n; ++i) {
      alphas[i].push_back(1);
    }

    ofstream ofs("alphas.txt", ios::app);
    int i = 0;
    for(; i < sample.n - 1; ++i) {
      ofs << alphas[i][alphas_idx] << " ";
    }
    if(i < sample.n) {
      ofs << alphas[i][alphas_idx];
    }
    ofs << endl;
    ofs.close();

    // edges
    for(int i = 0; i < sample.n; ++i) {
      alphas_edge[i].push_back(1);
    }

    ofstream ofse("alphas_edge.txt", ios::app);
    i = 0;
    for(; i < sample.n - 1; ++i) {
      ofse << alphas_edge[i][alphas_idx] << " ";
    }
    if(i < sample.n) {
      ofse << alphas_edge[i][alphas_idx];
    }
    ofse << endl;
    ofse.close();

    ++alphas_idx;
  }

  const int nMaxIterations = 5;
  bool bIterate = true;
  do {

    printf("-----------------------------------------SSVM-ITERATION-%d-START\n",
           struct_parm.ssvm_iteration);

    struct_parm.iterationId = 1;

    /* Do the learning and return structmodel. */
    if(alg_type == 0)
      svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_ALG);
    else if(alg_type == 1)
      svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_SHRINK_ALG);
    else if(alg_type == 2)
      svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_PRIMAL_ALG);
    else if(alg_type == 3)
      svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_ALG);
    else if(alg_type == 4)
      svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_CACHE_ALG);
    else if(alg_type == 9)
      svm_learn_struct_joint_custom(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel);
    else
      exit(1);

    char _modelfile[BUFFER_SIZE];
    //sprintf(_modelfile, "%s_%d", modelfile, struct_parm.ssvm_iteration);
    sprintf(_modelfile, "%s_%d", modelfile, struct_parm.ssvm_iteration);
    printf("[Main] Writing learned model to %s\n", _modelfile);
    write_struct_model(_modelfile, &structmodel, &struct_parm);

    // Run inference on training data and increase loss for misclassified points
    printf("[Main] Loading learned model to %s\n", _modelfile);
    EnergyParam param(_modelfile);

    updateCoeffs(sample, param, struct_parm, updateType, alphas, alphas_edge,
                 struct_parm.ssvm_iteration + 1);

    ofstream ofs("alphas.txt", ios::app);
    int i = 0;
    for(; i < sample.n - 1; ++i) {
      ofs << alphas[i][alphas_idx] << " ";
    }
    if(i < sample.n) {
      ofs << alphas[i][alphas_idx];
    }
    ofs << endl;
    ofs.close();

    ofstream ofse("alphas_edge.txt", ios::app);
    i = 0;
    for(; i < sample.n - 1; ++i) {
      ofse << alphas_edge[i][alphas_idx] << " ";
    }
    if(i < sample.n) {
      ofse << alphas_edge[i][alphas_idx];
    }
    ofse << endl;
    ofse.close();

    ++alphas_idx;

    printf("-----------------------------------------SSVM-ITERATION-%d-END\n",
           struct_parm.ssvm_iteration);

    ++struct_parm.ssvm_iteration;

    bIterate = (nMaxIterations == -1 || struct_parm.ssvm_iteration < nMaxIterations);

  } while(bIterate);

  // Output final segmentation for all examples
  long nExamples = sample.n;
  int nRFs = struct_parm.ssvm_iteration;
  double* lossPerLabel = 0;
  labelType* groundTruthLabels = 0;

  for(int i = 0; i < nExamples; i++) { /*** example loop ***/

    Slice_P* slice = sample.examples[i].x.slice;
    Feature* feature = sample.examples[i].x.feature;
    //map<sidType, nodeCoeffType>* nodeCoeffs = sample.examples[i].x.nodeCoeffs;
    //map<sidType, edgeCoeffType>* edgeCoeffs = sample.examples[i].x.edgeCoeffs;
    map<sidType, nodeCoeffType>* nodeCoeffs = 0;
    map<sidType, edgeCoeffType>* edgeCoeffs = 0;
    int nNodes = slice->getNbSupernodes();

    stringstream soutPb;
    soutPb << loss_dir;
    soutPb << "pb_";
    soutPb << getNameFromPathWithoutExtension(slice->getName());
    soutPb << "_";
    soutPb << "combined";
    //soutPb << setw(5) << setfill('0') << ssvm_iteration;
    soutPb << ".tif";
    printf("[Main] Exporting %s\n", soutPb.str().c_str());

    labelType* inferredLabels =
      computeCombinedLabels(slice, feature, groundTruthLabels,
                            lossPerLabel, nRFs, alphas, i,
                            nodeCoeffs, edgeCoeffs, soutPb.str().c_str());

    stringstream sout;
    sout << loss_dir;
    sout << getNameFromPathWithoutExtension(slice->getName());
    sout << "_";
    sout << "combined";
    //sout << setw(5) << setfill('0') << ssvm_iteration;
    sout << ".tif";
    printf("[Main] Exporting %s\n", sout.str().c_str());
    slice->exportOverlay(sout.str().c_str(), inferredLabels);

    stringstream soutBW;
    soutBW << loss_dir;
    soutBW << getNameFromPathWithoutExtension(slice->getName());
    soutBW << "_";
    soutBW << "combined";
    //soutBW << setw(5) << setfill('0') << ssvm_iteration;
    soutBW << "_BW.tif";
    printf("[Main] Exporting %s\n", soutBW.str().c_str());        
    slice->exportSupernodeLabels(soutBW.str().c_str(),
                                 struct_parm.nClasses,
                                 inferredLabels, nNodes,
                                 &(struct_parm.labelToClassIdx));

    delete[] inferredLabels;
  }

  free_struct_sample(sample);
  free_struct_model(structmodel);

  svm_struct_learn_api_exit();

  return 0;
}
예제 #5
0
int main(int argc, char* argv[]) {

  double *w; /* weight vector */
  long m, i;
  double C, epsilon;
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  char trainfile[1024];
  char modelfile[1024];
  int MAX_ITER;
  /* new struct variables */
  SVECTOR **fycache, *diff, *fy;
  EXAMPLE *ex;
	SAMPLE alldata;
  SAMPLE sample;
	SAMPLE val;
  STRUCT_LEARN_PARM sparm;
  STRUCTMODEL sm;
  
  double primal_obj;
  double stop_crit; 
	char itermodelfile[2000];

	/* self-paced learning variables */
	double init_spl_weight;
	double spl_weight;
	double spl_factor;
	int *valid_examples;
 

  /* read input parameters */
	my_read_input_parameters(argc, argv, trainfile, modelfile, &learn_parm, &kernel_parm, &sparm, 
													&init_spl_weight, &spl_factor); 

  epsilon = learn_parm.eps;
  C = learn_parm.svm_c;
  MAX_ITER = learn_parm.maxiter;

  /* read in examples */
  alldata = read_struct_examples(trainfile,&sparm);
  int ntrain = (int) round(1.0*alldata.n); /* no validation set */
	if(ntrain < alldata.n)
	{
 	 long *perm = randperm(alldata.n);
 	 sample = generate_train_set(alldata, perm, ntrain);
 	 val = generate_validation_set(alldata, perm, ntrain);
 	 free(perm);
	}
	else
	{
		sample = alldata;
	}
  ex = sample.examples;
  m = sample.n;
  
  /* initialization */
  init_struct_model(alldata,&sm,&sparm,&learn_parm,&kernel_parm); 

  w = create_nvector(sm.sizePsi);
  clear_nvector(w, sm.sizePsi);
  sm.w = w; /* establish link to w, as long as w does not change pointer */

  /* some training information */
  printf("C: %.8g\n", C);
	printf("spl weight: %.8g\n",init_spl_weight);
  printf("epsilon: %.8g\n", epsilon);
  printf("sample.n: %d\n", sample.n); 
  printf("sm.sizePsi: %ld\n", sm.sizePsi); fflush(stdout);


  /* prepare feature vector cache for correct labels with imputed latent variables */
  fycache = (SVECTOR**)malloc(m*sizeof(SVECTOR*));
  for (i=0;i<m;i++) {
    fy = psi(ex[i].x, ex[i].y, &sm, &sparm);
    diff = add_list_ss(fy);
    free_svector(fy);
    fy = diff;
    fycache[i] = fy;
  }

 	/* learn initial weight vector using all training examples */
	valid_examples = (int *) malloc(m*sizeof(int));     

  /* errors for validation set */

  double cur_loss, best_loss = DBL_MAX;
  int loss_iter;


	/* initializations */
	spl_weight = init_spl_weight;

	/* solve biconvex self-paced learning problem */
	primal_obj = alternate_convex_search(w, m, MAX_ITER, C, epsilon, fycache, ex, &sm, &sparm, valid_examples, spl_weight);
	printf("primal objective: %.4f\n", primal_obj);
	fflush(stdout);
	//alternate_convex_search(w, m, MAX_ITER, C, epsilon, fycache, ex, &sm, &sparm, valid_examples, spl_weight);
	int nValid = 0;
	for (i=0;i<m;i++) {
		if(valid_examples[i]) {
			nValid++;
		}
	}

		

	if(ntrain < alldata.n) {
		cur_loss = compute_current_loss(val,&sm,&sparm);
		printf("CURRENT LOSS: %f\n",cur_loss);
	}
  

  /* write structural model */
  write_struct_model(modelfile, &sm, &sparm);
  // skip testing for the moment  

  /* free memory */
  free_struct_sample(alldata);
	if(ntrain < alldata.n)
	{
		free(sample.examples);
		free(val.examples);
	}
  free_struct_model(sm, &sparm);
  for(i=0;i<m;i++) {
    free_svector(fycache[i]);
  }
  free(fycache);

	free(valid_examples);
   
  return(0); 
  
}
예제 #6
0
int main (int argc, char* argv[])
{
  int o, i, j, cad_num;
  char filename[256];
  CAD **cads, *cad;
  SAMPLE sample, sample_part;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;
  int rank;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  /* select GPU */
  select_gpu(rank);

  svm_struct_learn_api_init(argc,argv);

  read_input_parameters(argc, argv, trainfile, cadfile, testfile, &verbosity,
			&struct_verbosity, &struct_parm, &learn_parm,
			&kernel_parm, &alg_type);

  /* read cad models */
  cads = read_cad_model(cadfile, &cad_num, 0, &struct_parm);

  /* if cad_num == 1, train the final model */
  if(cad_num == 1)
  {
    printf("Train the hierarchical model\n");

    /* set the cad model for structmodel */
    structmodel.cad_num = 1;
    structmodel.cads = cads;

    printf("Read training samples\n");
    sample = read_struct_examples(trainfile, &struct_parm, &structmodel);
    printf("Read training samples done\n");

    if(struct_parm.is_root == 1 || struct_parm.is_aspectlet == 1)
    {
      /* first train weights for root parts */
      printf("Train root models\n");
      cad = cads[0];

      struct_parm.cad_index = 0;
      /* for each part */
      for(i = 0; i < cad->part_num; i++)
      {
        /* choose what parts to train */
        if((cad->roots[i] == -1 && struct_parm.is_root == 1) || (cad->roots[i] == 1 && struct_parm.is_aspectlet == 1))
        {
          printf("Train part %d\n", i);
          /* training iteration index */
          struct_parm.iter = 0;

          struct_parm.part_index = i;
          /* select training samples for part */
          if(rank == 0)
            select_examples_part(trainfile, sample, cad, 0, i);
          MPI_Barrier(MPI_COMM_WORLD);
          sample_part = read_struct_examples("temp_part.dat", &struct_parm, &structmodel);

          /* train the root template */
          struct_parm.deep = 0;

          /* Do the learning and return structmodel. */
          if(alg_type == 1)
            svm_learn_struct(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
          else if(alg_type == 2)
            svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
          else if(alg_type == 3)
            svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
          else if(alg_type == 4)
            svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
          else
            exit(1);

          /* if aspectlet, train the subtree */
          if(cad->roots[i] == 1 && struct_parm.is_aspectlet == 1)
          {
            printf("Train subtree for part %d\n", i);
            struct_parm.deep = 1;
            struct_parm.iter++;

            /* select training samples for part */
            if(rank == 0)
              select_examples_part(trainfile, sample, cad, 0, i);
            MPI_Barrier(MPI_COMM_WORLD);
            free_struct_sample(sample_part);
            sample_part = read_struct_examples("temp_part.dat", &struct_parm, &structmodel);

            free_struct_model(structmodel);
            /* set the cad model for structmodel */
            structmodel.cad_num = 1;
            structmodel.cads = cads;

            if(alg_type == 1)
              svm_learn_struct(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
            else if(alg_type == 2)
              svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
            else if(alg_type == 3)
              svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
            else if(alg_type == 4)
              svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
            else
              exit(1);
          }

          /* data mining hard examples */
          for(j = 0; j < struct_parm.hard_negative; j++)
          {
            /* increase iteration number */
            struct_parm.iter++;

            data_mining_hard_examples("temp_part.dat", testfile, &struct_parm, &structmodel);

            /* read the training examples */
            if(struct_verbosity>=1) 
            {
              printf("Reading training examples...");
              fflush(stdout);
            }
            free_struct_sample(sample_part);
            sample_part = read_struct_examples("temp.dat", &struct_parm, &structmodel);
            if(struct_verbosity>=1) 
            {
              printf("done\n");
              fflush(stdout);
            }
 
            /* Do the learning and return structmodel. */
            free_struct_model(structmodel);

            /* set the cad model for structmodel */
            structmodel.cad_num = 1;
            structmodel.cads = cads;

            if(alg_type == 1)
              svm_learn_struct(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
            else if(alg_type == 2)
              svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
            else if(alg_type == 3)
              svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
            else if(alg_type == 4)
              svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
            else
              exit(1);
          }

          /* save constraints for training the full model */
          if(rank == 0)
            save_constraints(&struct_parm, &structmodel);
          MPI_Barrier(MPI_COMM_WORLD);

          free_struct_sample(sample_part);
          free_struct_model(structmodel);

          /* set the cad model for structmodel */
          structmodel.cad_num = 1;
          structmodel.cads = cads;
        }
      } /* end for each part */

      if(rank == 0)
      {
        write_constraints(struct_parm.cset, &struct_parm);
        free(struct_parm.cset.rhs); 
        for(i = 0; i < struct_parm.cset.m; i++) 
          free_example(struct_parm.cset.lhs[i], 1);
        free(struct_parm.cset.lhs);
      }
      MPI_Barrier(MPI_COMM_WORLD);
    }  /* end if is_root == 1 */

    /* train the full model */
    printf("Train the full model\n");
    struct_parm.iter = 0;
    struct_parm.cad_index = -1;
    struct_parm.part_index = -1;
    struct_parm.deep = 1;

    /* Do the learning and return structmodel. */
    if(alg_type == 1)
      svm_learn_struct(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
    else if(alg_type == 2)
      svm_learn_struct_joint(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
    else if(alg_type == 3)
      svm_learn_struct_joint(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
    else if(alg_type == 4)
      svm_learn_struct_joint(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
    else
      exit(1);
  
    /* data mining hard examples */
    while(struct_parm.hard_negative > 0)
    {
      /* increase iteration number */
      struct_parm.iter++;

      data_mining_hard_examples(trainfile, testfile, &struct_parm, &structmodel);

      /* read the training examples */
      if(struct_verbosity>=1) 
      {
        printf("Reading training examples...");
        fflush(stdout);
      }
      free_struct_sample(sample);
      sample = read_struct_examples("temp.dat", &struct_parm, &structmodel);
      if(struct_verbosity>=1) 
      {
        printf("done\n");
        fflush(stdout);
      }
 
      /* Do the learning and return structmodel. */
      free_struct_model(structmodel);

      /* set the cad model for structmodel */
      structmodel.cad_num = 1;
      structmodel.cads = cads;

      if(alg_type == 1)
        svm_learn_struct(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
      else if(alg_type == 2)
        svm_learn_struct_joint(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
      else if(alg_type == 3)
        svm_learn_struct_joint(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
      else if(alg_type == 4)
        svm_learn_struct_joint(sample, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
      else
        exit(1);

      struct_parm.hard_negative--;
    }

    if(rank == 0)
    {
      if(struct_verbosity >= 1) 
      {
        printf("Writing learned model...");
        fflush(stdout);
      }
      sprintf(modelfile, "%s.mod", struct_parm.cls);
      write_struct_model(modelfile, &structmodel, &struct_parm);
      if(struct_verbosity>=1) 
      {
        printf("done\n");
        fflush(stdout);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    free_struct_sample(sample);
    free_struct_model(structmodel);
  }

  /* train weights for aspectlets */
  /* start with the second aspectlet, the first one is the whole object */
  for(o = 1; o < cad_num; o++)
  {
    printf("Train aspectlet %d\n", o);
    cad = cads[o];

    /* set the cad model for structmodel */
    structmodel.cad_num = 1;
    structmodel.cads = &cad;

    /* training iteration index */
    struct_parm.iter = 0;
    struct_parm.cad_index = -1;
    struct_parm.part_index = -1;
    struct_parm.deep = 1;

    /* select training samples for the aspectlet */
    if(rank == 0)
      select_examples_aspectlet(trainfile, cads, o);
    MPI_Barrier(MPI_COMM_WORLD);
    printf("Read training samples\n");
    sample_part = read_struct_examples("temp_part.dat", &struct_parm, &structmodel);
    printf("Read training samples done\n");

    /* Do the learning and return structmodel. */
    if(alg_type == 1)
      svm_learn_struct(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
    else if(alg_type == 2)
      svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
    else if(alg_type == 3)
      svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
    else if(alg_type == 4)
      svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
    else
      exit(1);

    /* data mining hard examples */
    for(i = 0; i < struct_parm.hard_negative; i++)
    {
      /* increase iteration number */
      struct_parm.iter++;

      data_mining_hard_examples("temp_part.dat", testfile, &struct_parm, &structmodel);

      /* read the training examples */
      if(struct_verbosity>=1) 
      {
        printf("Reading training examples...");
        fflush(stdout);
      }
      free_struct_sample(sample_part);
      sample_part = read_struct_examples("temp.dat", &struct_parm, &structmodel);
      if(struct_verbosity>=1) 
      {
        printf("done\n");
        fflush(stdout);
      }
 
      /* Do the learning and return structmodel. */
      free_struct_model(structmodel);

      /* set the cad model for structmodel */
      structmodel.cad_num = 1;
      structmodel.cads = &cad;

      if(alg_type == 1)
        svm_learn_struct(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel);
      else if(alg_type == 2)
        svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, PRIMAL_ALG);
      else if(alg_type == 3)
        svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_ALG);
      else if(alg_type == 4)
        svm_learn_struct_joint(sample_part, &struct_parm, &learn_parm, &kernel_parm, &structmodel, DUAL_CACHE_ALG);
      else
        exit(1);
    }

    if(rank == 0)
    {
      if(struct_verbosity>=1) 
      {
        printf("Writing learned model...");
        fflush(stdout);
      }
      sprintf(modelfile, "%s_cad%03d.mod", struct_parm.cls, o);
      write_struct_model(modelfile, &structmodel, &struct_parm);
      if(struct_verbosity>=1) 
      {
        printf("done\n");
        fflush(stdout);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);

    free_struct_sample(sample_part);
    free_struct_model(structmodel);
  }  /* end for each cad model */

  for(i = 0; i < cad_num; i++)
    destroy_cad(cads[i]);
  free(cads);

  svm_struct_learn_api_exit();

  MPI_Finalize();

  return 0;
}
int main(int argc, char* argv[]) {

    double *w; /* weight vector */
    int outer_iter;
    long m, i;
    double C, epsilon;
    LEARN_PARM learn_parm;
    KERNEL_PARM kernel_parm;
    char trainfile[1024];
    char modelfile[1024];
    int MAX_ITER;
    /* new struct variables */
    SVECTOR **fycache, *diff, *fy;
    EXAMPLE *ex;
    SAMPLE sample;
    STRUCT_LEARN_PARM sparm;
    STRUCTMODEL sm;

    //double decrement;
    double primal_obj;//, last_primal_obj;
    //double cooling_eps;
    //double stop_crit;

    DebugConfiguration::VerbosityLevel = VerbosityLevel::None;

    /* read input parameters */
    my_read_input_parameters(argc, argv, trainfile, modelfile, &learn_parm, &kernel_parm, &sparm);

    epsilon = learn_parm.eps;
    C = learn_parm.svm_c;
    MAX_ITER = learn_parm.maxiter;

    /* read in examples */
    sample = read_struct_examples(trainfile,&sparm);
    ex = sample.examples;
    m = sample.n;

    /* initialization */
    init_struct_model(sample,&sm,&sparm,&learn_parm,&kernel_parm);
    w = sm.w;

    //w = create_nvector(sm.sizePsi);
    //clear_nvector(w, sm.sizePsi);
    //sm.w = w; /* establish link to w, as long as w does not change pointer */

    /* some training information */
    printf("C: %.8g\n", C);
    printf("epsilon: %.8g\n", epsilon);
    printf("sample.n: %ld\n", sample.n);
    printf("sm.sizePsi: %ld\n", sm.sizePsi);
    fflush(stdout);

    /* impute latent variable for first iteration */
    init_latent_variables(&sample,&learn_parm,&sm,&sparm);

    /* prepare feature vector cache for correct labels with imputed latent variables */
    fycache = (SVECTOR**)malloc(m*sizeof(SVECTOR*));
    for (i=0; i<m; i++) {
        fy = psi(ex[i].x, ex[i].y, ex[i].h, &sm, &sparm);

        /* DEBUG */
        printf("true_psi[%d]=", i);
        for (int j = 0; j < sm.sizePsi; ++j)
            printf("%.4lf ", fy->words[j].weight);
        printf("\n");

        diff = add_list_ss(fy);
        free_svector(fy);
        fy = diff;
        fycache[i] = fy;
    }

    /* outer loop: latent variable imputation */
    outer_iter = 1;
    //last_primal_obj = 0;
    //decrement = 0;
    //cooling_eps = 0.5*C*epsilon;
    //while ((outer_iter<=MIN_OUTER_ITER)||((!stop_crit)&&(outer_iter<MAX_OUTER_ITER))) {
    while (outer_iter<MAX_OUTER_ITER) {
        LearningTracker::NextOuterIteration();
        printf("OUTER ITER %d\n", outer_iter);
        /* cutting plane algorithm */
        primal_obj = cutting_plane_algorithm(w, m, MAX_ITER, C, /*cooling_eps, */fycache, ex, &sm, &sparm);

        /* compute decrement in objective in this outer iteration */
        /*
        decrement = last_primal_obj - primal_obj;
        last_primal_obj = primal_obj;
        printf("primal objective: %.4f\n", primal_obj);
        printf("decrement: %.4f\n", decrement); fflush(stdout);
        stop_crit = (decrement<C*epsilon)&&(cooling_eps<0.5*C*epsilon+1E-8);
        cooling_eps = -decrement*0.01;
        cooling_eps = MAX(cooling_eps, 0.5*C*epsilon);
        printf("cooling_eps: %.8g\n", cooling_eps); */

        /* print new weights */
        printf("W=");
        for (i = 1; i <= sm.sizePsi; ++i)
            printf("%.3f ", sm.w[i]);
        printf("\n");

        /* Save model */
        char modelfile_tmp[1024];
        sprintf(modelfile_tmp, "%s.%d", modelfile, outer_iter);
        write_struct_model(modelfile_tmp, &sm, &sparm);

        /* impute latent variable using updated weight vector */
        for (i=0; i<m; i++) {
            free_latent_var(ex[i].h);
            ex[i].h = infer_latent_variables(ex[i].x, ex[i].y, &sm, &sparm);
        }
        /* re-compute feature vector cache */
        for (i=0; i<m; i++) {
            free_svector(fycache[i]);
            fy = psi(ex[i].x, ex[i].y, ex[i].h, &sm, &sparm);

            /* DEBUG */
            printf("true_psi[%d]=", i);
            for (int j = 0; j < sm.sizePsi; ++j)
                printf("%.4lf ", fy->words[j].weight);
            printf("\n");

            diff = add_list_ss(fy);
            free_svector(fy);
            fy = diff;
            fycache[i] = fy;
        }

        outer_iter++;
    } // end outer loop


    /* write structural model */
    write_struct_model(modelfile, &sm, &sparm);
    // skip testing for the moment

    /* free memory */
    free_struct_sample(sample);
    free_struct_model(sm, &sparm);
    for(i=0; i<m; i++) {
        free_svector(fycache[i]);
    }
    free(fycache);

    return(0);

}