Commit ab7cb609 authored by anjith2006's avatar anjith2006 Committed by Anjith GEORGE
Browse files

Mods

parent cc42de3f
...@@ -8,8 +8,6 @@ import pickle ...@@ -8,8 +8,6 @@ import pickle
import logging import logging
from bob.pad.base.utils import convert_frame_cont_to_array, convert_list_of_frame_cont_to_array from bob.pad.base.utils import convert_frame_cont_to_array, convert_list_of_frame_cont_to_array
#==============================================================================
class ScikitClassifier(Algorithm): class ScikitClassifier(Algorithm):
""" """
...@@ -23,37 +21,37 @@ class ScikitClassifier(Algorithm): ...@@ -23,37 +21,37 @@ class ScikitClassifier(Algorithm):
3. At test time, input features are classified using pre-trained Scikit model. 3. At test time, input features are classified using pre-trained Scikit model.
Parameters Parameters
---------- ----------
clf : object clf : object
An sklearn binary classifier or outlier detector instance, which is initialized in the config file. An sklearn binary classifier or outlier detector instance, which is initialized in the config file.
scaler : object scaler : object
An sklearn scaler instance which is initialized in the config file. An sklearn scaler instance which is initialized in the config file.
frame_level_scores_flag :bool frame_level_scores_flag :bool
Return scores for each frame individually if True. Otherwise, return a Return scores for each frame individually if True. Otherwise, return a
single score per video. Default: False. single score per video. Default: False.
subsample_train_data_flag : bool subsample_train_data_flag : bool
Uniformly subsample the training data if True. Default: False. Uniformly subsample the training data if True. Default: False.
subsampling_step : int subsampling_step : int
Training data subsampling step, only valid is Training data subsampling step, only valid is
subsample_train_data_flag = True. Default: 10 . subsample_train_data_flag = True. Default: 10 .
subsample_videos_flag : bool subsample_videos_flag : bool
Uniformly subsample the training videos if True. Default: False. Uniformly subsample the training videos if True. Default: False.
video_subsampling_step : int video_subsampling_step : int
Training videos subsampling step, only valid is Training videos subsampling step, only valid is
subsample_videos_flag = True. Default: 3 . subsample_videos_flag = True. Default: 3 .
norm_on_bonafide : bool norm_on_bonafide : bool
If set to `True` the normalizayion parameters are found from bonafide samples If set to `True` the normalizayion parameters are found from bonafide samples
only. If set to `False`, both bonafide and attacks will be used to find normalization parameters. only. If set to `False`, both bonafide and attacks will be used to find normalization parameters.
one_class : bool one_class : bool
If set to `True`, the classifier is assumed to be one class, and training and scoring would be performed If set to `True`, the classifier is assumed to be one class, and training and scoring would be performed
according to this assumption. The type of classifer either binary/ one class should be specified with this argument. according to this assumption. The type of classifer either binary/ one class should be specified with this argument.
""" """
...@@ -76,7 +74,7 @@ class ScikitClassifier(Algorithm): ...@@ -76,7 +74,7 @@ class ScikitClassifier(Algorithm):
subsample_videos_flag=subsample_videos_flag, subsample_videos_flag=subsample_videos_flag,
video_subsampling_step=video_subsampling_step, video_subsampling_step=video_subsampling_step,
performs_projection=True, performs_projection=True,
requires_projector_training=True, requires_projector_training=True,
norm_on_bonafide=norm_on_bonafide, norm_on_bonafide=norm_on_bonafide,
one_class=one_class) one_class=one_class)
...@@ -98,15 +96,11 @@ class ScikitClassifier(Algorithm): ...@@ -98,15 +96,11 @@ class ScikitClassifier(Algorithm):
self.one_class = one_class self.one_class = one_class
if self.one_class: if self.one_class:
assert('score_samples' in dir(clf)) assert('score_samples' in dir(clf))
else: else:
assert('predict_proba' in dir(clf)) assert('predict_proba' in dir(clf))
#==========================================================================
def _normalize(self, features, train=False): def _normalize(self, features, train=False):
""" """
The features in the input 2D array are normalized. The features in the input 2D array are normalized.
...@@ -114,16 +108,16 @@ class ScikitClassifier(Algorithm): ...@@ -114,16 +108,16 @@ class ScikitClassifier(Algorithm):
the scaler is trained, else the trained scaler is used for the normalization. the scaler is trained, else the trained scaler is used for the normalization.
Parameters Parameters
---------- ----------
features : numpy.ndarray features : numpy.ndarray
Array of features to be normalized. Array of features to be normalized.
Returns Returns
------- -------
features_norm : numpy.ndarray features_norm : numpy.ndarray
Normalized array of features. Normalized array of features.
""" """
...@@ -133,36 +127,35 @@ class ScikitClassifier(Algorithm): ...@@ -133,36 +127,35 @@ class ScikitClassifier(Algorithm):
features_norm = self.scaler.transform(features) features_norm = self.scaler.transform(features)
else: else:
features_norm=features.copy() features_norm = features.copy()
return features_norm return features_norm
#==========================================================================
def norm_train_data(self, real, attack): def norm_train_data(self, real, attack):
""" """
Mean-std normalization of input data arrays. The mean and std normalizers Mean-std normalization of input data arrays. The mean and std normalizers
are computed using real class only, unless `self.norm_on_bonafide` is set to `True` . are computed using real class only, unless `self.norm_on_bonafide` is set to `True` .
Parameters Parameters
---------- ----------
real : numpy.ndarray real : numpy.ndarray
Training features for the real class. Training features for the real class.
attack : numpy.ndarray attack : numpy.ndarray
Training features for the attack class. Training features for the attack class.
Returns Returns
------- -------
real_norm : numpy.ndarray real_norm : numpy.ndarray
Mean-std normalized training features for the real class. Mean-std normalized training features for the real class.
attack_norm : numpy.ndarray attack_norm : numpy.ndarray
Mean-std normalized training features for the attack class. Mean-std normalized training features for the attack class.
""" """
if self.norm_on_bonafide: # normalization parameters calculated from bonafide only if self.norm_on_bonafide: # normalization parameters calculated from bonafide only
real_norm = self._normalize(real, train=True) real_norm = self._normalize(real, train=True)
...@@ -170,7 +163,7 @@ class ScikitClassifier(Algorithm): ...@@ -170,7 +163,7 @@ class ScikitClassifier(Algorithm):
else: else:
all_data=np.vstack([real, attack]) all_data = np.vstack([real, attack])
_ = self._normalize(all_data, train=True) _ = self._normalize(all_data, train=True)
...@@ -180,25 +173,24 @@ class ScikitClassifier(Algorithm): ...@@ -180,25 +173,24 @@ class ScikitClassifier(Algorithm):
return real_norm, attack_norm return real_norm, attack_norm
#==========================================================================
def train_clf(self, real, attack): def train_clf(self, real, attack):
""" """
Train Scikit classifier given real and attack classes. Prior to training Train Scikit classifier given real and attack classes. Prior to training
the data is mean-std normalized. the data is mean-std normalized.
Parameters Parameters
---------- ----------
real : numpy.ndarray real : numpy.ndarray
Training features for the real class. Training features for the real class.
attack : numpy.ndarray attack : numpy.ndarray
Training features for the attack class. Training features for the attack class.
""" """
if self.one_class: if self.one_class:
assert(self.norm_on_bonafide==True) assert(self.norm_on_bonafide == True)
real, attack = self.norm_train_data(real, attack) real, attack = self.norm_train_data(real, attack)
# real and attack - are now mean-std normalized # real and attack - are now mean-std normalized
...@@ -207,9 +199,9 @@ class ScikitClassifier(Algorithm): ...@@ -207,9 +199,9 @@ class ScikitClassifier(Algorithm):
if self.one_class: if self.one_class:
X=real.copy() X = real.copy()
Y=np.ones(len(real)) Y = np.ones(len(real))
self.clf.fit(X) self.clf.fit(X)
...@@ -222,49 +214,47 @@ class ScikitClassifier(Algorithm): ...@@ -222,49 +214,47 @@ class ScikitClassifier(Algorithm):
return True return True
#==========================================================================
def save_clf_and_mean_std(self, projector_file): def save_clf_and_mean_std(self, projector_file):
""" """
Saves the Scikit Classifier and scaling parameters to '.obj' files. Saves the Scikit Classifier and scaling parameters to '.obj' files.
The absolute name of the file is specified in projector_file string. The absolute name of the file is specified in projector_file string.
Parameters Parameters
---------- ----------
projector_file : str projector_file : str
Absolute name of the file to save the data to, as returned by Absolute name of the file to save the data to, as returned by
bob.pad.base framework bob.pad.base framework
""" """
# Saving scikit classifier # Saving scikit classifier
projector_file_n = projector_file[:-5]+'_skmodel.obj' projector_file_n = projector_file[:-5] + '_skmodel.obj'
with open(projector_file_n, 'wb') as fp: with open(projector_file_n, 'wb') as fp:
pickle.dump(self.clf, fp) pickle.dump(self.clf, fp)
# Saving the scaler # Saving the scaler
scaler_file_n = projector_file[:-5]+'_scaler.obj' scaler_file_n = projector_file[:-5] + '_scaler.obj'
with open(scaler_file_n, 'wb') as fp: with open(scaler_file_n, 'wb') as fp:
pickle.dump(self.scaler, fp) pickle.dump(self.scaler, fp)
#==========================================================================
def subsample_train_videos(self, training_features, step): def subsample_train_videos(self, training_features, step):
""" """
Uniformly select subset of frmae containes from the input list Uniformly select subset of frmae containes from the input list
Parameters Parameters
---------- ----------
training_features : [FrameContainer] training_features : [FrameContainer]
A list of FrameContainers A list of FrameContainers
step :`int` step :`int`
Data selection step. Data selection step.
**Returns:** **Returns:**
training_features_subset : [FrameContainer] training_features_subset : [FrameContainer]
A list with selected FrameContainers A list with selected FrameContainers
""" """
indexes = range(0, len(training_features), step) indexes = range(0, len(training_features), step)
...@@ -273,7 +263,6 @@ class ScikitClassifier(Algorithm): ...@@ -273,7 +263,6 @@ class ScikitClassifier(Algorithm):
return training_features_subset return training_features_subset
#==========================================================================
def train_projector(self, training_features, projector_file): def train_projector(self, training_features, projector_file):
""" """
Train Scikit Classifier for feature projection and save them to files. Train Scikit Classifier for feature projection and save them to files.
...@@ -281,16 +270,16 @@ class ScikitClassifier(Algorithm): ...@@ -281,16 +270,16 @@ class ScikitClassifier(Algorithm):
to enable this function. to enable this function.
Parameters Parameters
---------- ----------
training_features : [[FrameContainer], [FrameContainer]] training_features : [[FrameContainer], [FrameContainer]]
A list containing two elements: [0] - a list of Frame Containers with A list containing two elements: [0] - a list of Frame Containers with
feature vectors for the real class; [1] - a list of Frame Containers with feature vectors for the real class; [1] - a list of Frame Containers with
feature vectors for the attack class. feature vectors for the attack class.
projector_file :`str` projector_file :`str`
The file to save the trained projector to, as returned by the The file to save the trained projector to, as returned by the
bob.pad.base framework. bob.pad.base framework.
""" """
# training_features[0] - training features for the REAL class. # training_features[0] - training features for the REAL class.
...@@ -326,35 +315,32 @@ class ScikitClassifier(Algorithm): ...@@ -326,35 +315,32 @@ class ScikitClassifier(Algorithm):
# Save the Scikit Classifier and normalizers: # Save the Scikit Classifier and normalizers:
self.save_clf_and_mean_std(projector_file) self.save_clf_and_mean_std(projector_file)
#==========================================================================
def load_clf_and_mean_std(self, projector_file): def load_clf_and_mean_std(self, projector_file):
""" """
Loads the machine, features mean and std from the hdf5 file. Loads the machine, features mean and std from the hdf5 file.
The absolute name of the file is specified in projector_file string. The absolute name of the file is specified in projector_file string.
Parameters Parameters
---------- ----------
projector_file : str projector_file : str
Absolute name of the file to load the trained projector from, as Absolute name of the file to load the trained projector from, as
returned by bob.pad.base framework. returned by bob.pad.base framework.
""" """
projector_file_n = projector_file[:-5]+'_skmodel.obj' projector_file_n = projector_file[:-5] + '_skmodel.obj'
# Load the params of the machine: # Load the params of the machine:
with open(projector_file_n, 'rb') as fp: with open(projector_file_n, 'rb') as fp:
self.clf = pickle.load(fp) self.clf = pickle.load(fp)
scaler_file_n = projector_file[:-5]+'_scaler.obj' scaler_file_n = projector_file[:-5] + '_scaler.obj'
# Load parameters of the scaler: # Load parameters of the scaler:
with open(scaler_file_n, 'rb') as fp: with open(scaler_file_n, 'rb') as fp:
self.scaler = pickle.load(fp) self.scaler = pickle.load(fp)
#==========================================================================
def load_projector(self, projector_file): def load_projector(self, projector_file):
""" """
The absolute name of the file is specified in projector_file string. The absolute name of the file is specified in projector_file string.
...@@ -362,18 +348,15 @@ class ScikitClassifier(Algorithm): ...@@ -362,18 +348,15 @@ class ScikitClassifier(Algorithm):
This function sets the arguments self.clf, with loaded machines. This function sets the arguments self.clf, with loaded machines.
Parameters Parameters
---------- ----------
projector_file : str projector_file : str
The file to read the projector from, as returned by the The file to read the projector from, as returned by the
bob.pad.base framework. bob.pad.base framework.
""" """
self.load_clf_and_mean_std(projector_file) self.load_clf_and_mean_std(projector_file)
#==========================================================================
def project(self, feature): def project(self, feature):
""" """
This function computes a vector of scores for each sample in the input This function computes a vector of scores for each sample in the input
...@@ -389,21 +372,21 @@ class ScikitClassifier(Algorithm): ...@@ -389,21 +372,21 @@ class ScikitClassifier(Algorithm):
project function is executed. project function is executed.
Parameters Parameters
---------- ----------
feature : FrameContainer or numpy.ndarray feature : FrameContainer or numpy.ndarray
Two types of inputs are accepted. Two types of inputs are accepted.
A Frame Container conteining the features of an individual, A Frame Container conteining the features of an individual,
see bob.bio.video.utils.FrameContainer. see bob.bio.video.utils.FrameContainer.
Or a 2D feature array of the size (N_samples x N_features). Or a 2D feature array of the size (N_samples x N_features).
Returns Returns
------- -------
scores : numpy.ndarray scores : numpy.ndarray
Vector of scores. Scores for the real class are expected to be Vector of scores. Scores for the real class are expected to be
higher, than the scores of the negative / attack class. higher, than the scores of the negative / attack class.
In this case scores are probabilities. In this case scores are probabilities.
""" """
# 1. Convert input array to numpy array if necessary. # 1. Convert input array to numpy array if necessary.
...@@ -415,36 +398,35 @@ class ScikitClassifier(Algorithm): ...@@ -415,36 +398,35 @@ class ScikitClassifier(Algorithm):
features_array = feature.copy() features_array = feature.copy()
features_array_norm = self._normalize(features_array, train =False) features_array_norm = self._normalize(features_array, train=False)
if self.one_class: if self.one_class:
scores= self.clf.score_samples(features_array_norm) scores = self.clf.score_samples(features_array_norm)
else: else:
scores = self.clf.predict_proba(features_array_norm)[:, 1] scores = self.clf.predict_proba(features_array_norm)[:, 1]
return scores return scores
#==========================================================================
def score(self, toscore): def score(self, toscore):
""" """
Returns a probability of a sample being a real class. Returns a probability of a sample being a real class.
Parameters Parameters
---------- ----------
toscore : numpy.ndarray toscore : numpy.ndarray
Vector with scores for each frame/sample defining the probability Vector with scores for each frame/sample defining the probability
of the frame being a sample of the real class. of the frame being a sample of the real class.
Returns Returns
------- -------
score : float score : float
If frame_level_scores_flag = False a single score is returned. If frame_level_scores_flag = False a single score is returned.
One score per video. This score is placed into a list, because One score per video. This score is placed into a list, because
the score must be an iterable. the score must be an iterable.
Score is a probability of a sample being a real class. Score is a probability of a sample being a real class.
If frame_level_scores_flag = True a list of scores is returned. If frame_level_scores_flag = True a list of scores is returned.
One score per frame/sample. One score per frame/sample.
""" """
if self.frame_level_scores_flag: if self.frame_level_scores_flag:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment