I. INTRODUCTION
+---------------
- This is the open-source C++ implementation of the folded hierarchy
- of classifiers for cat detection described in
+ This is the documentation for the open-source C++ implementation of
+ the folded hierarchy of classifiers for cat detection described in
F. Fleuret and D. Geman, "Stationary Features and Cat Detection",
Journal of Machine Learning Research (JMLR), 2008, to appear.
reports.
II. INSTALLATION
+----------------
If you have installed the RateMyKitten images provided on
It will
- * Compile the source code entirely
+ * Compile the source code entirely
- * Generate the "pool file" containing the uncompressed images
- converted to gray levels, labeled with the ground truth.
+ * Generate the "pool file" containing the uncompressed images
+ converted to gray levels, labeled with the ground truth.
- * Run 20 rounds of training / test (ten rounds for each of HB and
- H+B detectors with different random seeds)
+ * Run 20 rounds of training / test (ten rounds for each of HB and
+ H+B detectors with different random seeds)
You can run the full thing with the following commands if you have
wget installed
This program was developed on Debian GNU/Linux computers with the
following main tool versions
- * GNU bash, version 3.2.39
- * g++ 4.3.2
- * gnuplot 4.2 patchlevel 4
+ * GNU bash, version 3.2.39
+ * g++ 4.3.2
+ * gnuplot 4.2 patchlevel 4
- Due to approximations in the optimized arithmetic operations with
- g++, results may vary with different versions of the compiler
- and/or different levels of optimization.
+ Due to approximations in the optimized arithmetic operations with
+ g++, results may vary with different versions of the compiler and/or
+ different levels of optimization.
-III. PARAMETERS
+III. EXECUTING THE PROGRAM
+--------------------------
+
+ The main command has to be invoked with a list of parameter values,
+ followed by commands to execute.
To set the value of a parameter, just add an argument of the form
--parameter-name=value before the commands that should take it into
account.
+ For instance, to open a scene pool ./something.pool, train a
+ detector and save it, you would do
+
+ ./folding --pool-name=./something.pool open-pool train-detector write-detector
+
+IV. PARAMETERS
+--------------
+
For every parameter below, the default value is given between
parenthesis.
Should the pictures be generated for printing in black and white.
- * pool-name (no default)
+ * pool-name (none)
The scene pool file name.
- * test-pool-name (no default)
+ * test-pool-name (none)
Should we use a separate test pool file. If none is given, then
the test scenes are taken at random from the main pool file
* proportion-negative-cells-for-training (0.025)
Overall proportion of negative cells to use during learning (we
- sample among for boosting).
+ sample among them for boosting).
* nb-negative-samples-per-positive (10)
Should we display a progress bar during long computations.
-IV. COMMANDS
+V. COMMANDS
+-----------
- * open-pool
+ * open-pool
- Open the pool of scenes.
+ Open the pool of scenes.
- * train-detector
+ * train-detector
- Create a new detector from the training scenes.
+ Create a new detector from the training scenes.
- * compute-thresholds
+ * compute-thresholds
- Compute the thresholds of the detector classifiers from the
- validation set to obtain the required wanted-true-positive-rate.
+ Compute the thresholds of the detector classifiers from the
+ validation set to obtain the required wanted-true-positive-rate.
- * test-detector
+ * test-detector
- Run the detector on the test scenes.
+ Run the detector on the test scenes.
- * sequence-test-detector
+ * sequence-test-detector
- Visit nb-wanted-true-positive-rates rates between 0 and
- wanted-true-positive-rate, for each compute the detector
- thresholds on the validation set and estimate the error rate on
- the test set.
+ Visit nb-wanted-true-positive-rates rates between 0 and
+ wanted-true-positive-rate, for each compute the detector
+ thresholds on the validation set and estimate the error rate on
+ the test set.
- * write-detector
+ * write-detector
- Write the current detector to the file detector-name
+ Write the current detector to the file detector-name
- * read-detector
+ * read-detector
- Read a detector from the file detector-name
+ Read a detector from the file detector-name
- * write-pool-images
+ * write-pool-images
- For every of the first nb-images of the pool, save one PNG image
- with the ground truth, one with the corresponding referential at
- the reference scale, and one with the feature material-feature-nb
- from the detector. This last image is not saved if either no
- detector has been read/trained or if no feature number has been
- specified.
+ For every of the first nb-images of the pool, save one PNG image
+ with the ground truth, one with the corresponding referential at
+ the reference scale, and one with the feature material-feature-nb
+ from the detector. This last image is not saved if either no
+ detector has been read/trained or if no feature number has been
+ specified.
--
Francois Fleuret
scalar_t *responses = new scalar_t[nb_positives + nb_negatives_to_sample];
- (*global.log_stream) << "Collecting the sampled training set." << endl;
-
parsing_pool->weighted_sampling(loss_machine,
&full_pi_feature_family,
sample_set,
responses);
- (*global.log_stream) << "Training the classifier." << endl;
-
(*global.log_stream) << "Initial train_loss "
<< loss_machine->loss(sample_set, responses)
<< endl;
for(int c = 0; c < _nb_classifiers_per_level; c++) {
int q = l * _nb_classifiers_per_level + c;
- (*global.log_stream) << "Building classifier " << q << " (level " << l << ")" << endl;
-
// Train the classifier
train_classifier(l,
// Update the cell responses on the training set
- (*global.log_stream) << "Updating training cell responses." << endl;
-
train_parsing->update_cell_responses(_pi_feature_families[q],
_classifiers[q]);
// Update the cell responses on the validation set
- (*global.log_stream) << "Updating validation cell responses." << endl;
-
validation_parsing->update_cell_responses(_pi_feature_families[q],
_classifiers[q]);
int wanted_nb_fn_at_this_classifier
= int(nb_targets_total * (1 - wanted_tp_at_this_classifier));
- (*global.log_stream) << "q = " << q
- << " wanted_tp_at_this_classifier = " << wanted_tp_at_this_classifier
- << " wanted_nb_fn_at_this_classifier = " << wanted_nb_fn_at_this_classifier
- << endl;
-
indexed_fusion_sort(nb_targets_total, indexes, sorted_indexes,
responses + q * nb_targets_total);
delete[] still_detected;
delete[] indexes;
delete[] sorted_indexes;
-
- { ////////////////////////////////////////////////////////////////////
- // Sanity check
-
- int nb_positives = 0;
-
- for(int t = 0; t < nb_targets_total; t++) {
- int positive = 1;
- for(int q = 0; q < _nb_classifiers; q++) {
- if(responses[t + nb_targets_total * q] < _thresholds[q]) positive = 0;
- }
- if(positive) nb_positives++;
- }
-
- scalar_t actual_tp = scalar_t(nb_positives) / scalar_t(nb_targets_total);
-
- (*global.log_stream) << "Overall detection rate " << nb_positives << "/" << nb_targets_total
- << " "
- << "actual_tp = " << actual_tp
- << " "
- << "wanted_tp = " << wanted_tp
- << endl;
-
- if(actual_tp < wanted_tp) {
- cerr << "INCONSISTENCY" << endl;
- abort();
- }
- } ////////////////////////////////////////////////////////////////////
-
delete[] responses;
}
}
_hierarchy = read_hierarchy(is);
-
- (*global.log_stream) << "Read Detector" << endl
- << " _nb_levels " << _nb_levels << endl
- << " _nb_classifiers_per_level " << _nb_classifiers_per_level << endl;
}
void Detector::write(ostream *os) {
MAIN_URL="http://www.idiap.ch/folded-ctf"
-######################################################################
+#########################################################################
# Compiling
make -j -k
echo
-######################################################################
+#########################################################################
# Generating the pool file
DATA_PATH=./rmk-data
fi
-######################################################################
-# Running the computation per se
-
RESULT_DIR=./results
case $1 in
+ #####################################################################
+ ## Generate the pictures from the paper
+
pics)
SEED=0
if [[ -d "${EXPERIMENT_RESULT_DIR}" ]]; then
- for n in -1 0 2501 2504; do
+ for npf in -1 0 2497; do
./folding --random-seed=${SEED} \
--pool-name=${POOL_NAME} \
- --result-path=${EXPERIMENT_RESULT_DIR} \
+ --result-path=/tmp/ \
--detector-name=${EXPERIMENT_RESULT_DIR}/default.det \
- --nb-images=1 \
- --material-feature-nb=${n} \
+ --nb-images=63 \
+ --material-feature-nb=${npf} \
open-pool \
read-detector \
write-pool-images
;;
+ #####################################################################
+ ## Run the full computation
+
valgrind|"")
if [[ ! -d ${RESULT_DIR} ]]; then