Commit c66d0297 authored by Olegs Nikisins's avatar Olegs Nikisins
Browse files

Refactored MLPAlgorithm, no need for config in init, udated doc-strings, and unit test

parent fde5eaf5
Pipeline #26901 passed with stage
in 7 minutes and 21 seconds
......@@ -23,6 +23,8 @@ from bob.pad.base.utils import convert_list_of_frame_cont_to_array
import bob.io.base
import torch
# =============================================================================
# Main body :
......@@ -34,36 +36,15 @@ class MLPAlgorithm(Algorithm):
Attributes
-----------
config_file: str
Relative name of the config file.
The path should be relative to ``config_group``,
for example: "test_data/mlp_algo_test_config.py".
This file **must** contain at least the following definitions:
Function namely ``transform``, which takes numpy.ndarray as input,
and returns a transformed Tensor. The dimensionality of the output
tensor must match the format expected by the MLP.
A ``Network`` class, defining your network architecture. Note, if your
class is named differently, import it as ``Network``, for example:
``from bob.learn.pytorch.architectures import MyNetwork as Network``
Optional: ``network_kwargs`` to be used for ``Network`` initialization.
For example, if you don't want to use a sigmoid in the output of the
MLP, set the kwargs accodingly. Note: in current algorithm the
``forward()`` method of the ``Network`` is used for feature extraction.
config_group: str
Group/package name containing the configuration file. Usually all
configs should be stored in this folder/place.
For example: "bob.ip.pytorch_extractor".
Both ``config_file`` and ``config_group`` are used to access the
configuration module.
network : object
An instance of an MLP Network to be used for score computation.
Note: in current algorith the ``forward()`` method of the Network
is used for score computation. For example, if you don't want to use
a sigmoid in the output of an MLP, set the kwargs accodingly.
model_file : str
A paths to the model file to be used for network initialization.
The network structure is defined in the config file.
A paths to the model file to be used for ``network`` initialization.
url : str
URL to download the pretrained models from.
......@@ -91,16 +72,14 @@ class MLPAlgorithm(Algorithm):
"""
def __init__(self,
config_file,
config_group,
network,
model_file = None,
url = None,
archive_extension = '.tar.gz',
frame_level_scores_flag = True,
mean_std_norm_flag = True):
super(MLPAlgorithm, self).__init__(config_file = config_file,
config_group = config_group,
super(MLPAlgorithm, self).__init__(network = network,
model_file = model_file,
url = url,
archive_extension = archive_extension,
......@@ -109,8 +88,8 @@ class MLPAlgorithm(Algorithm):
performs_projection=True,
requires_projector_training=True)
self.config_file = config_file
self.config_group = config_group
self.transform = lambda x : torch.Tensor(x).unsqueeze(0)
self.network = network
self.model_file = model_file
self.url = url
self.archive_extension = archive_extension
......@@ -221,7 +200,7 @@ class MLPAlgorithm(Algorithm):
----------
feature : FrameContainer or :py:class:`numpy.ndarray`
Two types of inputs are accepted.
A Frame Container conteining the features of an individual frmaes,
A Frame Container containing the features of an individual frmaes,
see ``bob.bio.video.utils.FrameContainer``.
Or a ND feature array of the size (n_samples x n_features).
......@@ -250,15 +229,11 @@ class MLPAlgorithm(Algorithm):
self.features_mean,
self.features_std)
# kwargs for the transform_and_net_forward function:
function_kwargs = {}
function_kwargs["config_file"] = self.config_file
function_kwargs["config_group"] = self.config_group
function_kwargs["model_file"] = self.model_file
function_kwargs["color_input_flag"] = False
scores = transform_and_net_forward(feature = feature,
**function_kwargs)
transform = self.transform,
network = self.network,
model_file = self.model_file,
color_input_flag = False)
return scores
......
......@@ -101,35 +101,40 @@ def test_multi_net_patch_extractor():
# plt.show()
#def test_mlp_algorithm():
# """
# Test the MLPAlgorithm PAD algorithm class.
# """
#
# from bob.ip.pytorch_extractor import MLPAlgorithm
#
# # =========================================================================
# # prepare the test data / feature vector:
#
# features = numpy.random.randn(2, 1296)
#
# # =========================================================================
# # test the extractor:
#
# CONFIG_FILE = "test_data/mlp_algo_test_config.py" # config containing an instance of Composed Transform and a Network class to be used in feature extractor
# CONFIG_GROUP = "bob.ip.pytorch_extractor"
# MODEL_FILE = None
#
# algorithm = MLPAlgorithm(config_file = CONFIG_FILE,
# config_group = CONFIG_GROUP,
# model_file = MODEL_FILE,
# url = None,
# archive_extension = '.tar.gz',
# frame_level_scores_flag = True)
#
# # pass through encoder only, compute latent vector:
# score = algorithm.project(features)
#
# # test:
# assert score.shape == (2,)
def test_mlp_algorithm():
"""
Test the MLPAlgorithm PAD algorithm class.
"""
from bob.ip.pytorch_extractor import MLPAlgorithm
from bob.learn.pytorch.architectures import TwoLayerMLP
# =========================================================================
# prepare the test data / feature vector:
features = numpy.random.randn(2, 1296)
# =========================================================================
# test the extractor:
# don't use the sigmoid in the output:
NETWORK = TwoLayerMLP(in_features = 1296,
n_hidden_relu = 10,
apply_sigmoid = False)
MODEL_FILE = None
algorithm = MLPAlgorithm(network = NETWORK,
model_file = MODEL_FILE,
url = None,
archive_extension = '.tar.gz',
frame_level_scores_flag = True,
mean_std_norm_flag = True)
# pass through encoder only, compute latent vector:
score = algorithm.project(features)
# test:
assert score.shape == (2,)
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
@author: Olegs Nikisins
"""
#==============================================================================
# Import here:
import torch
#==============================================================================
# Define parameters here:
"""
Transformations to be applied to the input 1D numpy arrays (feature vectors).
Only conversion to Tensor and unsqueezing is needed to match the input of
TwoLayerMLP network
"""
def transform(x):
"""
Convert input to Tensor and unsqueeze to match the input of
TwoLayerMLP network.
Arguments
---------
x : numpy array
1D numpy array / feature vector.
Return
------
x_transform : Tensor
Torch tensor, transformed ``x`` to be used as MLP input.
"""
return torch.Tensor(x).unsqueeze(0)
"""
Define the network to be trained as a class, named ``Network``.
Note: Do not change the name of the below class, always import as ``Network``.
"""
from bob.learn.pytorch.architectures import TwoLayerMLP as Network
"""
kwargs to be used for ``Network`` initialization. The name must be ``network_kwargs``.
"""
network_kwargs = {}
network_kwargs['in_features'] = 1296
network_kwargs['n_hidden_relu'] = 10
network_kwargs['apply_sigmoid'] = False # don't use sigmoid to make the scores more even
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