Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bob
bob.pad.base
Commits
dd21da37
Commit
dd21da37
authored
Jul 12, 2019
by
anjith2006
Committed by
Anjith GEORGE
Aug 21, 2019
Browse files
Mods
parent
4b9c5165
Changes
1
Hide whitespace changes
Inline
Side-by-side
bob/pad/base/algorithm/ScikitClassifier.py
View file @
dd21da37
...
...
@@ -8,8 +8,6 @@ import pickle
import
logging
from
bob.pad.base.utils
import
convert_frame_cont_to_array
,
convert_list_of_frame_cont_to_array
#==============================================================================
class
ScikitClassifier
(
Algorithm
):
"""
...
...
@@ -23,37 +21,37 @@ class ScikitClassifier(Algorithm):
3. At test time, input features are classified using pre-trained Scikit model.
Parameters
----------
----------
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
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
Return scores for each frame individually if True. Otherwise, return a
single score per video. Default: False.
Return scores for each frame individually if True. Otherwise, return a
single score per video. Default: False.
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
Training data subsampling step, only valid is
subsample_train_data_flag = True. Default: 10 .
Training data subsampling step, only valid is
subsample_train_data_flag = True. Default: 10 .
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
Training videos subsampling step, only valid is
subsample_videos_flag = True. Default: 3 .
Training videos subsampling step, only valid is
subsample_videos_flag = True. Default: 3 .
norm_on_bonafide : bool
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.
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.
one_class : bool
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.
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.
"""
...
...
@@ -76,7 +74,7 @@ class ScikitClassifier(Algorithm):
subsample_videos_flag
=
subsample_videos_flag
,
video_subsampling_step
=
video_subsampling_step
,
performs_projection
=
True
,
requires_projector_training
=
True
,
requires_projector_training
=
True
,
norm_on_bonafide
=
norm_on_bonafide
,
one_class
=
one_class
)
...
...
@@ -98,15 +96,11 @@ class ScikitClassifier(Algorithm):
self
.
one_class
=
one_class
if
self
.
one_class
:
assert
(
'score_samples'
in
dir
(
clf
))
assert
(
'score_samples'
in
dir
(
clf
))
else
:
assert
(
'predict_proba'
in
dir
(
clf
))
assert
(
'predict_proba'
in
dir
(
clf
))
#==========================================================================
def
_normalize
(
self
,
features
,
train
=
False
):
"""
The features in the input 2D array are normalized.
...
...
@@ -114,16 +108,16 @@ class ScikitClassifier(Algorithm):
the scaler is trained, else the trained scaler is used for the normalization.
Parameters
----------
----------
features : numpy.ndarray
Array of features to be normalized.
Array of features to be normalized.
Returns
-------
features_norm : numpy.ndarray
Normalized array of features.
Normalized array of features.
"""
...
...
@@ -133,36 +127,35 @@ class ScikitClassifier(Algorithm):
features_norm
=
self
.
scaler
.
transform
(
features
)
else
:
features_norm
=
features
.
copy
()
features_norm
=
features
.
copy
()
return
features_norm
#==========================================================================
def
norm_train_data
(
self
,
real
,
attack
):
"""
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` .
Parameters
----------
----------
real : numpy.ndarray
Training features for the real class.
Training features for the real class.
attack : numpy.ndarray
Training features for the attack class.
Training features for the attack class.
Returns
-------
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
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
)
...
...
@@ -170,7 +163,7 @@ class ScikitClassifier(Algorithm):
else
:
all_data
=
np
.
vstack
([
real
,
attack
])
all_data
=
np
.
vstack
([
real
,
attack
])
_
=
self
.
_normalize
(
all_data
,
train
=
True
)
...
...
@@ -180,25 +173,24 @@ class ScikitClassifier(Algorithm):
return
real_norm
,
attack_norm
#==========================================================================
def
train_clf
(
self
,
real
,
attack
):
"""
Train Scikit classifier given real and attack classes. Prior to training
the data is mean-std normalized.
Parameters
----------
----------
real : numpy.ndarray
Training features for the real class.
Training features for the real class.
attack : numpy.ndarray
Training features for the attack class.
Training features for the attack 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 and attack - are now mean-std normalized
...
...
@@ -207,9 +199,9 @@ class ScikitClassifier(Algorithm):
if
self
.
one_class
:
X
=
real
.
copy
()
X
=
real
.
copy
()
Y
=
np
.
ones
(
len
(
real
))
Y
=
np
.
ones
(
len
(
real
))
self
.
clf
.
fit
(
X
)
...
...
@@ -222,49 +214,47 @@ class ScikitClassifier(Algorithm):
return
True
#==========================================================================
def
save_clf_and_mean_std
(
self
,
projector_file
):
"""
Saves the Scikit Classifier and scaling parameters to '.obj' files.
The absolute name of the file is specified in projector_file string.
Parameters
----------
----------
projector_file : str
Absolute name of the file to save the data to, as returned by
bob.pad.base framework
Absolute name of the file to save the data to, as returned by
bob.pad.base framework
"""
# 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
:
pickle
.
dump
(
self
.
clf
,
fp
)
# 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
:
pickle
.
dump
(
self
.
scaler
,
fp
)
#==========================================================================
def
subsample_train_videos
(
self
,
training_features
,
step
):
"""
Uniformly select subset of frmae containes from the input list
Parameters
----------
----------
training_features : [FrameContainer]
A list of FrameContainers
A list of FrameContainers
step :`int`
Data selection step.
Data selection step.
**Returns:**
training_features_subset : [FrameContainer]
A list with selected FrameContainers
A list with selected FrameContainers
"""
indexes
=
range
(
0
,
len
(
training_features
),
step
)
...
...
@@ -273,7 +263,6 @@ class ScikitClassifier(Algorithm):
return
training_features_subset
#==========================================================================
def
train_projector
(
self
,
training_features
,
projector_file
):
"""
Train Scikit Classifier for feature projection and save them to files.
...
...
@@ -281,16 +270,16 @@ class ScikitClassifier(Algorithm):
to enable this function.
Parameters
----------
----------
training_features : [[FrameContainer], [FrameContainer]]
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 attack class.
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 attack class.
projector_file :`str`
The file to save the trained projector to, as returned by the
bob.pad.base framework.
The file to save the trained projector to, as returned by the
bob.pad.base framework.
"""
# training_features[0] - training features for the REAL class.
...
...
@@ -326,35 +315,32 @@ class ScikitClassifier(Algorithm):
# Save the Scikit Classifier and normalizers:
self
.
save_clf_and_mean_std
(
projector_file
)
#==========================================================================
def
load_clf_and_mean_std
(
self
,
projector_file
):
"""
Loads the machine, features mean and std from the hdf5 file.
The absolute name of the file is specified in projector_file string.
Parameters
----------
----------
projector_file : str
Absolute name of the file to load the trained projector from, as
returned by bob.pad.base framework.
Absolute name of the file to load the trained projector from, as
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:
with
open
(
projector_file_n
,
'rb'
)
as
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:
with
open
(
scaler_file_n
,
'rb'
)
as
fp
:
self
.
scaler
=
pickle
.
load
(
fp
)
#==========================================================================
def
load_projector
(
self
,
projector_file
):
"""
The absolute name of the file is specified in projector_file string.
...
...
@@ -362,18 +348,15 @@ class ScikitClassifier(Algorithm):
This function sets the arguments self.clf, with loaded machines.
Parameters
----------
----------
projector_file : str
The file to read the projector from, as returned by the
bob.pad.base framework.
The file to read the projector from, as returned by the
bob.pad.base framework.
"""
self
.
load_clf_and_mean_std
(
projector_file
)
#==========================================================================
def
project
(
self
,
feature
):
"""
This function computes a vector of scores for each sample in the input
...
...
@@ -389,21 +372,21 @@ class ScikitClassifier(Algorithm):
project function is executed.
Parameters
----------
----------
feature : FrameContainer or numpy.ndarray
Two types of inputs are accepted.
A Frame Container conteining the features of an individual,
see bob.bio.video.utils.FrameContainer.
Or a 2D feature array of the size (N_samples x N_features).
Two types of inputs are accepted.
A Frame Container conteining the features of an individual,
see bob.bio.video.utils.FrameContainer.
Or a 2D feature array of the size (N_samples x N_features).
Returns
-------
scores : numpy.ndarray
Vector of scores. Scores for the real class are expected to be
higher, than the scores of the negative / attack class.
In this case scores are probabilities.
Vector of scores. Scores for the real class are expected to be
higher, than the scores of the negative / attack class.
In this case scores are probabilities.
"""
# 1. Convert input array to numpy array if necessary.
...
...
@@ -415,36 +398,35 @@ class ScikitClassifier(Algorithm):
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
:
scores
=
self
.
clf
.
score_samples
(
features_array_norm
)
scores
=
self
.
clf
.
score_samples
(
features_array_norm
)
else
:
scores
=
self
.
clf
.
predict_proba
(
features_array_norm
)[:,
1
]
return
scores
#==========================================================================
def
score
(
self
,
toscore
):
"""
Returns a probability of a sample being a real class.
Parameters
----------
----------
toscore : numpy.ndarray
Vector with scores for each frame/sample defining the probability
of the frame being a sample of the real class.
Vector with scores for each frame/sample defining the probability
of the frame being a sample of the real class.
Returns
-------
score : float
If frame_level_scores_flag = False a single score is returned.
One score per video. This score is placed into a list, because
the score must be an iterable.
Score is a probability of a sample being a real class.
If frame_level_scores_flag = True a list of scores is returned.
One score per frame/sample.
If frame_level_scores_flag = False a single score is returned.
One score per video. This score is placed into a list, because
the score must be an iterable.
Score is a probability of a sample being a real class.
If frame_level_scores_flag = True a list of scores is returned.
One score per frame/sample.
"""
if
self
.
frame_level_scores_flag
:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment