Commit 4478742b authored by Anjith GEORGE's avatar Anjith GEORGE

WIP: OneclassGMM with the new wrapper, fixes

parent d672805e
Pipeline #36736 passed with stage
in 14 minutes and 33 seconds
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
@author: Anjith George
"""
#==============================================================================
from .ScikitClassifier import ScikitClassifier
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler
class OneClassGMM3(ScikitClassifier):
"""
This class is designed to train a OneClassGMM based PAD system. The OneClassGMM is trained
using data of one class (real class) only. The procedure is the following:
1. First, the training data is mean-std normalized using mean and std of the
real class only.
2. Second, the OneClassGMM with ``n_components`` Gaussians is trained using samples
of the real class.
3. The input features are next classified using pre-trained OneClassGMM machine.
**Parameters:**
``n_components`` : :py:class:`int`
Number of Gaussians in the OneClassGMM. Default: 1 .
``random_state`` : :py:class:`int`
A seed for the random number generator used in the initialization of
the OneClassGMM. Default: 3 .
``frame_level_scores_flag`` : :py:class:`bool`
Return scores for each frame individually if True. Otherwise, return a
single score per video. Default: False.
"""
def __init__(self,
n_components=1,
random_state=3,
frame_level_scores_flag=False,
covariance_type='full',
reg_covar=1e-06,
):
ScikitClassifier.__init__(self,
clf=GaussianMixture(n_components=n_components, random_state=random_state, covariance_type=covariance_type,reg_covar=reg_covar),
scaler=StandardScaler(),
frame_level_scores_flag=frame_level_scores_flag,
norm_on_bonafide=True,
one_class=True)
\ No newline at end of file
......@@ -128,11 +128,10 @@ class ScikitClassifier(Algorithm):
if train:
self.scaler.fit(features)
features_norm = self.scaler.transform(features)
else:
features_norm=features.copy()
features = self.scaler.transform(features)
return features_norm
return features
#==========================================================================
def norm_train_data(self, real, attack):
......@@ -206,11 +205,10 @@ class ScikitClassifier(Algorithm):
if self.one_class:
X=real.copy()
Y=np.ones(len(real))
self.clf.fit(X)
self.clf.fit(real)
else:
X = np.vstack([real, attack])
......
......@@ -2,6 +2,8 @@ from .Algorithm import Algorithm
from .SVM import SVM
from .OneClassGMM import OneClassGMM
from .OneClassGMM2 import OneClassGMM2
from .OneClassGMM3 import OneClassGMM3
from .LogRegr import LogRegr
from .SVMCascadePCA import SVMCascadePCA
from .Predictions import Predictions, VideoPredictions
......@@ -33,6 +35,7 @@ __appropriate__(
SVM,
OneClassGMM,
OneClassGMM2,
OneClassGMM3,
LogRegr,
SVMCascadePCA,
Predictions,
......
......@@ -11,11 +11,11 @@ import bob.bio.video
import bob.pad.base
from bob.pad.base.algorithm import SVM
from bob.pad.base.algorithm import OneClassGMM
from bob.pad.base.algorithm import OneClassGMM, OneClassGMM3
from bob.pad.base.algorithm import MLP
from bob.pad.base.algorithm import PadLDA
from bob.pad.base.algorithm import ScikitClassifier
import os
import random
from bob.pad.base.utils import (
......@@ -157,6 +157,56 @@ def test_video_gmm_pad_algorithm():
assert (np.max(scores_attack) + 5.3633030621521272) < 0.000001
def test_video_gmm_pad_algorithm_3():
random.seed(7)
N = 1000
mu = 1
sigma = 1
real_array = np.transpose(
np.vstack([[random.gauss(mu, sigma) for _ in range(N)],
[random.gauss(mu, sigma) for _ in range(N)]]))
mu = 5
sigma = 1
attack_array = np.transpose(
np.vstack([[random.gauss(mu, sigma) for _ in range(N)],
[random.gauss(mu, sigma) for _ in range(N)]]))
real = convert_array_to_list_of_frame_cont(real_array)
attack = convert_array_to_list_of_frame_cont(attack_array)
N_COMPONENTS = 1
RANDOM_STATE = 3
FRAME_LEVEL_SCORES_FLAG = True
algorithm = OneClassGMM3(
n_components=N_COMPONENTS,
random_state=RANDOM_STATE,
frame_level_scores_flag=FRAME_LEVEL_SCORES_FLAG)
# training_features[0] - training features for the REAL class.
real_array_converted = convert_list_of_frame_cont_to_array(real) # output is array
attack_array_converted = convert_list_of_frame_cont_to_array(attack) # output is array
assert (real_array == real_array_converted).all()
# Train the OneClassGMM machine and get normalizers:
status = algorithm.train_clf(
real=real_array_converted, attack=attack_array_converted)
scores_real = algorithm.project(real_array_converted)
scores_attack = algorithm.project(attack_array)
assert (np.min(scores_real) + 7.9423798970985917) < 0.000001
assert (np.max(scores_real) + 1.8380480068281055) < 0.000001
assert (np.min(scores_attack) + 38.831260843070098) < 0.000001
assert (np.max(scores_attack) + 5.3633030621521272) < 0.000001
def test_convert_list_of_frame_cont_to_array():
N = 1000
......@@ -226,6 +276,7 @@ def test_LDA():
def test_ScikitClassifier():
random.seed(7)
os.mkdir('tmp')
N = 20000
mu = 1
......@@ -250,10 +301,10 @@ def test_ScikitClassifier():
_clf = GaussianMixture(n_components=10, covariance_type='full')
sk = ScikitClassifier(clf=_clf, scaler=_scaler, frame_level_scores_flag=False, one_class=True)
sk.train_projector(training_features, '/tmp/sk.hdf5')
sk.train_projector(training_features, 'tmp/sk.hdf5')
# Model path `/tmp/sk_skmodel.obj`
# Scaler path `/tmp/sk_scaler.obj`
# Model path `tmp/sk_skmodel.obj`
# Scaler path `tmp/sk_scaler.obj`
assert sk.clf.n_components==10
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