diff --git a/bob/pad/face/algorithm/VideoCascadeSvmPadAlgorithm.py b/bob/pad/face/algorithm/VideoCascadeSvmPadAlgorithm.py
index c5955171ad728f346d5e4aa40a206b76743c04a9..2f04d931bdf935016dce6da21d9781f3c9d49d33 100644
--- a/bob/pad/face/algorithm/VideoCascadeSvmPadAlgorithm.py
+++ b/bob/pad/face/algorithm/VideoCascadeSvmPadAlgorithm.py
@@ -15,6 +15,8 @@ import numpy as np
 
 import bob.learn.libsvm
 
+import bob.learn.linear
+
 import bob.io.base
 
 import os
@@ -759,13 +761,13 @@ class VideoCascadeSvmPadAlgorithm(Algorithm):
 
         resulting_file_name = os.path.join( os.path.split(projector_file)[0], projector_file_name + extension ) # name of the file
 
-        f = bob.io.base.HDF5File(resulting_file_name, 'a') # file to read the machine from
+        f = bob.io.base.HDF5File(resulting_file_name, 'r') # file to read the machine from
 
-        if "pca_" in resulting_file_name:
+        if "pca_" in projector_file_name:
 
             machine = bob.learn.linear.Machine(f)
 
-        if "svm_" in resulting_file_name:
+        if "svm_" in projector_file_name:
 
             machine = bob.learn.libsvm.Machine(f)
 
@@ -1014,57 +1016,26 @@ class VideoCascadeSvmPadAlgorithm(Algorithm):
 
         **Returns:**
 
-        ``score`` : :py:class:`float` or a 1D :py:class:`numpy.ndarray`
+        ``score`` : [:py:class:`float`]
             If ``frame_level_scores_flag = False`` a single score is returned.
-            One score per video.
-            Score is a probability of a sample being a real class.
-            If ``frame_level_scores_flag = True`` a 1D array of scores is returned.
-            One score per frame.
+            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:
 
-            score = toscore # here score is a 1D array containing scores for each frame
+            score = list(toscore)
 
         else:
 
-            score = np.mean( toscore ) # compute a single score per video
+            score = [np.mean( toscore )] # compute a single score per video
 
         return score
 
 
-    #==========================================================================
-    def score_for_multiple_projections(self, toscore):
-        """
-        Returns a list of scores computed by the score method of this class.
-
-        **Parameters:**
-
-        ``toscore`` : 1D or 2D :py:class:`numpy.ndarray`
-            2D in the case of two-class SVM.
-            An array containing class probabilities for each frame.
-            First column contains probabilities for each frame being a real class.
-            Second column contains probabilities for each frame being an attack class.
-            1D in the case of one-class SVM.
-            Vector with scores for each frame defining belonging to the real class.
-
-        **Returns:**
-
-        ``list_of_scores`` : [:py:class:`float`]
-            A list containing the scores.
-        """
-
-        scores = self.score(toscore) # returns float score or 1D array of scores
-
-        if isinstance(scores, np.float): # if a single score
-
-            list_of_scores = [scores]
-
-        else:
-
-            list_of_scores = list(scores)
 
