From f20bd6857acd56378b28b13c19d2fd31b91f7ca1 Mon Sep 17 00:00:00 2001 From: Rakesh Mehta <rakesh.mehta@idiap.ch> Date: Tue, 20 Aug 2013 14:02:00 +0200 Subject: [PATCH] Trainer tests added --- xbob/boosting/core/trainers.py | 51 ++++++++++----------- xbob/boosting/tests/datafile.hdf5 | Bin 0 -> 10144 bytes xbob/boosting/tests/test_trainer_lut.py | 56 ++++++++++++++++++++++-- 3 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 xbob/boosting/tests/datafile.hdf5 diff --git a/xbob/boosting/core/trainers.py b/xbob/boosting/core/trainers.py index 575da62..0446277 100644 --- a/xbob/boosting/core/trainers.py +++ b/xbob/boosting/core/trainers.py @@ -181,7 +181,7 @@ class LutMachine(): - def get_weak_scores(self, fset): + def get_weak_scores(self, features): """ Function computes classification results according to the LUT machine Function classifies the features based on a single LUT machine. @@ -193,13 +193,13 @@ class LutMachine(): weak_scores: The classification scores of the features based on current weak classifier""" # Initialize - num_samp = len(fset) + num_samp = len(features) num_outputs = len(self.luts[0]) weak_scores = numpy.zeros([num_samp,num_outputs]) # Compute weak scores - for oi in range(num_outputs): - weak_scores[:,oi] = numpy.transpose(self.luts[fset[:,self.selected_indices[oi]],oi]) + for output_index in range(num_outputs): + weak_scores[:,output_index] = numpy.transpose(self.luts[features[:,self.selected_indices[output_index]],output_index]) return weak_scores @@ -233,9 +233,7 @@ class LutTrainer(): """ self.num_entries = num_entries self.num_outputs = num_outputs - self.luts = numpy.ones((num_entries, num_outputs), dtype = numpy.int) self.selection_type = selection_type - self.selected_indices = numpy.zeros([num_outputs,1], 'int16') @@ -261,8 +259,8 @@ class LutTrainer(): """ # Initializations - num_outputs = loss_grad.shape[1] - fea_grad = numpy.zeros([self.num_entries, num_outputs]) + # num_outputs = loss_grad.shape[1] + fea_grad = numpy.zeros([self.num_entries, self.num_outputs]) lut_machine = LutMachine(self.num_outputs, self.num_entries) # Compute the sum of the gradient based on the feature values or the loss associated with each @@ -270,6 +268,7 @@ class LutTrainer(): sum_loss = self.compute_grad_sum(loss_grad, fea) + # Select the most discriminative index (or indices) for classification which minimizes the loss # and compute the sum of gradient for that index @@ -280,10 +279,10 @@ class LutTrainer(): selected_indices = [numpy.argmin(col) for col in numpy.transpose(sum_loss)] - for oi in range(num_outputs): - curr_id = sum_loss[:,oi].argmin() - fea_grad[:,oi] = self.compute_grad_hist(loss_grad[:,oi],fea[:,curr_id]) - lut_machine.selected_indices[oi] = curr_id + for output_index in range(self.num_outputs): + curr_id = sum_loss[:,output_index].argmin() + fea_grad[:,output_index] = self.compute_grad_hist(loss_grad[:,output_index],fea[:,curr_id]) + lut_machine.selected_indices[output_index] = curr_id elif self.selection_type == 'shared': @@ -293,10 +292,11 @@ class LutTrainer(): accum_loss = numpy.sum(sum_loss,1) selected_findex = accum_loss.argmin() - lut_machine.selected_indices = selected_findex*numpy.ones([num_outputs,1],'int16') + lut_machine.selected_indices = selected_findex*numpy.ones([self.num_outputs,1],'int16') + + for output_index in range(self.num_outputs): + fea_grad[:,output_index] = self.compute_grad_hist(loss_grad[:,output_index],fea[:,selected_findex]) - for oi in range(num_outputs): - fea_grad[:,oi] = self.compute_grad_hist(loss_grad[:,oi],fea[:,selected_findex]) # Assign the values to LookUp Table lut_machine.luts[fea_grad <= 0.0] = -1 @@ -323,14 +323,14 @@ class LutTrainer(): # initialize values num_fea = len(fea[0]) num_samp = len(fea) - num_outputs = len(loss_grad[0]) - sum_loss = numpy.zeros([num_fea,num_outputs]) + sum_loss = numpy.zeros([num_fea,self.num_outputs]) # Compute the loss for each feature - for fi in range(num_fea): - for oi in range(num_outputs): - hist_grad = self.compute_grad_hist(loss_grad[:,oi],fea[:,fi]) - sum_loss[fi,oi] = - sum(abs(hist_grad)) + for feature_index in range(num_fea): + for output_index in range(self.num_outputs): + hist_grad = self.compute_grad_hist(loss_grad[:,output_index],fea[:,feature_index]) + sum_loss[feature_index,output_index] = - sum(abs(hist_grad)) + return sum_loss @@ -339,7 +339,7 @@ class LutTrainer(): - def compute_grad_hist(self, loss_grado,fval): + def compute_grad_hist(self, loss_grado,features): """ The function computes the loss for a single feature. Function computes sum of the loss gradient that have same feature values. @@ -350,12 +350,13 @@ class LutTrainer(): return: hist_grad: The sum of the loss gradient""" # initialize the values - num_samp = len(fval) + num_samp = len(features) hist_grad = numpy.zeros([self.num_entries]) # compute the sum of the gradient - for hi in range(self.num_entries): - hist_grad[hi] = sum(loss_grado[fval == hi]) + for feature_value in range(self.num_entries): + + hist_grad[feature_value] = sum(loss_grado[features == feature_value]) return hist_grad diff --git a/xbob/boosting/tests/datafile.hdf5 b/xbob/boosting/tests/datafile.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..57b7d45c2c220d085e76b1ac3efc48b1ba5112cb GIT binary patch literal 10144 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 DxBgZx literal 0 HcmV?d00001 diff --git a/xbob/boosting/tests/test_trainer_lut.py b/xbob/boosting/tests/test_trainer_lut.py index 3a4c519..f5ed96f 100644 --- a/xbob/boosting/tests/test_trainer_lut.py +++ b/xbob/boosting/tests/test_trainer_lut.py @@ -4,9 +4,6 @@ import xbob.boosting import numpy import bob -def get_single_feature(): - num_feature = 100 - class TestLutTrainer(unittest.TestCase): """Class to test the LUT trainer """ @@ -32,10 +29,63 @@ class TestLutTrainer(unittest.TestCase): + def test_lut_selected_index(self): + + num_samples = 100 + max_feature = 20 + dimension_feature = 10 + + selected_index = 5 + range_feature = max_feature + trainer = xbob.boosting.core.trainers.LutTrainer(range_feature,'indep', 1) + + data_file = bob.io.File('xbob/boosting/tests/datafile.hdf5', 'r') + #features = bob.io.load('test_data.hdf5') + features = data_file.read() + + x_train1 = numpy.copy(features) + x_train1[x_train1[:,selected_index] >=10, selected_index] = 9 + x_train2 = numpy.copy(features) + x_train2[x_train2[:,selected_index] < 10, selected_index] = 10 + x_train = numpy.vstack((x_train1, x_train2)) + + y_train = numpy.vstack((numpy.ones([num_samples,1]),-numpy.ones([num_samples,1]))) + + scores = numpy.zeros([2*num_samples,1]) + loss_grad = -y_train*(numpy.exp(y_train*scores)) + + machine = trainer.compute_weak_trainer(x_train, loss_grad) + + self.assertTrue((machine.luts[0:9] == -1).all()) # The values of the LUT are negative of the classes sign + self.assertTrue((machine.luts[10:] == 1).all()) + + + + def test_lut_selected_index(self): + + num_samples = 100 + max_feature = 20 + dimension_feature = 10 + delta = 5 + selected_index = 5 + range_feature = max_feature + delta + trainer = xbob.boosting.core.trainers.LutTrainer(range_feature,'indep', 1) + data_file = bob.io.File('xbob/boosting/tests/datafile.hdf5', 'r') + + features = data_file.read() + x_train1 = numpy.copy(features) + x_train2 = numpy.copy(features) + x_train = numpy.vstack((x_train1, x_train2)) + x_train[0:num_samples,selected_index] = x_train[0:num_samples,selected_index] + delta + y_train = numpy.vstack((numpy.ones([num_samples,1]),-numpy.ones([num_samples,1]))) + scores = numpy.zeros([2*num_samples,1]) + loss_grad = -y_train*(numpy.exp(y_train*scores)) + machine = trainer.compute_weak_trainer(x_train, loss_grad) + self.assertEqual(machine.selected_indices[0], selected_index) -- GitLab