2 * folded-ctf is an implementation of the folded hierarchy of
3 * classifiers for object detection, developed by Francois Fleuret
6 * Copyright (c) 2008 Idiap Research Institute, http://www.idiap.ch/
7 * Written by Francois Fleuret <francois.fleuret@idiap.ch>
9 * This file is part of folded-ctf.
11 * folded-ctf is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published
13 * by the Free Software Foundation, either version 3 of the License,
14 * or (at your option) any later version.
16 * folded-ctf is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with folded-ctf. If not, see <http://www.gnu.org/licenses/>.
26 #include "parsing_pool.h"
29 ParsingPool::ParsingPool(LabelledImagePool *image_pool, PoseCellHierarchy *hierarchy, scalar_t proportion_negative_cells) {
30 _nb_images = image_pool->nb_images();
31 _parsings = new Parsing *[_nb_images];
34 _nb_positive_cells = 0;
35 _nb_negative_cells = 0;
36 for(int i = 0; i < _nb_images; i++) {
37 _parsings[i] = new Parsing(image_pool, hierarchy, proportion_negative_cells, i);
38 _nb_cells += _parsings[i]->nb_cells();
39 _nb_positive_cells += _parsings[i]->nb_positive_cells();
40 _nb_negative_cells += _parsings[i]->nb_negative_cells();
42 (*global.log_stream) << "ParsingPool initialized" << endl;
43 (*global.log_stream) << " _nb_cells = " << _nb_cells << endl;
44 (*global.log_stream) << " _nb_positive_cells = " << _nb_positive_cells << endl;
45 (*global.log_stream) << " _nb_negative_cells = " << _nb_negative_cells << endl;
48 ParsingPool::~ParsingPool() {
49 for(int i = 0; i < _nb_images; i++)
54 void ParsingPool::down_one_level(LossMachine *loss_machine, PoseCellHierarchy *hierarchy, int level) {
55 scalar_t *labels = new scalar_t[_nb_cells];
56 scalar_t *tmp_responses = new scalar_t[_nb_cells];
60 { ////////////////////////////////////////////////////////////////////
63 for(int i = 0; i < _nb_images; i++) {
64 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
65 if(_parsings[i]->label(d) != 0) {
66 l += exp( - _parsings[i]->label(d) * _parsings[i]->response(d));
70 (*global.log_stream) << "* INITIAL LOSS IS " << l << endl;
71 } ////////////////////////////////////////////////////////////////////
73 // Put the negative samples with their current responses, and all
77 for(int i = 0; i < _nb_images; i++) {
78 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
79 if(_parsings[i]->label(d) < 0) {
81 tmp_responses[c] = _parsings[i]->response(d);
90 // Sub-sample among the negative ones
92 int *sample_nb_occurences = new int[_nb_cells];
93 scalar_t *sample_responses = new scalar_t[_nb_cells];
95 loss_machine->subsample(_nb_cells, labels, tmp_responses,
96 _nb_negative_cells, sample_nb_occurences, sample_responses,
100 for(int i = 0; i < _nb_images; i++) {
101 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
102 if(_parsings[i]->label(d) > 0) {
103 sample_nb_occurences[c + d] = 1;
104 sample_responses[c + d] = _parsings[i]->response(d);
108 int d = c + _parsings[i]->nb_cells();
110 _parsings[i]->down_one_level(hierarchy, level, sample_nb_occurences + c, sample_responses + c);
115 { ////////////////////////////////////////////////////////////////////
118 for(int i = 0; i < _nb_images; i++) {
119 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
120 if(_parsings[i]->label(d) != 0) {
121 l += exp( - _parsings[i]->label(d) * _parsings[i]->response(d));
125 (*global.log_stream) << "* FINAL LOSS IS " << l << endl;
126 } ////////////////////////////////////////////////////////////////////
128 delete[] sample_responses;
129 delete[] sample_nb_occurences;
132 delete[] tmp_responses;
135 void ParsingPool::update_cell_responses(PiFeatureFamily *pi_feature_family,
136 Classifier *classifier) {
137 for(int i = 0; i < _nb_images; i++) {
138 _parsings[i]->update_cell_responses(pi_feature_family, classifier);
142 void ParsingPool::weighted_sampling(LossMachine *loss_machine,
143 PiFeatureFamily *pi_feature_family,
144 SampleSet *sample_set,
145 scalar_t *responses) {
147 int nb_negatives_to_sample = sample_set->nb_samples() - _nb_positive_cells;
149 ASSERT(nb_negatives_to_sample > 0);
151 scalar_t *labels = new scalar_t[_nb_cells];
152 scalar_t *tmp_responses = new scalar_t[_nb_cells];
156 // Put the negative samples with their current responses, and all
160 for(int i = 0; i < _nb_images; i++) {
161 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
162 if(_parsings[i]->label(d) < 0) {
164 tmp_responses[c] = _parsings[i]->response(d);
167 tmp_responses[c] = 0;
173 // Sub-sample among the negative ones
175 int *sample_nb_occurences = new int[_nb_cells];
176 scalar_t *sample_responses = new scalar_t[_nb_cells];
178 loss_machine->subsample(_nb_cells, labels, tmp_responses,
179 nb_negatives_to_sample, sample_nb_occurences, sample_responses,
182 for(int k = 0; k < _nb_cells; k++) {
183 if(sample_nb_occurences[k] > 0) {
184 ASSERT(sample_nb_occurences[k] == 1);
186 tmp_responses[k] = sample_responses[k];
192 delete[] sample_responses;
193 delete[] sample_nb_occurences;
195 // Put the positive ones
198 for(int i = 0; i < _nb_images; i++) {
199 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
200 if(_parsings[i]->label(d) > 0) {
202 tmp_responses[c] = _parsings[i]->response(d);
208 // Here we have the responses for the sub-sampled in tmp_responses,
209 // and we have labels[n] set to zero for non-sampled samples
214 for(int i = 0; i < _nb_images; i++) {
216 int *to_collect = new int[_parsings[i]->nb_cells()];
218 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
219 to_collect[d] = (labels[c + d] != 0);
222 _parsings[i]->collect_samples(sample_set, pi_feature_family, s, to_collect);
224 for(int d = 0; d < _parsings[i]->nb_cells(); d++) {
226 responses[s++] = tmp_responses[c + d];
232 c += _parsings[i]->nb_cells();
235 delete[] tmp_responses;
239 void ParsingPool::write_roc(ofstream *out) {
240 int nb_negatives = nb_negative_cells();
241 int nb_positives = nb_positive_cells();
243 scalar_t *pos_responses = new scalar_t[nb_positives];
244 scalar_t *neg_responses = new scalar_t[nb_negatives];
246 for(int i = 0; i < _nb_images; i++) {
247 for(int c = 0; c < _parsings[i]->nb_cells(); c++) {
248 if(_parsings[i]->label(c) > 0)
249 pos_responses[np++] = _parsings[i]->response(c);
250 else if(_parsings[i]->label(c) < 0)
251 neg_responses[nn++] = _parsings[i]->response(c);
255 ASSERT(nn == nb_negatives && np == nb_positives);
257 print_roc_small_pos(out,
258 nb_positives, pos_responses,
259 nb_negatives, neg_responses,
262 delete[] pos_responses;
263 delete[] neg_responses;