-        return list_of_scores
 
 
diff --git a/bob/pad/face/algorithm/VideoLRPadAlgorithm.py b/bob/pad/face/algorithm/VideoLRPadAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..a078fb6b9ad3cd0bac4445a293e59da3abcba276
--- /dev/null
+++ b/bob/pad/face/algorithm/VideoLRPadAlgorithm.py
@@ -0,0 +1,512 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+"""
+Created on Fri Aug 25 09:29:02 2017
+
+@author: Olegs Nikisins
+"""
+
+#==============================================================================
+# Import what is needed here:
+
+from bob.pad.base.algorithm import Algorithm
+
+from bob.bio.video.utils import FrameContainer
+
+import numpy as np
+
+from sklearn import linear_model
+
+import bob.io.base
+
+
+#==============================================================================
+# Main body :
+
+class VideoLRPadAlgorithm(Algorithm):
+    """
+    This class is designed to Logistic Regression classifier given Frame Containers
+    with features of real and attack classes. The procedure is the following:
+
+    1. First, the input data is mean-std normalized using mean and std of the
+       real class only.
+
+    2. Second, the Logistic Regression classifier is trained on normalized
+       input features.
+
+    3. The input features are next classified using pre-trained LR machine.
+
+    **Parameters:**
+
+    ``C`` : :py:class:`float`
+        Inverse of regularization strength in LR classifier; must be a positive.
+        Like in support vector machines, smaller values specify stronger
+        regularization. Default: 1.0 .
+
+    ``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,
+                 C = 1,
+                 frame_level_scores_flag = False):
+
+
+        Algorithm.__init__(self,
+                           C = C,
+                           frame_level_scores_flag = frame_level_scores_flag,
+                           performs_projection=True,
+                           requires_projector_training=True)
+
+        self.C = C
+
+        self.frame_level_scores_flag = frame_level_scores_flag
+
+        self.lr_machine = None # this argument will be updated with pretrained LR machine
+
+        self.features_mean = None # this argument will be updated with features mean
+        self.features_std = None # this argument will be updated with features std
+
+        # names of the arguments of the pretrained LR machine to be saved/loaded to/from HDF5 file:
+        self.lr_param_keys = ["C", "classes_", "coef_", "intercept_"]
+
+
+    #==========================================================================
+    def convert_frame_cont_to_array(self, frame_container):
+        """
+        This function converts a single Frame Container into an array of features.
+        The rows are samples, the columns are features.
+
+        **Parameters:**
+
+        ``frame_container`` : object
+            A Frame Container conteining the features of an individual,
+            see ``bob.bio.video.utils.FrameContainer``.
+
+        **Returns:**
+
+        ``features_array`` : 2D :py:class:`numpy.ndarray`
+            An array containing features for all frames.
+            The rows are samples, the columns are features.
+        """
+
+        feature_vectors = []
+
+        frame_dictionary = {}
+
+        for frame in frame_container:
+
+            frame_dictionary[frame[0]] = frame[1]
+
+        for idx, _ in enumerate(frame_container):
+
+            # Frames are stored in a mixed order, therefore we get them using incrementing frame index:
+            feature_vectors.append(frame_dictionary[str(idx)])
+
+        features_array = np.vstack(feature_vectors)
+
+        return features_array
+
+
+    #==========================================================================
+    def convert_list_of_frame_cont_to_array(self, frame_containers):
+        """
+        This function converts a list of Frame containers into an array of features.
+        Features from different frame containers (individuals) are concatenated into the
+        same list. This list is then converted to an array. The rows are samples,
+        the columns are features.
+
+        **Parameters:**
+
+        ``frame_containers`` : [FrameContainer]
+            A list of Frame Containers, , see ``bob.bio.video.utils.FrameContainer``.
+            Each frame Container contains feature vectors for the particular individual/person.
+
+        **Returns:**
+
+        ``features_array`` : 2D :py:class:`numpy.ndarray`
+            An array containing features for all frames of all individuals.
+        """
+
+        feature_vectors = []
+
+        for frame_container in frame_containers:
+
+            video_features_array = self.convert_frame_cont_to_array(frame_container)
+
+            feature_vectors.append( video_features_array )
+
+        features_array = np.vstack(feature_vectors)
+
+        return features_array
+
+
+    #==========================================================================
+    def mean_std_normalize(self, features, features_mean= None, features_std = None):
+        """
+        The features in the input 2D array are mean-std normalized.
+        The rows are samples, the columns are features. If ``features_mean``
+        and ``features_std`` are provided, then these vectors will be used for
+        normalization. Otherwise, the mean and std of the features is
+        computed on the fly.
+
+        **Parameters:**
+
+        ``features`` : 2D :py:class:`numpy.ndarray`
+            Array of features to be normalized.
+
+        ``features_mean`` : 1D :py:class:`numpy.ndarray`
+            Mean of the features. Default: None.
+
+        ``features_std`` : 2D :py:class:`numpy.ndarray`
+            Standart deviation of the features. Default: None.
+
+        **Returns:**
+
+        ``features_norm`` : 2D :py:class:`numpy.ndarray`
+            Normalized array of features.
+
+        ``features_mean`` : 1D :py:class:`numpy.ndarray`
+            Mean of the features.
+
+        ``features_std`` : 1D :py:class:`numpy.ndarray`
+            Standart deviation of the features.
+        """
+
+        features = np.copy(features)
+
+        # Compute mean and std if not given:
+        if features_mean is None:
+
+            features_mean = np.mean(features, axis=0)
+
+            features_std = np.std(features, axis=0)
+
+        row_norm_list = []
+
+        for row in features: # row is a sample
+
+            row_norm = (row - features_mean) / features_std
+
+            row_norm_list.append(row_norm)
+
+        features_norm = np.vstack(row_norm_list)
+
+        return features_norm, features_mean, features_std
+
+
+    #==========================================================================
+    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.
+
+        **Parameters:**
+
+        ``real`` : 2D :py:class:`numpy.ndarray`
+            Training features for the real class.
+
+        ``attack`` : 2D :py:class:`numpy.ndarray`
+            Training features for the attack class.
+
+        **Returns:**
+
+        ``real_norm`` : 2D :py:class:`numpy.ndarray`
+            Mean-std normalized training features for the real class.
+
+        ``attack_norm`` : 2D :py:class:`numpy.ndarray`
+            Mean-std normalized training features for the attack class.
+            Or an empty list if ``one_class_flag = True``.
+
+        ``features_mean`` : 1D :py:class:`numpy.ndarray`
+            Mean of the features.
+
+        ``features_std`` : 1D :py:class:`numpy.ndarray`
+            Standart deviation of the features.
+        """
+
+        real_norm, features_mean, features_std = self.mean_std_normalize(real)
+
+        attack_norm, _, _ = self.mean_std_normalize(attack, features_mean, features_std)
+
+        return real_norm, attack_norm, features_mean, features_std
+
+
+    #==========================================================================
+    def train_lr(self, real, attack, C):
+        """
+        Train LR classifier given real and attack classes. Prior to training
+        the data is mean-std normalized.
+
+        **Parameters:**
+
+        ``real`` : 2D :py:class:`numpy.ndarray`
+            Training features for the real class.
+
+        ``attack`` : 2D :py:class:`numpy.ndarray`
+            Training features for the attack class.
+
+        ``C`` : :py:class:`float`
+            Inverse of regularization strength in LR classifier; must be a positive.
+            Like in support vector machines, smaller values specify stronger
+            regularization. Default: 1.0 .
+
+        **Returns:**
+
+        ``machine`` : object
+            A trained LR machine. The mean-std normalizers are also set in the
+            machine.
+
+        ``features_mean`` : 1D :py:class:`numpy.ndarray`
+            Mean of the features.
+
+        ``features_std`` : 1D :py:class:`numpy.ndarray`
+            Standart deviation of the features.
+        """
+
+        real, attack, features_mean, features_std = self.norm_train_data(real, attack)
+        # real and attack - are now mean-std normalized
+
+        X = np.vstack([real, attack])
+
+        Y = np.hstack( [ np.zeros(len(real) ), np.ones(len(attack) ) ] )
+
+        machine = linear_model.LogisticRegression( C = C )
+
+        machine.fit(X, Y)
+
+        return machine, features_mean, features_std
+
+
+    #==========================================================================
+    def save_lr_machine_and_mean_std(self, projector_file, machine, features_mean, features_std):
+        """
+        Saves the LR machine, features mean and std to the hdf5 file.
+        The absolute name of the file is specified in ``projector_file`` string.
+
+        **Parameters:**
+
+        ``projector_file`` : :py:class:`str`
+            Absolute name of the file to save the data to, as returned by
+            ``bob.pad.base`` framework.
+
+        ``machine`` : object
+            The LR machine to be saved. As returned by sklearn.linear_model
+            module.
+
+        ``features_mean`` : 1D :py:class:`numpy.ndarray`
+            Mean of the features.
+
+        ``features_std`` : 1D :py:class:`numpy.ndarray`
+            Standart deviation of the features.
+        """
+
+        f = bob.io.base.HDF5File(projector_file, 'w') # open hdf5 file to save to
+
+        for key in self.lr_param_keys: # ["C", "classes_", "coef_", "intercept_"]
+
+            data = getattr( machine, key )
+
+            f.set( key, data )
+
+        f.set( "features_mean", features_mean )
+
+        f.set( "features_std", features_std )
+
+        del f
+
+
+    #==========================================================================
+    def train_projector(self, training_features, projector_file):
+        """
+        Train LR for feature projection and save them to files.
+        The ``requires_projector_training = True`` flag must be set to True
+        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.
+
+        ``projector_file`` : :py:class:`str`
+            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.
+        real = self.convert_list_of_frame_cont_to_array(training_features[0]) # output is array
+        # training_features[1] - training features for the ATTACK class.
+        attack = self.convert_list_of_frame_cont_to_array(training_features[1]) # output is array
+
+        # Train the LR machine and get normalizers:
+        machine, features_mean, features_std = self.train_lr(real = real,
+                                                             attack = attack,
+                                                             C = self.C)
+
+        # Save the LR machine and normalizers:
+        self.save_lr_machine_and_mean_std(projector_file, machine, features_mean, features_std)
+
+
+    #==========================================================================
+    def load_lr_machine_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`` : :py:class:`str`
+            Absolute name of the file to load the trained projector from, as
+            returned by ``bob.pad.base`` framework.
+
+        **Returns:**
+
+        ``machine`` : object
+            The loaded LR machine. As returned by sklearn.linear_model module.
+
+        ``features_mean`` : 1D :py:class:`numpy.ndarray`
+            Mean of the features.
+
+        ``features_std`` : 1D :py:class:`numpy.ndarray`
+            Standart deviation of the features.
+        """
+
+        f = bob.io.base.HDF5File(projector_file, 'r') # file to read the machine from
+
+        # initialize the machine:
+        machine = linear_model.LogisticRegression()
+
+        # set the params of the machine:
+        for key in self.lr_param_keys: # ["C", "classes_", "coef_", "intercept_"]
+
+            data = f.read(key)
+
+            setattr(machine, key, data)
+
+        features_mean = f.read("features_mean")
+
+        features_std = f.read("features_std")
+
+        del f
+
+        return machine, features_mean, features_std
+
+
+    #==========================================================================
+    def load_projector(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.
+
+        This function sets the arguments ``self.lr_machine``, ``self.features_mean``
+        and ``self.features_std`` of this class with loaded machines.
+
+        The function must be capable of reading the data saved with the
+        :py:meth:`train_projector` method of this class.
+
+        Please register `performs_projection = True` in the constructor to
+        enable this function.
+
+        **Parameters:**
+
+        ``projector_file`` : :py:class:`str`
+            The file to read the projector from, as returned by the
+            ``bob.pad.base`` framework. In this class the names of the files to
+            read the projectors from are modified, see ``load_machine`` and
+            ``load_cascade_of_machines`` methods of this class for more details.
+        """
+
+        lr_machine, features_mean, features_std = self.load_lr_machine_and_mean_std(projector_file)
+
+        self.lr_machine = lr_machine
+
+        self.features_mean = features_mean
+
+        self.features_std = features_std
+
+
+    #==========================================================================
+    def project(self, feature):
+        """
+        This function computes a vector of scores for each sample in the input
+        array of features. The following steps are apllied:
+
+        1. First, the input data is mean-std normalized using mean and std of the
+           real class only.
+
+        2. The input features are next classified using pre-trained LR machine.
+
+        Set ``performs_projection = True`` in the constructor to enable this function.
+        It is assured that the :py:meth:`load_projector` was **called before** the
+        ``project`` function is executed.
+
+        **Parameters:**
+
+        ``feature`` : FrameContainer or 2D :py:class:`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).
+
+        **Returns:**
+
+        ``scores`` : 1D :py:class:`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.
+        """
+
+        # 1. Convert input array to numpy array if necessary.
+        if isinstance(feature, FrameContainer): # if FrameContainer convert to 2D numpy array
+
+            features_array = self.convert_frame_cont_to_array(feature)
+
+        else:
+
+            features_array = feature
+
+        features_array_norm, _, _ = self.mean_std_normalize(features_array, self.features_mean, self.features_std)
+
+        scores = self.lr_machine.predict_proba( features_array_norm )[:,0]
+
+        return scores
+
+
+    #==========================================================================
+    def score(self, toscore):
+        """
+        Returns a probability of a sample being a real class.
+
+        **Parameters:**
+
+        ``toscore`` : 1D :py:class:`numpy.ndarray`
+            Vector with scores for each frame/sample defining the probability
+            of the frame being a sample of the real class.
+
+        **Returns:**
+
+        ``score`` : [:py:class:`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 self.frame_level_scores_flag:
+
+            score = list(toscore)
+
+        else:
+
+            score = [np.mean( toscore )] # compute a single score per video
+
+        return score
+
+
+
+
diff --git a/bob/pad/face/algorithm/__init__.py b/bob/pad/face/algorithm/__init__.py
index c763a329a4bf9771995439461666917d3bcc0de6..3ef1ea1c5da23998f47a172c21121658933c4e3e 100644
--- a/bob/pad/face/algorithm/__init__.py
+++ b/bob/pad/face/algorithm/__init__.py
@@ -1,5 +1,6 @@
 from .VideoSvmPadAlgorithm import VideoSvmPadAlgorithm
 from .VideoCascadeSvmPadAlgorithm import VideoCascadeSvmPadAlgorithm
+from .VideoLRPadAlgorithm import VideoLRPadAlgorithm
 
 def __appropriate__(*args):
     """Says object was actually declared here, and not in the import module.
@@ -22,5 +23,6 @@ def __appropriate__(*args):
 __appropriate__(
     VideoSvmPadAlgorithm,
     VideoCascadeSvmPadAlgorithm,
+    VideoLRPadAlgorithm,
 )
 __all__ = [_ for _ in dir() if not _.startswith('_')]
diff --git a/bob/pad/face/config/algorithm/video_cascade_svm_pad_algorithm.py b/bob/pad/face/config/algorithm/video_cascade_svm_pad_algorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..edd34b0123b256c720ba66d6fcd3ebc208f56c7d
--- /dev/null
+++ b/bob/pad/face/config/algorithm/video_cascade_svm_pad_algorithm.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python
+
+from bob.pad.face.algorithm import VideoCascadeSvmPadAlgorithm
+
+
+#=======================================================================================
+# Define instances here:
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.2}
+N = 2
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n2_gamma_02 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.1}
+N = 2
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n2_gamma_01 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.05}
+N = 2
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n2_gamma_005 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.01}
+N = 2
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n2_gamma_001 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+
+#=======================================================================================
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.1}
+N = 10
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n10_gamma_01 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.05}
+N = 10
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n10_gamma_005 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.01}
+N = 10
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n10_gamma_001 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.005}
+N = 10
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n10_gamma_0005 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+
+#=======================================================================================
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.5}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_05 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.2}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_02 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.1}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_01 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.05}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_005 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.01}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_001 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.005}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_0005 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.001}
+N = 20
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = True
+
+algorithm_n20_gamma_0001 = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+
+#=======================================================================================
+
+MACHINE_TYPE = 'ONE_CLASS'
+KERNEL_TYPE = 'RBF'
+SVM_KWARGS = {'nu': 0.001, 'gamma': 0.1}
+N = 2
+POS_SCORES_SLOPE = 0.01
+FRAME_LEVEL_SCORES_FLAG = False
+
+algorithm_n2_gamma_01_video_level = VideoCascadeSvmPadAlgorithm(machine_type = MACHINE_TYPE,
+                                        kernel_type = KERNEL_TYPE,
+                                        svm_kwargs = SVM_KWARGS,
+                                        N = N,
+                                        pos_scores_slope = POS_SCORES_SLOPE,
+                                        frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+
diff --git a/bob/pad/face/config/qm_lr_aggregated_db.py b/bob/pad/face/config/qm_lr_aggregated_db.py
new file mode 100644
index 0000000000000000000000000000000000000000..986afb3d4fefc16a81d2dc215514300fd96b63ff
--- /dev/null
+++ b/bob/pad/face/config/qm_lr_aggregated_db.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
+"""
+This file contains configurations to run Image Quality Measures (IQM) and SVM based face PAD baseline.
+The settings of the preprocessor and extractor are tuned for the Replay-attack database.
+In the SVM algorithm the amount of training data is reduced speeding-up the training for
+large data sets, such as Aggregated PAD database.
+The IQM features used in this algorithm/resource are introduced in the following papers: [WHJ15]_ and [CBVM16]_.
+"""
+
+
+#=======================================================================================
+sub_directory = 'qm_svm_aggregated_db'
+"""
+Sub-directory where results will be placed.
+
+You may change this setting using the ``--sub-directory`` command-line option
+or the attribute ``sub_directory`` in a configuration file loaded **after**
+this resource.
+"""
+
+
+#=======================================================================================
+# define preprocessor:
+
+from ..preprocessor import VideoFaceCrop
+
+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
+CHECK_FACE_SIZE_FLAG = True   # Check the size of the face
+MIN_FACE_SIZE = 50
+USE_LOCAL_CROPPER_FLAG = True # Use the local face cropping class (identical to Ivana's paper)
+RGB_OUTPUT_FLAG = True        # Return RGB cropped face using local cropper
+
+preprocessor = VideoFaceCrop(cropped_image_size = CROPPED_IMAGE_SIZE,
+                             cropped_positions = CROPPED_POSITIONS,
+                             fixed_positions = FIXED_POSITIONS,
+                             mask_sigma = MASK_SIGMA,
+                             mask_neighbors = MASK_NEIGHBORS,
+                             mask_seed = None,
+                             check_face_size_flag = CHECK_FACE_SIZE_FLAG,
+                             min_face_size = MIN_FACE_SIZE,
+                             use_local_cropper_flag = USE_LOCAL_CROPPER_FLAG,
+                             rgb_output_flag = RGB_OUTPUT_FLAG)
+"""
+In the preprocessing stage the face is cropped in each frame of the input video given facial annotations.
+The size of the face is normalized to ``cropped_image_size`` dimensions. The faces of the size
+below ``min_face_size`` threshold are discarded. The preprocessor is similar to the one introduced in
+[CAM12]_, which is defined by ``use_local_cropper_flag = True``. The preprocessed frame is the RGB
+facial image, which is defined by ``RGB_OUTPUT_FLAG = True``.
+"""
+
+
+#=======================================================================================
+# define extractor:
+
+from ..extractor import VideoQualityMeasure
+
+GALBALLY=True
+MSU=True
+DTYPE=None
+
+extractor = VideoQualityMeasure(galbally=GALBALLY,
+                                msu=MSU,
+                                dtype=DTYPE)
+"""
+In the feature extraction stage the Image Quality Measures are extracted from each frame of the preprocessed RGB video.
+The features to be computed are introduced in the following papers: [WHJ15]_ and [CBVM16]_.
+"""
+
+
+#=======================================================================================
+# define algorithm:
+
+from ..algorithm import VideoLRPadAlgorithm
+
+C = 1. # The regularization parameter for the LR classifier
+FRAME_LEVEL_SCORES_FLAG = True # Return one score per frame
+
+algorithm = VideoLRPadAlgorithm(C = C,
+                                frame_level_scores_flag = FRAME_LEVEL_SCORES_FLAG)
+
+"""
+The Logistic Regression is used to classify the data into *real* and *attack* classes.
+One score is produced for each frame of the input video, ``frame_level_scores_flag = True``.
+"""
+
+
diff --git a/requirements.txt b/requirements.txt
index 795e4100ff0332650da93fc9470405eefac9649e..c02452136f9beef322f603a69149aedc88dfa911 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,4 +12,7 @@ bob.bio.video
 bob.io.image
 bob.ip.color
 bob.ip.qualitymeasure
-bob.learn.libsvm
\ No newline at end of file
+bob.learn.libsvm
+bob.learn.linear
+sklearn
+
diff --git a/setup.py b/setup.py
index 01fbf4963d02758a9a0d5460150c1d6dbdd1abe5..9d1c453f075068e2173678eaad4dc717eca4273f 100644
--- a/setup.py
+++ b/setup.py
@@ -77,7 +77,7 @@ setup(
             'msu-mfsd = bob.pad.face.config.msu_mfsd',
             'aggregated-db = bob.pad.face.config.aggregated_db',
 
-            # baselines:
+            # baselines using SVM:
             'lbp-svm = bob.pad.face.config.lbp_svm',
             'lbp-svm-aggregated-db = bob.pad.face.config.lbp_svm_aggregated_db',
 
@@ -91,6 +91,9 @@ setup(
             'frame-diff-svm-aggregated-db = bob.pad.face.config.frame_diff_svm_aggregated_db',
 
             'frame-diff-one-class-svm = bob.pad.face.config.frame_diff_one_class_svm',
+
+            # baselines using LR:
+            'qm-lr-aggregated-db = bob.pad.face.config.qm_lr_aggregated_db',
             ],
 
         # registered preprocessors:
@@ -110,6 +113,28 @@ setup(
             'video-svm-pad-algorithm-10k-grid-mean-std = bob.pad.face.config.algorithm.video_svm_pad_algorithm:video_svm_pad_algorithm_10k_grid_mean_std',
             'video-svm-pad-algorithm-10k-grid-mean-std-frame-level = bob.pad.face.config.algorithm.video_svm_pad_algorithm:video_svm_pad_algorithm_10k_grid_mean_std_frame_level',
             'video-svm-pad-algorithm-default-svm-param-mean-std-frame-level = bob.pad.face.config.algorithm.video_svm_pad_algorithm:video_svm_pad_algorithm_default_svm_param_mean_std_frame_level',
+
+            # for grid search experiments with cascade of SVMs N = 2
+            'algorithm-n2-gamma-02 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n2_gamma_02',
+            'algorithm-n2-gamma-01 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n2_gamma_01',
+            'algorithm-n2-gamma-005 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n2_gamma_005',
+            'algorithm-n2-gamma-001 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n2_gamma_001',
+            'algorithm-n2-gamma-01-video-level = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n2_gamma_01_video_level',
+
+            # for grid search experiments with cascade of SVMs N = 10
+            'algorithm-n10-gamma-01 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n10_gamma_01',
+            'algorithm-n10-gamma-005 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n10_gamma_005',
+            'algorithm-n10-gamma-001 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n10_gamma_001',
+            'algorithm-n10-gamma-0005 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n10_gamma_0005',
+
+            # for grid search experiments with cascade of SVMs N = 20
+            'algorithm-n20-gamma-05 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_05',
+            'algorithm-n20-gamma-02 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_02',
+            'algorithm-n20-gamma-01 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_01',
+            'algorithm-n20-gamma-005 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_005',
+            'algorithm-n20-gamma-001 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_001',
+            'algorithm-n20-gamma-0005 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_0005',
+            'algorithm-n20-gamma-0001 = bob.pad.face.config.algorithm.video_cascade_svm_pad_algorithm:algorithm_n20_gamma_0001',
             ],
 
         # registered grid configurations: