From 13c7964dbfa216cbe9868c421377790045dc5116 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS <onikisins@italix03.idiap.ch> Date: Mon, 29 May 2017 13:31:57 +0200 Subject: [PATCH] Changed the LBP+SVM pipeline settings to partially match Ivana's paper --- .../face/algorithm/VideoSvmPadAlgorithm.py | 81 +++++++++++++++++-- .../config/extractor/video_lbp_histogram.py | 25 ++---- bob/pad/face/config/grid.py | 4 +- .../config/preprocessor/video_face_crop.py | 14 ++-- setup.py | 5 +- 5 files changed, 92 insertions(+), 37 deletions(-) diff --git a/bob/pad/face/algorithm/VideoSvmPadAlgorithm.py b/bob/pad/face/algorithm/VideoSvmPadAlgorithm.py index a6225ecb..ef921338 100644 --- a/bob/pad/face/algorithm/VideoSvmPadAlgorithm.py +++ b/bob/pad/face/algorithm/VideoSvmPadAlgorithm.py @@ -17,6 +17,10 @@ import numpy as np import bob.learn.libsvm +import bob.io.base + +import os + #============================================================================== # Main body : @@ -52,6 +56,10 @@ class VideoSvmPadAlgorithm(Algorithm): ``mean_std_norm_flag`` : :py:class:`bool` Perform mean-std normalization of data if set to True. Default: False. + + ``frame_level_scores`` : :py:class:`bool` + Return scores for each frame individually if True. Otherwise, return a + single score per video. Default: False. """ def __init__(self, @@ -59,7 +67,8 @@ class VideoSvmPadAlgorithm(Algorithm): kernel_type = 'RBF', n_samples = 10000, trainer_grid_search_params = { 'cost': [2**p for p in range(-5, 16, 2)], 'gamma': [2**p for p in range(-15, 4, 2)]}, - mean_std_norm_flag = False): + mean_std_norm_flag = False, + frame_level_scores = False): Algorithm.__init__(self, @@ -68,6 +77,7 @@ class VideoSvmPadAlgorithm(Algorithm): n_samples = n_samples, trainer_grid_search_params = trainer_grid_search_params, mean_std_norm_flag = mean_std_norm_flag, + frame_level_scores = frame_level_scores, performs_projection=True, requires_projector_training=True) @@ -76,6 +86,7 @@ class VideoSvmPadAlgorithm(Algorithm): self.n_samples = n_samples self.trainer_grid_search_params = trainer_grid_search_params self.mean_std_norm_flag = mean_std_norm_flag + self.frame_level_scores = frame_level_scores self.machine = None @@ -434,7 +445,8 @@ class VideoSvmPadAlgorithm(Algorithm): def train_svm(self, training_features, n_samples = 10000, machine_type = 'C_SVC', kernel_type = 'RBF', trainer_grid_search_params = { 'cost': [2**p for p in range(-5, 16, 2)], 'gamma': [2**p for p in range(-15, 4, 2)]}, - mean_std_norm_flag = False): + mean_std_norm_flag = False, + projector_file = ""): """ First, this function tunes the hyper-parameters of the SVM classifier using grid search on the sub-sets of training data. Train and cross-validation @@ -469,6 +481,12 @@ class VideoSvmPadAlgorithm(Algorithm): ``mean_std_norm_flag`` : :py:class:`bool` Perform mean-std normalization of data if set to True. Default: False. + ``projector_file`` : :py:class:`str` + The name of the file to save the trained projector to. Only the path + of this file is used in this function. The file debug_data.hdf5 will + be save in this path. This file contains information, which might be + usefull for debugging. + **Returns:** ``machine`` : object @@ -525,6 +543,18 @@ class VideoSvmPadAlgorithm(Algorithm): setattr(trainer, key, selected_params[key]) # set the params of trainer + # Save the data, which is usefull for debugging. + debug_file = os.path.join( os.path.split(projector_file)[0], "debug_data.hdf5" ) + debug_dict = {} + debug_dict['precisions_train'] = precisions_train + debug_dict['precisions_cv'] = precisions_cv + debug_dict['cost'] = selected_params['cost'] + debug_dict['gamma'] = selected_params['gamma'] + f = bob.io.base.HDF5File(debug_file, 'w') # open hdf5 file to save the debug data + for key in debug_dict.keys(): + f.set(key, debug_dict[key]) + del f + # training_features[0] - training features for the REAL class. real = self.convert_list_of_frame_cont_to_array(training_features[0]) # output is array # training_features[1] - training features for the ATTACK class. @@ -574,10 +604,14 @@ class VideoSvmPadAlgorithm(Algorithm): machine_type = self.machine_type, kernel_type = self.kernel_type, trainer_grid_search_params = self.trainer_grid_search_params, - mean_std_norm_flag = self.mean_std_norm_flag) + mean_std_norm_flag = self.mean_std_norm_flag, + projector_file = projector_file) + + f = bob.io.base.HDF5File(projector_file, 'w') # open hdf5 file to save to + machine.save(f) # save the machine and normalization parameters - machine.save(projector_file) + del f #========================================================================== @@ -596,7 +630,11 @@ class VideoSvmPadAlgorithm(Algorithm): The file to read the projector from. """ - self.machine = bob.learn.libsvm.Machine(projector_file) + f = bob.io.base.HDF5File(projector_file, 'a') + + self.machine = bob.learn.libsvm.Machine(f) + + del f #========================================================================== @@ -648,22 +686,49 @@ class VideoSvmPadAlgorithm(Algorithm): **Returns:** ``score`` : :py:class:`float` + or a list of scores containing individual score for each frame. A score value for the object ``toscore``. A probability of a sample being a real class. """ - score = np.mean(toscore, axis=0)[0] + if self.frame_level_scores: + + score = toscore[:,0] # here score is a list containing scores for each frame + + else: + + score = np.mean(toscore, axis=0)[0] # compute a single score per video return score #========================================================================== def score_for_multiple_projections(self, toscore): - """Returns the difference between log likelihoods of being real or attack""" + """ + Returns a list of scores computed by the score method of this class. + + **Parameters:** + + ``toscore`` : 2D :py:class:`numpy.ndarray` + An array containing scores computed by score() method of this class. + + **Returns:** + + ``list_of_scores`` : list + A list containing the scores. + """ # import ipdb; ipdb.set_trace() - return [self.score(toscore)] + if self.frame_level_scores: + + list_of_scores = self.score(toscore) + + else: + + list_of_scores = [self.score(toscore)] + + return list_of_scores diff --git a/bob/pad/face/config/extractor/video_lbp_histogram.py b/bob/pad/face/config/extractor/video_lbp_histogram.py index d9d3e96c..ee0ec7f7 100644 --- a/bob/pad/face/config/extractor/video_lbp_histogram.py +++ b/bob/pad/face/config/extractor/video_lbp_histogram.py @@ -6,25 +6,16 @@ from bob.pad.face.extractor import VideoLBPHistogram #======================================================================================= # Define instances here: -lbptype='regular' +lbptype='uniform' elbptype='regular' -rad=3 +rad=1 neighbors=8 circ=False dtype=None -video_lbp_histogram_extractor_n8r3 = VideoLBPHistogram(lbptype=lbptype, - elbptype=elbptype, - rad=rad, - neighbors=neighbors, - circ=circ, - dtype=dtype) - -lbptype='uniform' - -video_lbp_histogram_extractor_n8r3_uniform = VideoLBPHistogram(lbptype=lbptype, - elbptype=elbptype, - rad=rad, - neighbors=neighbors, - circ=circ, - dtype=dtype) \ No newline at end of file +video_lbp_histogram_extractor_n8r1_uniform = VideoLBPHistogram(lbptype=lbptype, + elbptype=elbptype, + rad=rad, + neighbors=neighbors, + circ=circ, + dtype=dtype) diff --git a/bob/pad/face/config/grid.py b/bob/pad/face/config/grid.py index 3cddf7e5..12d4c405 100644 --- a/bob/pad/face/config/grid.py +++ b/bob/pad/face/config/grid.py @@ -19,7 +19,7 @@ idiap = Grid( number_of_enrollment_jobs=32, enrollment_queue='8G-io-big', - number_of_scoring_jobs=50, + number_of_scoring_jobs=1, scoring_queue='8G-io-big', ) @@ -39,6 +39,6 @@ idiap_user_machines = Grid( number_of_enrollment_jobs=32, enrollment_queue='8G', - number_of_scoring_jobs=50, + number_of_scoring_jobs=1, scoring_queue='8G', ) diff --git a/bob/pad/face/config/preprocessor/video_face_crop.py b/bob/pad/face/config/preprocessor/video_face_crop.py index b210d189..61eaf725 100644 --- a/bob/pad/face/config/preprocessor/video_face_crop.py +++ b/bob/pad/face/config/preprocessor/video_face_crop.py @@ -6,15 +6,15 @@ from bob.pad.face.preprocessor import VideoFaceCrop #======================================================================================= # Define instances here: -cropped_image_size = (100, 100) # The size of the resulting face -cropped_positions = { 'topleft' : (0,0) , 'bottomright' : cropped_image_size} +cropped_image_size = (64, 64) # The size of the resulting face +cropped_positions = {'topleft' : (0,0) , 'bottomright' : cropped_image_size} fixed_positions = None -mask_sigma = None # The sigma for random values areas outside image -mask_neighbors = 5 # The number of neighbors to consider while extrapolating -mask_seed = None # The seed for generating random values during extrapolation -color_channel = 'gray' # Convert image to gray-scale format +mask_sigma = None # The sigma for random values areas outside image +mask_neighbors = 5 # The number of neighbors to consider while extrapolating +mask_seed = None # The seed for generating random values during extrapolation +color_channel = 'gray' # Convert image to gray-scale format -video_face_crop_preproc_100_100 = VideoFaceCrop(cropped_image_size = cropped_image_size, +video_face_crop_preproc_64_64 = VideoFaceCrop(cropped_image_size = cropped_image_size, cropped_positions = cropped_positions, fixed_positions = fixed_positions, mask_sigma = mask_sigma, diff --git a/setup.py b/setup.py index 53dab1e9..791a68e8 100644 --- a/setup.py +++ b/setup.py @@ -100,13 +100,12 @@ setup( # registered preprocessors: 'bob.pad.preprocessor': [ - 'video-face-crop-preproc-100 = bob.pad.face.config.preprocessor.video_face_crop:video_face_crop_preproc_100_100', + 'video-face-crop-preproc-64 = bob.pad.face.config.preprocessor.video_face_crop:video_face_crop_preproc_64_64', ], # registered preprocessors: 'bob.pad.extractor': [ - 'video-lbp-histogram-extractor-n8r3 = bob.pad.face.config.extractor.video_lbp_histogram:video_lbp_histogram_extractor_n8r3', - 'video-lbp-histogram-extractor-n8r3-uniform = bob.pad.face.config.extractor.video_lbp_histogram:video_lbp_histogram_extractor_n8r3_uniform', + 'video-lbp-histogram-extractor-n8r1-uniform = bob.pad.face.config.extractor.video_lbp_histogram:video_lbp_histogram_extractor_n8r1_uniform', ], # registered algorithms: -- GitLab