35 int _max_depth,
int _tree_number,
37 :
image_classifier(_image_width, _image_height, _class_number,_LearnProgress)
56 cout <<
"Reading Forest in " << directory_name <<
":" << endl;
61 char tree_filename[1000];
62 sprintf(tree_filename,
"%s/tree%04d.txt", directory_name.data(), i);
64 ifstream ifs(tree_filename);
68 cout <<
" Reading " << tree_filename <<
": " << flush;
72 if ( !tree->
load(tree_filename) )
78 trees.push_back(tree);
82 if (
trees.size() == 0 )
return false;
91 char weights_filename[1000];
92 sprintf(weights_filename,
"%s/weights.txt", directory_name.data());
93 ifstream wfs(weights_filename);
96 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
97 (*tree_it)->root->load_probability_sums_recursive(wfs);
105 char thresholds_filename[1000];
106 sprintf(thresholds_filename,
"%s/thresholds.txt", directory_name.data());
107 ifstream tfs(thresholds_filename);
117 char misclassification_rates_filename[1000];
118 sprintf(misclassification_rates_filename,
"%s/misclassification_rates.txt", directory_name.data());
119 ifstream rfs(misclassification_rates_filename);
130 cout <<
"Done." << endl;
142 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
164 cout <<
"FOREST: BUILDING TREE # " << i << endl;
172 vector <image_classification_node*> L;
174 L.push_back(tree->
root);
176 int new_node_index = 1;
180 cout <<
"BUILDING RANDOM TREE: ~ " << new_node_index <<
" nodes.\r" << flush;
204 cout <<
"Random tree built (" << tree->
node_number() <<
" nodes)." << endl;
206 trees.push_back(tree);
213 for(
int i = 0; i < call_number; i++)
218 cout <<
"FOREST REFINEMENT: " << call_number - i <<
"... " << (char)13 << flush;
222 for(vector<image_class_example *>::iterator example_it = examples->begin(); example_it < examples->end(); example_it++)
224 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
227 unsigned char * I = (
unsigned char *)((*example_it)->preprocessed->imageData);
231 int dot_product = (int)I[node->
d1] - (
int)I[node->
d2];
233 if (dot_product <= 0)
238 node->
P[(*example_it)->class_index]++;
240 weights[(*example_it)->class_index]++;
248 cout <<
"Reweighted refinement: " << endl;
256 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
257 (*tree_it)->root->reestimate_probabilities_recursive(
weights);
259 cout <<
"Forest refinement done (" << call_number <<
" calls to generate_random_examples). " << endl;
266 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
267 (*tree_it)->root->restore_occurances_recursive(
weights);
275 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
276 (*tree_it)->root->reset_class_occurances_recursive(class_index);
289 const float step = 0.01f;
290 int bin_number = int(1. / step);
293 inlier_total[i] = total[i] = 0;
295 correct_samples[i] =
new int[bin_number];
296 uncorrect_samples[i] =
new int[bin_number];
297 for(
int j = 0; j < bin_number; j++)
298 correct_samples[i][j] = uncorrect_samples[i][j] = 0;
301 for(
int i = 0; i < call_number; i++)
306 cout <<
"GENERATING TESTING SET: " << call_number - i <<
"... " << (char)13 << flush;
310 for(vector<image_class_example *>::iterator it = examples->begin(); it < examples->end(); it++)
313 int found_class_index =
recognize(*it, &score);
315 int bin_index = int(score / step);
316 if (bin_index < 0) bin_index = 0;
317 if (bin_index >= bin_number) bin_index = bin_number - 1;
319 total[(*it)->class_index]++;
320 if ((*it)->class_index == found_class_index)
322 inlier_total[found_class_index]++;
323 correct_samples[found_class_index][bin_index]++;
326 uncorrect_samples[found_class_index][bin_index]++;
335 cout <<
"Testing: " << endl;
336 cout <<
"Classification rate = [#p | Y(p) = c = Y^(p)] / [#p | Y(p) = c = Y^(p) or Y(p) != c = Y^(p)]" << endl;
337 cout <<
"Ambiguity measure = [#p | Y(p) = c != Y^(p)] / [#p | Y(p) = c = Y^(p)]" << endl;
352 IT += inlier_total[i];
355 float inlier_percentage = 100.f * float(IT) / T;
361 float desired_inlier_rate = 0.6f;
362 float ambiguity_rate_mean = 0;
365 cout <<
"CLASS " << setw(4) << i <<
": ";
366 int correct_number = 0, uncorrect_number = 0;
368 for(j = bin_number - 1; j >= 0; j--)
370 correct_number += correct_samples[i][j];
371 uncorrect_number += uncorrect_samples[i][j];
372 if (
float(correct_number) / (correct_number + uncorrect_number) < desired_inlier_rate &&
373 (correct_number + uncorrect_number) > 10)
377 cout << setw(5) << total[i] <<
" generated samples, ";
378 cout << setw(4) <<
" T = " << setw(8) <<
thresholds[i] <<
", ";
379 cout << setw(6) << setprecision(3) << 100. * float(inlier_total[i]) / total[i] <<
"% inliers, " << flush;
381 correct_number = 0; uncorrect_number = 0;
382 for(
int j = bin_number - 1; j >= 0; j--)
384 correct_number += correct_samples[i][j];
385 uncorrect_number += uncorrect_samples[i][j];
387 if (correct_number != 0)
389 ambiguity_rate_mean += float(uncorrect_number) / correct_number;
390 cout <<
"Ambig: " << setw(4) << setprecision(3) << float(uncorrect_number) / correct_number << endl;
394 ambiguity_rate_mean += 2.;
395 cout <<
"Ambig: +oo" << endl;
398 cout <<
"-------------------------------------------" << endl;
399 cout <<
" GLOBAL ESTIMATION: " << setprecision(4) << inlier_percentage <<
"% inliers." << endl;
401 cout <<
" E[Ambig] = " << ambiguity_rate_mean << endl;
402 cout <<
"-------------------------------------------" << endl;
407 delete [] correct_samples[i];
408 delete [] uncorrect_samples[i];
411 delete [] correct_samples;
412 delete [] uncorrect_samples;
415 delete [] inlier_total;
422 float best_p = p[best_class];
434 *confidence = best_p;
455 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin();
456 tree_it <
trees.end();
459 float * tree_p = (*tree_it)->posterior_probabilities(pv);
465 float inv_tree_number = 1.f /
trees.size();
467 p[i] *= inv_tree_number;
476 tree_number =
trees.size();
478 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin();
479 tree_it <
trees.end();
482 float * tree_p = (*tree_it)->posterior_probabilities(pv);
488 if (n > tree_number)
break;
493 p[i] *= inv_class_number;
509 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin();
510 tree_it <
trees.end();
513 (*tree_it)->change_class_number_and_reset_probabilities(new_class_number);
521 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin();
522 tree_it <
trees.end();
525 char tree_name[1000];
527 sprintf(tree_name,
"%s/tree%04d.txt", directory_name.data(), tree_index);
529 (*tree_it)->save(tree_name);
535 char thresholds_filename[1000];
536 sprintf(thresholds_filename,
"%s/thresholds.txt", directory_name.data());
537 ofstream tfs(thresholds_filename);
538 if (!tfs.good())
return false;
539 tfs << setw(12) << setprecision(12);
545 char misclassification_rates_filename[1000];
546 sprintf(misclassification_rates_filename,
"%s/misclassification_rates.txt", directory_name.data());
547 ofstream rfs(misclassification_rates_filename);
553 char weights_filename[1000];
554 sprintf(weights_filename,
"%s/weights.txt", directory_name.data());
555 ofstream wfs(weights_filename);
558 for(vector<image_classification_tree *>::iterator tree_it =
trees.begin(); tree_it <
trees.end(); tree_it++)
560 (*tree_it)->root->save_probability_sums_recursive(wfs);