Commit 144b1e10 authored by Amir MOHAMMADI's avatar Amir MOHAMMADI

Improve the intro docs

parent 1f3afa3f
Pipeline #50874 passed with stage
in 9 minutes and 37 seconds
......@@ -3,8 +3,7 @@
from abc import ABCMeta, abstractmethod
from bob.pipelines.sample import SAMPLE_DATA_ATTRS, Sample, SampleSet, DelayedSample
import functools
from bob.pipelines.sample import Sample, SampleSet
import numpy as np
import os
......@@ -242,22 +241,24 @@ class BioAlgorithm(metaclass=ABCMeta):
pass
def score_multiple_biometric_references(self, biometric_references, data):
"""
It handles the score computation of one probe against multiple biometric references
This method is called if `allow_scoring_multiple_references` is set to true
"""Score one probe against multiple biometric references (models).
This method is called if `allow_scoring_multiple_references` is set to true.
You may want to override this method to improve the performance of computations.
Parameters
----------
biometric_references : list
List of biometric references (models) to be scored
[description]
data
Data used for the creation of ONE biometric probe.
biometric_references: list
List of biometric references to be scored
data:
Data used for the creation of ONE BIOMETRIC REFERENCE
Returns
-------
list
A list of scores for the comparison of the probe against multiple models.
"""
raise NotImplementedError(
"Your BioAlgorithm implementation should implement score_multiple_biometric_references."
)
return [self.score(model, data) for model in biometric_references]
class Database(metaclass=ABCMeta):
......
......@@ -10,7 +10,7 @@ def resources(command_line_parameters = None):
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--types", '-t', nargs = '+',
choices = ('d', 'database', 'an', 'annotator', 'p', 'pipeline', 'c', 'config'),
default = ('d', 'an', 'b', 'c'),
default = ('d', 'an', 'p', 'c'),
help = "Select the resource types that should be listed.")
parser.add_argument("--details", '-d', action='store_true', help = "Prints the complete configuration for all resources")
......@@ -28,19 +28,19 @@ def resources(command_line_parameters = None):
if 'd' in args.types or 'database' in args.types:
print ("\nList of registered databases:")
print ("\nList of registered databases (can be used after the --database option):")
print (bob.bio.base.list_resources('database', **kwargs))
if 'an' in args.types or 'annotator' in args.types:
print ("\nList of registered annotators:")
print ("\nList of registered annotators (can be used after the --annotator option):")
print (bob.bio.base.list_resources('annotator', **kwargs))
if 'p' in args.types or 'pipeline' in args.types:
print ("\nList of registered pipelines:")
print ("\nList of registered pipelines (can be used after the --pipeline option):")
print (bob.bio.base.list_resources('pipeline', **kwargs))
if 'c' in args.types or 'config' in args.types:
print ("\nList of registered configs:")
print ("\nList of registered configs. Configs may contain multiple resources and they also allow chain loading (see bob.extension docs on chain loading). Configs are used as arguments to commands such as vanilla-biometrics):")
print (bob.bio.base.list_resources('config', **kwargs))
print()
......
import numpy
import numpy as np
from bob.bio.base.pipelines.vanilla_biometrics import BioAlgorithm
from bob.bio.base.pipelines.vanilla_biometrics import VanillaBiometricsPipeline
from bob.pipelines import wrap
from sklearn.decomposition import PCA
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import FunctionTransformer
from sklearn.utils import check_array
## Implementation of a Transformer
## Transformers
pca = PCA(n_components=0.95)
from sklearn.base import TransformerMixin, BaseEstimator
# the images are in shape of Nx112x92, we want to flatten to Nx10304 them so we can train a PCA on them.
def flatten(images):
images = check_array(images, allow_nd=True)
new_shape = [images.shape[0], -1]
return np.reshape(images, new_shape)
class CustomTransformer(TransformerMixin, BaseEstimator):
def transform(self, X):
transformed_X = X
return transformed_X
flatten_transformer = FunctionTransformer(flatten, validate=False)
def fit(self, X, y=None):
return self
# Chain the Transformers together
transformer = make_pipeline(flatten_transformer, pca)
# All transformers must be sample transformers
transformer = wrap(["sample"], transformer)
## Implementation of the BioAlgorithm
from bob.bio.base.pipelines.vanilla_biometrics.abstract_classes import BioAlgorithm
class CustomDistance(BioAlgorithm):
# A better implementation is available in:
# from bob.bio.base.pipelines.vanilla_biometrics import Distance
class EuclideanDistance(BioAlgorithm):
def enroll(self, enroll_features):
model = numpy.mean(enroll_features, axis=0)
model = np.mean(enroll_features, axis=0)
return model
def score(self, model, probe):
distance = 1/numpy.linalg.norm(model-probe)
return distance
similarity = 1/np.linalg.norm(model-probe)
# you should always return a similarity score
return similarity
bio_algorithm = EuclideanDistance()
## Creation of the pipeline
from sklearn.pipeline import make_pipeline
from bob.pipelines import wrap
from bob.bio.base.pipelines.vanilla_biometrics import VanillaBiometricsPipeline
# Instantiate the Transformers
my_transformer = CustomTransformer()
# Chain the Transformers together
transformer = make_pipeline(
wrap(["sample"], my_transformer),
# Add more transformers here if needed
)
# Instantiate the BioAlgorithm
bio_algorithm = CustomDistance()
# Assemble the Vanilla Biometric pipeline and execute
## Creation of the pipeline
# `pipeline` will be used by the `bob bio pipelines vanilla-biometrics` command
pipeline = VanillaBiometricsPipeline(transformer, bio_algorithm)
# Prevent the need to implement a `score_multiple_biometric_references` method
database.allow_scoring_with_all_biometric_references = False
# `pipeline` will be used by the `bob bio pipelines` command
# you can also specify the other options in this file:
database = "atnt"
output = "results"
......@@ -12,7 +12,7 @@ The transition to the pipeline concept changed the way data goes from the raw sa
However, a set of tools was implemented to support the older bob implementations (designated as *legacy*) of database, preprocessor, extractor, and algorithms.
This adaptation consists of wrapper classes that take a legacy bob class as input and constructs a :py:class:`Transformer` or :py:class:`BiometricAlgorithm` out of it.
This adaptation consists of wrapper classes that take a legacy bob class as input and constructs a Transformer or :py:class:`BiometricAlgorithm` out of it.
.. WARNING::
......@@ -183,11 +183,11 @@ This example shows the creation of the Mobio database interface in the bob.pipel
Legacy Preprocessor wrapper
---------------------------
The :py:class:`~bob.bio.base.transformer.PreprocessorTransformer` wrapper takes a :py:class`bob.bio.base.preprocessor` from the old :py:mod:`bob.bio.base` as input and creates a :py:class:`Transformer` out of it.
The :py:class:`~bob.bio.base.transformer.PreprocessorTransformer` wrapper takes a :py:class`bob.bio.base.preprocessor` from the old :py:mod:`bob.bio.base` as input and creates a Transformer out of it.
The :py:meth:`~bob.bio.base.preprocessor.__call__` method of the :py:class`~bob.bio.base.preprocessor` class is called when the :py:meth:`Transformer.transform` method is called.
This example shows how to create a :py:class:`Transformer` out of a legacy preprocessor (FaceCrop, from bob.bio.face):
This example shows how to create a Transformer out of a legacy preprocessor (FaceCrop, from bob.bio.face):
.. code-block:: python
......@@ -211,7 +211,7 @@ Legacy Extractor wrapper
A similar wrapper is available for the legacy :py:mod:`bob.bio.base` Extractor. It is the :py:class:`~bob.bio.base.transformer.ExtractorTransformer`.
It maps the :py:meth:`Transformer.transform` method to the :py:meth:`~bob.bio.base.extractor.__call__` of the legacy Extractor.
Here is an example showing how to create a :py:class:`Transformer` from a legacy Extractor (Linearize, from bob.bio.base):
Here is an example showing how to create a Transformer from a legacy Extractor (Linearize, from bob.bio.base):
.. code-block:: python
......@@ -225,12 +225,12 @@ Here is an example showing how to create a :py:class:`Transformer` from a legacy
Legacy Algorithm wrappers
-------------------------
Lastly, :py:class:`~bob.bio.base.transformer.AlgorithmTransformer` and :py:class:`~bob.bio.base.pipelines.vanilla_biometrics.legacy.BioAlgorithmLegacy` are available to map correctly a legacy Algorithm to a :py:class:`Transformer` and a :py:class:`BioAlgorithm`.
Lastly, :py:class:`~bob.bio.base.transformer.AlgorithmTransformer` and :py:class:`~bob.bio.base.pipelines.vanilla_biometrics.legacy.BioAlgorithmLegacy` are available to map correctly a legacy Algorithm to a Transformer and a :py:class:`BioAlgorithm`.
Those two adaptors are needed as the legacy Algorithm could consist of a projector that could be trainable (with methods :py:meth:`~bob.bio.base.algorithm.Algorithm.project` and :py:meth:`~bob.bio.base.algorithm.Algorithm.train_projector`), which correspond to a :py:class:`Transformer` in the new API.
Those two adaptors are needed as the legacy Algorithm could consist of a projector that could be trainable (with methods :py:meth:`~bob.bio.base.algorithm.Algorithm.project` and :py:meth:`~bob.bio.base.algorithm.Algorithm.train_projector`), which correspond to a Transformer in the new API.
The enrollment and scoring of the legacy algorithm were done using the :py:meth:`~bob.bio.base.algorithm.Algorithm.enroll` and :py:meth:`~bob.bio.base.algorithm.Algorithm.score` methods, which can be mapped to the same methods in a :py:class:`BioAlgorithm`.
Here is an example showing how to create the :py:class:`Transformer` out of a bob.bio.base Algorithm (:py:class:`~bob.bio.base.Distance`):
Here is an example showing how to create the Transformer out of a bob.bio.base Algorithm (:py:class:`~bob.bio.base.Distance`):
.. code-block:: python
......
......@@ -48,7 +48,7 @@ Assembling the pipeline
.. autosummary::
bob.bio.base.script.vanilla_biometrics.vanilla_biometrics
bob.bio.base.pipelines.vanilla_biometrics.VanillaBiometricsPipeline
Building Pipelines from Legacy constructs
......
......@@ -138,7 +138,7 @@ The following file structure and file naming must be followed, for the class to
| +-- train_world.csv
|
+-- dev
| |
| |
| +-- for_models.csv
| +-- for_probes.csv
|
......@@ -216,8 +216,8 @@ To use the cross-validation database interface, use the following:
test_size=0.8,
samples_for_enrollment=1,
csv_to_sample_loader=CSVToSampleLoader(
data_loader=bob.io.base.load,
dataset_original_directory="",
data_loader=bob.io.base.load,
dataset_original_directory="",
extension="",
metadata_loader=AnnotationsLoader()
),
......@@ -309,18 +309,18 @@ Checkpointing experiments
Checkpoints are a useful tool that allows an experiment to prevent computing data multiple times by saving the results of each step so it can be retrieved later.
It can be used when an experiment fails in a later stage, preventing the computation of the stages coming before it, in case the experiment is restarted.
The checkpoints are files created on disk that contain the result of a sample of data passed through a :py:class:`Transformer` or :py:class:`BiometricAlgorithm`.
The checkpoints are files created on disk that contain the result of a sample of data passed through a Transformer or :py:class:`BiometricAlgorithm`.
When running, if the system finds a checkpoint file for its current processing step, it will load the results directly from the disk, instead of computing it again.
To enable the checkpointing of a :py:class:`Transformer` or :py:class:`BiometricAlgorithm`, a :py:class:`~bob.pipelines.CheckpointWrapper` is available.
This class takes a :py:class:`Transformer` as input and returns the same :py:class:`Transformer` with the ability to automatically create checkpoint files.
To enable the checkpointing of a Transformer or :py:class:`BiometricAlgorithm`, a :py:class:`~bob.pipelines.CheckpointWrapper` is available.
This class takes a Transformer as input and returns the same Transformer with the ability to automatically create checkpoint files.
The :py:class:`~bob.pipelines.CheckpointWrapper` class is available in the :py:mod:`bob.pipelines`.
The ``-c`` option (``--checkpoint``) is a command-line option that automatically wraps every steps of the pipeline with checkpointing::
$ bob bio pipelines vanilla-biometrics -d <database> -p <pipeline> -c -o <output_dir>
When doing so, the output of each :py:class:`Transformer` of the pipeline will be saved to the disk in the ``<output_dir>`` folder specified with the ``-o`` (``--output``) option.
When doing so, the output of each Transformer of the pipeline will be saved to the disk in the ``<output_dir>`` folder specified with the ``-o`` (``--output``) option.
.. WARNING::
......@@ -344,7 +344,7 @@ Diagnostic and monitoring tools are also available to watch progress and debug.
Using Dask with vanilla-biometrics
----------------------------------
To run an experiment with Dask, a :py:class:`bob.pipelines.DaskWrapper` class is available that takes any :py:class:`Transformer` or :py:class:`BiometricAlgorithm` and outputs a *dasked* version of it.
To run an experiment with Dask, a :py:class:`bob.pipelines.DaskWrapper` class is available that takes any Transformer or :py:class:`BiometricAlgorithm` and outputs a *dasked* version of it.
You can easily benefit from Dask by using the ``-l`` (``--dask-client``) option like so::
......
This diff is collapsed.
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