From ccedc9a34e8d868ca406f566a8caba17323ee929 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Fri, 25 Jan 2019 15:23:44 +0100 Subject: [PATCH 01/17] Added MultiNetPatchClassifier extractor and utils, temp fix in LightCNN9 --- .../MultiNetPatchClassifier.py | 162 ++++++++++++ bob/ip/pytorch_extractor/__init__.py | 2 + bob/ip/pytorch_extractor/utils.py | 240 ++++++++++++++++++ 3 files changed, 404 insertions(+) create mode 100644 bob/ip/pytorch_extractor/MultiNetPatchClassifier.py create mode 100644 bob/ip/pytorch_extractor/utils.py diff --git a/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py b/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py new file mode 100644 index 0000000..27df0d6 --- /dev/null +++ b/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Oct 11 15:32:02 2018 + +@author: Olegs Nikisins +""" + +# ============================================================================= +# Import what is needed here: +from bob.bio.base.extractor import Extractor + +import numpy as np + +from bob.ip.pytorch_extractor.utils import reshape_flat_patches +from bob.ip.pytorch_extractor.utils import combinations +from bob.ip.pytorch_extractor.utils import net_forward + +# ============================================================================= +# Main body: +class MultiNetPatchClassifier(Extractor, object): + """ + This class is designed to pass a set of patches through a possibly multiple + networks and compute a feature vector combining outputs of all networks. + + The functional work-flow is the following: + + First, an array of **flattened** input patches is converted to a list + of patches with original dimensions (2D or 3D arrays). + + Second, each patch is passed through an individual network, for example + an auto-encoder pre-trained for each patch type (left eye, for example). + + Third, outputs of all networks are concatenated into a single feature + vector. + + Attributes + ----------- + config_file: str + Relative name of the config file defining the network, training data, + and training parameters. The path should be relative to + ``config_group``, + for example: "autoencoder/net1_batl_3_layers_partial.py". + + config_group: str + Group/package name containing the configuration file. Usually all + configs should be stored in this folder/place. + For example: "bob.learn.pytorch.config". + Both ``config_file`` and ``config_group`` are used to access the + configuration module. + + model_file : str + A path to the model file to be used for network initialization. + The network structure is defined in the config file. + + function_name : str + Name of the function to be applied to the input tensor. + Currently only "net_forward" function is supported. + + function_kwargs : dict + Key-word arguments for the function defined by ``function_name``. + Note, that you can also specify one of the values in the dictionary + as a list containing multiple elements. Then, ``function_kwargs`` will + be different, for each patch you apply function, defined by + ``function_name``, to. See the ``__call__`` for more details. + + patches_num : [int] + A list of inices specifying which patches will be selected for + processing/feature vector extraction. + + patch_reshape_parameters : [int] or None + The parameters to be used for patch reshaping. The loaded patch is + vectorized. Example: + ``patch_reshape_parameters = [4, 8, 8]``, then the patch of the + size (256,) will be reshaped to (4,8,8) dimensions. Only 2D and 3D + patches are supported. + Default: None. + """ + + # ========================================================================= + def __init__(self, config_file, + config_group, + model_file, + function_name, + function_kwargs, + patches_num, + patch_reshape_parameters = None): + """ + Init method. + """ + + super(MultiNetPatchClassifier, self).__init__(config_file = config_file, + config_group = config_group, + model_file = model_file, + function_name = function_name, + function_kwargs = function_kwargs, + patches_num = patches_num, + patch_reshape_parameters = patch_reshape_parameters) + + self.config_file = config_file + self.config_group = config_group + self.model_file = model_file + self.function_name = function_name + self.function_kwargs = function_kwargs + self.patches_num = patches_num + self.patch_reshape_parameters = patch_reshape_parameters + + + # ========================================================================= + def __call__(self, patches): + """ + Extract features combining outputs of multiple networks. + + Parameters + ----------- + patches : 2D :py:class:`numpy.ndarray` + An array containing flattened patches. The dimensions are: + ``num_patches x len_of_flat_patch`` + Optional: the last column of the array can also be a binary mask. + This case is also handled. + + Returns + -------- + features : :py:class:`numpy.ndarray` + Feature vector. + """ + + # convert all values in the dictionary to the list if not a list already: + function_kwargs = {k:[v] if not isinstance(v, list) else v for (k,v) in self.function_kwargs.items()} + + # compute all possible key-value combinations: + function_kwargs = combinations(function_kwargs) # function_kwargs is now a list with kwargs + + # select patches specified by indices: + patches_selected = [patches[idx] for idx in self.patches_num] # convert to list to make it iterable + + # convert to original dimensions: + patches_3d = reshape_flat_patches(patches_selected, self.patch_reshape_parameters) + + features_all_patches = [] + + for idx, patch in enumerate(patches_3d): + + if self.function_name == 'net_forward': + + if len(function_kwargs) == 1: # patches are passed through the same network: + + features = net_forward(feature = patch, **function_kwargs[0]) + + else: # patches are passed through different networks: + + features = net_forward(feature = patch, **function_kwargs[self.patches_num(idx)]) + +# print ("The model we use for patch {} is:".format(str(idx))) +# print (function_kwargs[self.patches_num(idx)]["model_file"]) + + features_all_patches.append(features) + + features = np.hstack(features_all_patches) + + return features + diff --git a/bob/ip/pytorch_extractor/__init__.py b/bob/ip/pytorch_extractor/__init__.py index 57500b0..aa6aa99 100755 --- a/bob/ip/pytorch_extractor/__init__.py +++ b/bob/ip/pytorch_extractor/__init__.py @@ -1,6 +1,7 @@ from .CNN8 import CNN8Extractor from .CasiaNet import CasiaNetExtractor from .LightCNN9 import LightCNN9Extractor +from .MultiNetPatchClassifier import MultiNetPatchClassifier # gets sphinx autodoc done right - don't remove it def __appropriate__(*args): @@ -21,6 +22,7 @@ __appropriate__( CNN8Extractor, CasiaNetExtractor, LightCNN9Extractor, + MultiNetPatchClassifier, ) # gets sphinx autodoc done right - don't remove it diff --git a/bob/ip/pytorch_extractor/utils.py b/bob/ip/pytorch_extractor/utils.py new file mode 100644 index 0000000..00982a8 --- /dev/null +++ b/bob/ip/pytorch_extractor/utils.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 25 14:29:55 2019 + +@author: Olegs Nikisins +""" + +# ============================================================================= +# Import what is needed here: +import os + +import importlib + +from torchvision import transforms + +import numpy as np + +import PIL + +import torch + +from torch.autograd import Variable + +import itertools as it + + +# ============================================================================= +def reshape_flat_patches(patches, patch_reshape_parameters = None): + """ + Reshape a set of flattened patches into original dimensions, 2D or 3D + + **Parameters:** + + ``patches`` : 2D :py:class:`numpy.ndarray` + An array containing flattened patches. The dimensions are: + ``num_patches x len_of_flat_patch`` + + ``patch_reshape_parameters`` : [int] or None + The parameters to be used for patch reshaping. The loaded patch is + vectorized. Example: + ``patch_reshape_parameters = [4, 8, 8]``, then the patch of the + size (256,) will be reshaped to (4,8,8) dimensions. Only 2D and 3D + patches are supported. + Default: None. + + **Returns:** + + ``patches_3d`` : [2D or 3D :py:class:`numpy.ndarray`] + A list of patches converted to the original dimensions. + """ + + patches_3d = [] + + for patch in patches: + + if patch_reshape_parameters is not None: + + # The dimensionality of the reshaped patch: + new_shape = [np.int(len(patch)/(patch_reshape_parameters[-2]*patch_reshape_parameters[-1]))] + list(patch_reshape_parameters[-2:]) + + patch = np.squeeze(patch.reshape(new_shape)) + + patches_3d.append(patch) + + return patches_3d + + +# ============================================================================= +def combinations( input_dict ): + """ + Obtain all possible key-value combinations in the input dictionary. + + **Parameters:** + + ``input_dict`` : dict + An input dictionary. + + **Returns:** + + ``combinations`` : [dict] + List of dictionaries containing the combinations. + """ + + varNames = sorted( input_dict ) + + combinations = [ dict( zip( varNames, prod ) ) for prod in it.product( *( input_dict[ varName ] for varName in varNames ) ) ] + + return combinations + + +# ============================================================================= +def apply_transform_as_pil(img_array, transform): + """ + Apply composed transformation to the input bw or rgb image / numpy array. + Input image is in the Bob format. Before the transformation the input + image is transformed to the PIL image. + + **Parameters:** + + ``img_array`` : 2D or 3D :py:class:`numpy.ndarray` + An input image / array. stored in Bob format for RGB images. + + ``transform`` : torchvision.transforms.transforms.Compose + Composed transfromation to be applied to the input image. + + **Returns:** + + ``features`` : Tensor + Transformed image. + """ + + + if isinstance(transform, transforms.Compose): # if an instance of torchvision composed transformation + + if len(img_array.shape) == 3: # for color images + + img_array_tr = np.swapaxes(img_array, 1, 2) + img_array_tr = np.swapaxes(img_array_tr, 0, 2) + + pil_img = PIL.Image.fromarray( img_array_tr ) # convert to PIL from array of size (H x W x 3) + + else: # for gray-scale images + + pil_img = PIL.Image.fromarray( img_array, 'L' ) # convert to PIL from array of size (H x W) + + if transform is not None: + + pil_img = transform(pil_img) + + return pil_img + + +# ============================================================================= +def net_forward(feature, + config_file, + config_group, + model_file, + invert_scores_flag = False, + prediction_function = None, + color_input_flag = False): + """ + **Parameters:** + + ``feature`` : :py:class:`numpy.ndarray` + ND feature array of the size (N_samples x dim1 x dim2 x ...). + + ``config_file``: py:class:`string` + Relative name of the config file defining the network, training data, + and training parameters. The path should be relative to + ``config_group``, for example: "autoencoder/netN.py". + + ``config_group``: py:class:`string` + Group/package name containing the configuration file. Usually all + configs should be stored in this folder/place. + For example: "bob.pad.face.config.pytorch". + Both ``config_file`` and ``config_group`` are used to access the + configuration module. + + ``model_file`` : str + A path to the model file to be used for network initialization. + The network structure is defined in the config file. + + ``invert_scores_flag`` : bool + If set to ``True`` output array will be multiplied by -1. + Default: ``False``. + + ``prediction_function`` : function + If defined, will be used insted of forward() method of the network + to compute the output. + Default: ``None``. + + ``color_input_flag`` : bool + If set to ``True``, the input is considered to be a color image of the + size ``(3, H, W)``. The tensor to be passed through the net will be + of the size ``(1, 3, H, W)``. + If set to ``False``, the input is considered to be a set of BW images + of the size ``(n_samples, H, W)``. The tensor to be passed through + the net will be of the size ``(n_samples, 1, H, W)``. + + **Returns:** + + ``net_output`` : [float] + Output of the network per input sample/frame. + """ + + # Create relative module name given path: + relative_mod_name = '.' + os.path.splitext(config_file)[0].replace(os.path.sep, '.') + + config_module = importlib.import_module(relative_mod_name, config_group) + + # preprocess the features before passing to the NN: + + if "transform" in dir(config_module): + + if isinstance(config_module.transform, transforms.Compose): + + feature = apply_transform_as_pil(feature, config_module.transform) + + else: + + feature = np.stack([config_module.transform(item) for item in feature]) + + if color_input_flag: + # convert feature array to Tensor of size (1, 3, H, W) + feature_tensor = torch.Tensor(feature).unsqueeze(0) + + else: + # convert feature array to Tensor of size (n_samples, 1, H, W) + feature_tensor = torch.Tensor(feature).unsqueeze(1) + + # Initialize the model + local_model = config_module.Network() + + model_state = torch.load(model_file, map_location=lambda storage,loc:storage) + + # Initialize the state of the model: + local_model.load_state_dict(model_state) + + # Model is used for evaluation only + local_model.train(False) + + if prediction_function is not None: + + output_tensor = prediction_function(local_model, Variable(feature_tensor)) + + else: + + output_tensor = local_model.forward(Variable(feature_tensor)) + + net_output = output_tensor.data.numpy().squeeze() + + net_output = net_output.flatten() + + if invert_scores_flag: + + net_output = -1.*net_output + + return net_output.astype(np.float) + -- GitLab From 6fcf9c5e6f8845bbb6979351b480bd4a829b1ba6 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Fri, 25 Jan 2019 16:56:40 +0100 Subject: [PATCH 02/17] Added unit test for MultiNetPatchClassifier extractor, and pre-trained model for AE --- bob/ip/pytorch_extractor/test.py | 76 ++++++++++++++++++ ...el_pretrain_celeba_tune_batl_full_face.pth | Bin 0 -> 101452 bytes 2 files changed, 76 insertions(+) create mode 100644 bob/ip/pytorch_extractor/test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index a4fc5d2..ae5822b 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -45,3 +45,79 @@ def test_lightcnn9(): data = numpy.random.rand(128, 128).astype("float32") output = extractor(data) assert output.shape[0] == 256 + +def test_multi_net_patch_classifier(): + """ + Test the MultiNetPatchClassifier extractor class. + """ + + from bob.ip.pytorch_extractor import MultiNetPatchClassifier + + # ========================================================================= + # prepare the test data: + patch_2d = numpy.repeat(numpy.expand_dims(numpy.sin(numpy.arange(0,12.8,0.1)), axis=0), 128, axis=0) + + patch = numpy.uint8((numpy.stack([patch_2d, patch_2d.transpose(), -patch_2d])+1)*255/2.) + + # flatten the 3D test patch: + patch_flat = numpy.expand_dims(patch.flatten(), axis=0) + + # ========================================================================= + # test the extractor: + + CONFIG_FILE = "autoencoder/net1_celeba.py" # config containing an instance of Composed Transform and a Network class to be used in feature extractor + CONFIG_GROUP = "bob.learn.pytorch.config" + # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: + + MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', + 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] + + FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch + + def _prediction_function(local_model, x): # use only encoder from Network loaded from above config. + x = local_model.encoder(x) + return x + + # kwargs for function defined by FUNCTION_NAME constant: + FUNCTION_KWARGS = {} + FUNCTION_KWARGS["config_file"] = CONFIG_FILE + FUNCTION_KWARGS["config_group"] = CONFIG_GROUP + FUNCTION_KWARGS["model_file"] = MODEL_FILE + FUNCTION_KWARGS["invert_scores_flag"] = False + FUNCTION_KWARGS["prediction_function"] = _prediction_function + FUNCTION_KWARGS["color_input_flag"] = True + + PATCHES_NUM = [0] # patches to be used in the feature extraction process + + PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network + + image_extractor = MultiNetPatchClassifier(config_file = CONFIG_FILE, + config_group = CONFIG_GROUP, + model_file = MODEL_FILE, + function_name = FUNCTION_NAME, + function_kwargs = FUNCTION_KWARGS, + patches_num = PATCHES_NUM, + patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) + + # pass through encoder only, compute latent vector: + latent_vector = image_extractor(patch_flat) + + # pass through AE, compute reconstructed image: + image_extractor.function_kwargs['prediction_function'] = None + reconstructed = image_extractor(patch_flat).reshape(PATCH_RESHAPE_PARAMETERS) + + # test: + assert latent_vector.shape == (1296,) + assert reconstructed.shape == (3, 128, 128) + +# # for visualization/debugging only: +# import matplotlib.pyplot as plt +# import bob.io.image +# +# plt.figure() +# plt.imshow(bob.io.image.to_matplotlib(patch)) +# plt.show() +# +# plt.figure() +# plt.imshow(bob.io.image.to_matplotlib(reconstructed)) +# plt.show() diff --git a/bob/ip/pytorch_extractor/test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth b/bob/ip/pytorch_extractor/test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth new file mode 100644 index 0000000000000000000000000000000000000000..1cb97a261f2901a1632e50d651d1c136c8146da8 GIT binary patch literal 101452 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 z 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 literal 0 HcmV?d00001 -- GitLab From 94a39dbfe313b95f8ca90a41329eeea2629d3f5a Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Fri, 25 Jan 2019 17:02:18 +0100 Subject: [PATCH 03/17] Added .pth to manifest, for models --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 7268ed7..1031f82 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ include README.rst buildout.cfg develop.cfg COPYING version.txt requirements.txt -recursive-include doc *.py *.rst +recursive-include doc *.py *.rst *.pth -- GitLab From 3a083e3089c175124bc677ede085206cbc5b8b71 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Fri, 25 Jan 2019 17:51:39 +0100 Subject: [PATCH 04/17] Added a config without DB instance, to fix the tests --- bob/ip/pytorch_extractor/test.py | 4 +- .../pytorch_extractor/test_data/__init__.py | 0 .../test_data/net1_test_config.py | 81 +++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100755 bob/ip/pytorch_extractor/test_data/__init__.py create mode 100644 bob/ip/pytorch_extractor/test_data/net1_test_config.py diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index ae5822b..c2b8868 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -65,8 +65,8 @@ def test_multi_net_patch_classifier(): # ========================================================================= # test the extractor: - CONFIG_FILE = "autoencoder/net1_celeba.py" # config containing an instance of Composed Transform and a Network class to be used in feature extractor - CONFIG_GROUP = "bob.learn.pytorch.config" + CONFIG_FILE = "test_data/net1_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" # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', diff --git a/bob/ip/pytorch_extractor/test_data/__init__.py b/bob/ip/pytorch_extractor/test_data/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/bob/ip/pytorch_extractor/test_data/net1_test_config.py b/bob/ip/pytorch_extractor/test_data/net1_test_config.py new file mode 100644 index 0000000..6ba47e5 --- /dev/null +++ b/bob/ip/pytorch_extractor/test_data/net1_test_config.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +""" +@author: Olegs Nikisins +""" +#============================================================================== +# Import here: + +from torchvision import transforms + +#from bob.pad.face.database import CELEBAPadDatabase + +from torch import nn + + +#============================================================================== +# Define parameters here: + +""" +Note: do not change names of the below constants. +""" +NUM_EPOCHS = 70 # Maximum number of epochs +BATCH_SIZE = 32 # Size of the batch +LEARNING_RATE = 1e-3 # Learning rate +NUM_WORKERS = 8 # The number of workers for the DataLoader + + +""" +Transformations to be applied sequentially to the input PIL image. +Note: the variable name ``transform`` must be the same in all configuration files. +""" + +transform = transforms.Compose([transforms.ToTensor(), + transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) + ]) + + +""" +Set the parameters of the DataFolder dataset class. +Note: do not change the name ``kwargs``. +""" +#bob_hldi_instance = CELEBAPadDatabase(original_directory = "", original_extension = "") + +kwargs = {} +kwargs["data_folder"] = "NO NEED TO SET HERE, WILL BE SET IN THE TRAINING SCRIPT" +kwargs["transform"] = transform +kwargs["extension"] = '.hdf5' +kwargs["bob_hldi_instance"] = None +kwargs["hldi_type"] = "pad" +kwargs["groups"] = ['train'] +kwargs["protocol"] = 'grandtest' +kwargs["purposes"] = ['real'] +kwargs["allow_missing_files"] = True + + +""" +Define the network to be trained as a class, named ``Network``. +Note: Do not change the name of the below class. +""" + +from bob.learn.pytorch.architectures import ConvAutoencoder as Network + + +""" +Define the loss to be used for training. +Note: do not change the name of the below variable. +""" +loss_type = nn.MSELoss() + + +""" +OPTIONAL: if not defined loss will be computed in the training script. +See training script for details + +Define the function to compute the loss. Don't change the signature of this +function. +""" +# we don't define the loss_function for this configuration +#def loss_function(output, img, target): + + -- GitLab From e079864491cfd0b566c1d31a723d4588c177e9ff Mon Sep 17 00:00:00 2001 From: Olegs Nikisins Date: Fri, 25 Jan 2019 20:23:14 +0100 Subject: [PATCH 05/17] disabled unit test for MultiNetPatchClassifier --- bob/ip/pytorch_extractor/test.py | 147 ++++++++++++++++--------------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index c2b8868..e3a59e7 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -46,78 +46,79 @@ def test_lightcnn9(): output = extractor(data) assert output.shape[0] == 256 -def test_multi_net_patch_classifier(): - """ - Test the MultiNetPatchClassifier extractor class. - """ - - from bob.ip.pytorch_extractor import MultiNetPatchClassifier - - # ========================================================================= - # prepare the test data: - patch_2d = numpy.repeat(numpy.expand_dims(numpy.sin(numpy.arange(0,12.8,0.1)), axis=0), 128, axis=0) - - patch = numpy.uint8((numpy.stack([patch_2d, patch_2d.transpose(), -patch_2d])+1)*255/2.) - - # flatten the 3D test patch: - patch_flat = numpy.expand_dims(patch.flatten(), axis=0) - - # ========================================================================= - # test the extractor: - - CONFIG_FILE = "test_data/net1_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" - # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: - - MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', - 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] - - FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch - - def _prediction_function(local_model, x): # use only encoder from Network loaded from above config. - x = local_model.encoder(x) - return x - - # kwargs for function defined by FUNCTION_NAME constant: - FUNCTION_KWARGS = {} - FUNCTION_KWARGS["config_file"] = CONFIG_FILE - FUNCTION_KWARGS["config_group"] = CONFIG_GROUP - FUNCTION_KWARGS["model_file"] = MODEL_FILE - FUNCTION_KWARGS["invert_scores_flag"] = False - FUNCTION_KWARGS["prediction_function"] = _prediction_function - FUNCTION_KWARGS["color_input_flag"] = True - - PATCHES_NUM = [0] # patches to be used in the feature extraction process - - PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network - - image_extractor = MultiNetPatchClassifier(config_file = CONFIG_FILE, - config_group = CONFIG_GROUP, - model_file = MODEL_FILE, - function_name = FUNCTION_NAME, - function_kwargs = FUNCTION_KWARGS, - patches_num = PATCHES_NUM, - patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) - - # pass through encoder only, compute latent vector: - latent_vector = image_extractor(patch_flat) - - # pass through AE, compute reconstructed image: - image_extractor.function_kwargs['prediction_function'] = None - reconstructed = image_extractor(patch_flat).reshape(PATCH_RESHAPE_PARAMETERS) - - # test: - assert latent_vector.shape == (1296,) - assert reconstructed.shape == (3, 128, 128) - -# # for visualization/debugging only: -# import matplotlib.pyplot as plt -# import bob.io.image +# def test_multi_net_patch_classifier(): +# """ +# Test the MultiNetPatchClassifier extractor class. +# """ +# +# from bob.ip.pytorch_extractor import MultiNetPatchClassifier +# +# # ========================================================================= +# # prepare the test data: +# patch_2d = numpy.repeat(numpy.expand_dims(numpy.sin(numpy.arange(0,12.8,0.1)), axis=0), 128, axis=0) +# +# patch = numpy.uint8((numpy.stack([patch_2d, patch_2d.transpose(), -patch_2d])+1)*255/2.) +# +# # flatten the 3D test patch: +# patch_flat = numpy.expand_dims(patch.flatten(), axis=0) +# +# # ========================================================================= +# # test the extractor: +# +# CONFIG_FILE = "test_data/net1_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" +# # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: +# +# MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', +# 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] +# +# FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch # -# plt.figure() -# plt.imshow(bob.io.image.to_matplotlib(patch)) -# plt.show() +# def _prediction_function(local_model, x): # use only encoder from Network loaded from above config. +# x = local_model.encoder(x) +# return x # -# plt.figure() -# plt.imshow(bob.io.image.to_matplotlib(reconstructed)) -# plt.show() +# # kwargs for function defined by FUNCTION_NAME constant: +# FUNCTION_KWARGS = {} +# FUNCTION_KWARGS["config_file"] = CONFIG_FILE +# FUNCTION_KWARGS["config_group"] = CONFIG_GROUP +# FUNCTION_KWARGS["model_file"] = MODEL_FILE +# FUNCTION_KWARGS["invert_scores_flag"] = False +# FUNCTION_KWARGS["prediction_function"] = _prediction_function +# FUNCTION_KWARGS["color_input_flag"] = True +# +# PATCHES_NUM = [0] # patches to be used in the feature extraction process +# +# PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network +# +# image_extractor = MultiNetPatchClassifier(config_file = CONFIG_FILE, +# config_group = CONFIG_GROUP, +# model_file = MODEL_FILE, +# function_name = FUNCTION_NAME, +# function_kwargs = FUNCTION_KWARGS, +# patches_num = PATCHES_NUM, +# patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) +# +# # pass through encoder only, compute latent vector: +# latent_vector = image_extractor(patch_flat) +# +# # pass through AE, compute reconstructed image: +# image_extractor.function_kwargs['prediction_function'] = None +# reconstructed = image_extractor(patch_flat).reshape(PATCH_RESHAPE_PARAMETERS) +# +# # test: +# assert latent_vector.shape == (1296,) +# assert reconstructed.shape == (3, 128, 128) +# +# # # for visualization/debugging only: +# # import matplotlib.pyplot as plt +# # import bob.io.image +# # +# # plt.figure() +# # plt.imshow(bob.io.image.to_matplotlib(patch)) +# # plt.show() +# # +# # plt.figure() +# # plt.imshow(bob.io.image.to_matplotlib(reconstructed)) +# # plt.show() + -- GitLab From 3b6dd3210fcf1262fe0aa227d8e01d0d4410b191 Mon Sep 17 00:00:00 2001 From: Olegs Nikisins Date: Fri, 25 Jan 2019 21:12:34 +0100 Subject: [PATCH 06/17] Modified MANIFEST, more detailed path to .pth file --- MANIFEST.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 1031f82..955314e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ include README.rst buildout.cfg develop.cfg COPYING version.txt requirements.txt -recursive-include doc *.py *.rst *.pth +recursive-include doc *.py *.rst +recursive-include bob/ip/pytorch_extractor *.pth -- GitLab From cc5e28b164ca2a0c77441627bc8ced8d910fe9fe Mon Sep 17 00:00:00 2001 From: Olegs Nikisins Date: Fri, 25 Jan 2019 21:41:33 +0100 Subject: [PATCH 07/17] Unit test for MultiNetPatchClassifier is ON again --- bob/ip/pytorch_extractor/test.py | 147 ++++++++++++++++--------------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index e3a59e7..1d2b685 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -46,79 +46,80 @@ def test_lightcnn9(): output = extractor(data) assert output.shape[0] == 256 -# def test_multi_net_patch_classifier(): -# """ -# Test the MultiNetPatchClassifier extractor class. -# """ -# -# from bob.ip.pytorch_extractor import MultiNetPatchClassifier -# -# # ========================================================================= -# # prepare the test data: -# patch_2d = numpy.repeat(numpy.expand_dims(numpy.sin(numpy.arange(0,12.8,0.1)), axis=0), 128, axis=0) -# -# patch = numpy.uint8((numpy.stack([patch_2d, patch_2d.transpose(), -patch_2d])+1)*255/2.) -# -# # flatten the 3D test patch: -# patch_flat = numpy.expand_dims(patch.flatten(), axis=0) -# -# # ========================================================================= -# # test the extractor: -# -# CONFIG_FILE = "test_data/net1_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" -# # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: -# -# MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', -# 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] -# -# FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch -# -# def _prediction_function(local_model, x): # use only encoder from Network loaded from above config. -# x = local_model.encoder(x) -# return x -# -# # kwargs for function defined by FUNCTION_NAME constant: -# FUNCTION_KWARGS = {} -# FUNCTION_KWARGS["config_file"] = CONFIG_FILE -# FUNCTION_KWARGS["config_group"] = CONFIG_GROUP -# FUNCTION_KWARGS["model_file"] = MODEL_FILE -# FUNCTION_KWARGS["invert_scores_flag"] = False -# FUNCTION_KWARGS["prediction_function"] = _prediction_function -# FUNCTION_KWARGS["color_input_flag"] = True -# -# PATCHES_NUM = [0] # patches to be used in the feature extraction process -# -# PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network -# -# image_extractor = MultiNetPatchClassifier(config_file = CONFIG_FILE, -# config_group = CONFIG_GROUP, -# model_file = MODEL_FILE, -# function_name = FUNCTION_NAME, -# function_kwargs = FUNCTION_KWARGS, -# patches_num = PATCHES_NUM, -# patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) -# -# # pass through encoder only, compute latent vector: -# latent_vector = image_extractor(patch_flat) -# -# # pass through AE, compute reconstructed image: -# image_extractor.function_kwargs['prediction_function'] = None -# reconstructed = image_extractor(patch_flat).reshape(PATCH_RESHAPE_PARAMETERS) +def test_multi_net_patch_classifier(): + """ + Test the MultiNetPatchClassifier extractor class. + """ + + from bob.ip.pytorch_extractor import MultiNetPatchClassifier + + # ========================================================================= + # prepare the test data: + patch_2d = numpy.repeat(numpy.expand_dims(numpy.sin(numpy.arange(0,12.8,0.1)), axis=0), 128, axis=0) + + patch = numpy.uint8((numpy.stack([patch_2d, patch_2d.transpose(), -patch_2d])+1)*255/2.) + + # flatten the 3D test patch: + patch_flat = numpy.expand_dims(patch.flatten(), axis=0) + + # ========================================================================= + # test the extractor: + + CONFIG_FILE = "test_data/net1_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" + # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: + + MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', + 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] + + FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch + + def _prediction_function(local_model, x): # use only encoder from Network loaded from above config. + x = local_model.encoder(x) + return x + + # kwargs for function defined by FUNCTION_NAME constant: + FUNCTION_KWARGS = {} + FUNCTION_KWARGS["config_file"] = CONFIG_FILE + FUNCTION_KWARGS["config_group"] = CONFIG_GROUP + FUNCTION_KWARGS["model_file"] = MODEL_FILE + FUNCTION_KWARGS["invert_scores_flag"] = False + FUNCTION_KWARGS["prediction_function"] = _prediction_function + FUNCTION_KWARGS["color_input_flag"] = True + + PATCHES_NUM = [0] # patches to be used in the feature extraction process + + PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network + + image_extractor = MultiNetPatchClassifier(config_file = CONFIG_FILE, + config_group = CONFIG_GROUP, + model_file = MODEL_FILE, + function_name = FUNCTION_NAME, + function_kwargs = FUNCTION_KWARGS, + patches_num = PATCHES_NUM, + patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) + + # pass through encoder only, compute latent vector: + latent_vector = image_extractor(patch_flat) + + # pass through AE, compute reconstructed image: + image_extractor.function_kwargs['prediction_function'] = None + reconstructed = image_extractor(patch_flat).reshape(PATCH_RESHAPE_PARAMETERS) + + # test: + assert latent_vector.shape == (1296,) + assert reconstructed.shape == (3, 128, 128) + +# # for visualization/debugging only: +# import matplotlib.pyplot as plt +# import bob.io.image # -# # test: -# assert latent_vector.shape == (1296,) -# assert reconstructed.shape == (3, 128, 128) +# plt.figure() +# plt.imshow(bob.io.image.to_matplotlib(patch)) +# plt.show() # -# # # for visualization/debugging only: -# # import matplotlib.pyplot as plt -# # import bob.io.image -# # -# # plt.figure() -# # plt.imshow(bob.io.image.to_matplotlib(patch)) -# # plt.show() -# # -# # plt.figure() -# # plt.imshow(bob.io.image.to_matplotlib(reconstructed)) -# # plt.show() +# plt.figure() +# plt.imshow(bob.io.image.to_matplotlib(reconstructed)) +# plt.show() + -- GitLab From 4886bbadbb1ee1e6a50974c36aed3dd21971367b Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Tue, 29 Jan 2019 13:35:46 +0100 Subject: [PATCH 08/17] Updated the docstring of MultiNetPatchClassifier --- bob/ip/pytorch_extractor/MultiNetPatchClassifier.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py b/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py index 27df0d6..7d5a991 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py @@ -37,9 +37,8 @@ class MultiNetPatchClassifier(Extractor, object): Attributes ----------- config_file: str - Relative name of the config file defining the network, training data, - and training parameters. The path should be relative to - ``config_group``, + Relative name of the config file defining the network, and training parameters. + The path should be relative to ``config_group``, for example: "autoencoder/net1_batl_3_layers_partial.py". config_group: str -- GitLab From 19f0e884eb02947719d27ec30dac36ece3b5b408 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Tue, 29 Jan 2019 14:15:45 +0100 Subject: [PATCH 09/17] Renamed the class MultiNetPatchClassifier to MultiNetPatchExtractor --- ...lassifier.py => MultiNetPatchExtractor.py} | 4 ++-- bob/ip/pytorch_extractor/__init__.py | 4 ++-- bob/ip/pytorch_extractor/test.py | 20 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) rename bob/ip/pytorch_extractor/{MultiNetPatchClassifier.py => MultiNetPatchExtractor.py} (97%) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py similarity index 97% rename from bob/ip/pytorch_extractor/MultiNetPatchClassifier.py rename to bob/ip/pytorch_extractor/MultiNetPatchExtractor.py index 7d5a991..cd61104 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchClassifier.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py @@ -18,7 +18,7 @@ from bob.ip.pytorch_extractor.utils import net_forward # ============================================================================= # Main body: -class MultiNetPatchClassifier(Extractor, object): +class MultiNetPatchExtractor(Extractor, object): """ This class is designed to pass a set of patches through a possibly multiple networks and compute a feature vector combining outputs of all networks. @@ -88,7 +88,7 @@ class MultiNetPatchClassifier(Extractor, object): Init method. """ - super(MultiNetPatchClassifier, self).__init__(config_file = config_file, + super(MultiNetPatchExtractor, self).__init__(config_file = config_file, config_group = config_group, model_file = model_file, function_name = function_name, diff --git a/bob/ip/pytorch_extractor/__init__.py b/bob/ip/pytorch_extractor/__init__.py index aa6aa99..725c7cf 100755 --- a/bob/ip/pytorch_extractor/__init__.py +++ b/bob/ip/pytorch_extractor/__init__.py @@ -1,7 +1,7 @@ from .CNN8 import CNN8Extractor from .CasiaNet import CasiaNetExtractor from .LightCNN9 import LightCNN9Extractor -from .MultiNetPatchClassifier import MultiNetPatchClassifier +from .MultiNetPatchExtractor import MultiNetPatchExtractor # gets sphinx autodoc done right - don't remove it def __appropriate__(*args): @@ -22,7 +22,7 @@ __appropriate__( CNN8Extractor, CasiaNetExtractor, LightCNN9Extractor, - MultiNetPatchClassifier, + MultiNetPatchExtractor, ) # gets sphinx autodoc done right - don't remove it diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index 1d2b685..cb519db 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -46,12 +46,12 @@ def test_lightcnn9(): output = extractor(data) assert output.shape[0] == 256 -def test_multi_net_patch_classifier(): +def test_multi_net_patch_extractor(): """ - Test the MultiNetPatchClassifier extractor class. + Test the MultiNetPatchExtractor extractor class. """ - from bob.ip.pytorch_extractor import MultiNetPatchClassifier + from bob.ip.pytorch_extractor import MultiNetPatchExtractor # ========================================================================= # prepare the test data: @@ -91,13 +91,13 @@ def test_multi_net_patch_classifier(): PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network - image_extractor = MultiNetPatchClassifier(config_file = CONFIG_FILE, - config_group = CONFIG_GROUP, - model_file = MODEL_FILE, - function_name = FUNCTION_NAME, - function_kwargs = FUNCTION_KWARGS, - patches_num = PATCHES_NUM, - patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) + image_extractor = MultiNetPatchExtractor(config_file = CONFIG_FILE, + config_group = CONFIG_GROUP, + model_file = MODEL_FILE, + function_name = FUNCTION_NAME, + function_kwargs = FUNCTION_KWARGS, + patches_num = PATCHES_NUM, + patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) # pass through encoder only, compute latent vector: latent_vector = image_extractor(patch_flat) -- GitLab From 46be4794c5fcec9bbaac42bf6b606001e76a58e0 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Tue, 29 Jan 2019 14:39:28 +0100 Subject: [PATCH 10/17] Removed the prediction_function from net_forward, simplified the test config --- .../MultiNetPatchExtractor.py | 12 ++--- bob/ip/pytorch_extractor/test.py | 15 +----- .../test_data/net1_test_config.py | 48 ++----------------- bob/ip/pytorch_extractor/utils.py | 35 ++++++++++---- 4 files changed, 38 insertions(+), 72 deletions(-) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py index cd61104..d4aff78 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py @@ -89,12 +89,12 @@ class MultiNetPatchExtractor(Extractor, object): """ super(MultiNetPatchExtractor, self).__init__(config_file = config_file, - config_group = config_group, - model_file = model_file, - function_name = function_name, - function_kwargs = function_kwargs, - patches_num = patches_num, - patch_reshape_parameters = patch_reshape_parameters) + config_group = config_group, + model_file = model_file, + function_name = function_name, + function_kwargs = function_kwargs, + patches_num = patches_num, + patch_reshape_parameters = patch_reshape_parameters) self.config_file = config_file self.config_group = config_group diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index cb519db..58dba26 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -74,17 +74,12 @@ def test_multi_net_patch_extractor(): FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch - def _prediction_function(local_model, x): # use only encoder from Network loaded from above config. - x = local_model.encoder(x) - return x - # kwargs for function defined by FUNCTION_NAME constant: FUNCTION_KWARGS = {} FUNCTION_KWARGS["config_file"] = CONFIG_FILE FUNCTION_KWARGS["config_group"] = CONFIG_GROUP FUNCTION_KWARGS["model_file"] = MODEL_FILE FUNCTION_KWARGS["invert_scores_flag"] = False - FUNCTION_KWARGS["prediction_function"] = _prediction_function FUNCTION_KWARGS["color_input_flag"] = True PATCHES_NUM = [0] # patches to be used in the feature extraction process @@ -102,13 +97,8 @@ def test_multi_net_patch_extractor(): # pass through encoder only, compute latent vector: latent_vector = image_extractor(patch_flat) - # pass through AE, compute reconstructed image: - image_extractor.function_kwargs['prediction_function'] = None - reconstructed = image_extractor(patch_flat).reshape(PATCH_RESHAPE_PARAMETERS) - # test: assert latent_vector.shape == (1296,) - assert reconstructed.shape == (3, 128, 128) # # for visualization/debugging only: # import matplotlib.pyplot as plt @@ -117,9 +107,6 @@ def test_multi_net_patch_extractor(): # plt.figure() # plt.imshow(bob.io.image.to_matplotlib(patch)) # plt.show() -# -# plt.figure() -# plt.imshow(bob.io.image.to_matplotlib(reconstructed)) -# plt.show() + diff --git a/bob/ip/pytorch_extractor/test_data/net1_test_config.py b/bob/ip/pytorch_extractor/test_data/net1_test_config.py index 6ba47e5..4a40ced 100644 --- a/bob/ip/pytorch_extractor/test_data/net1_test_config.py +++ b/bob/ip/pytorch_extractor/test_data/net1_test_config.py @@ -16,15 +16,6 @@ from torch import nn #============================================================================== # Define parameters here: -""" -Note: do not change names of the below constants. -""" -NUM_EPOCHS = 70 # Maximum number of epochs -BATCH_SIZE = 32 # Size of the batch -LEARNING_RATE = 1e-3 # Learning rate -NUM_WORKERS = 8 # The number of workers for the DataLoader - - """ Transformations to be applied sequentially to the input PIL image. Note: the variable name ``transform`` must be the same in all configuration files. @@ -35,47 +26,16 @@ transform = transforms.Compose([transforms.ToTensor(), ]) -""" -Set the parameters of the DataFolder dataset class. -Note: do not change the name ``kwargs``. -""" -#bob_hldi_instance = CELEBAPadDatabase(original_directory = "", original_extension = "") - -kwargs = {} -kwargs["data_folder"] = "NO NEED TO SET HERE, WILL BE SET IN THE TRAINING SCRIPT" -kwargs["transform"] = transform -kwargs["extension"] = '.hdf5' -kwargs["bob_hldi_instance"] = None -kwargs["hldi_type"] = "pad" -kwargs["groups"] = ['train'] -kwargs["protocol"] = 'grandtest' -kwargs["purposes"] = ['real'] -kwargs["allow_missing_files"] = True - - """ Define the network to be trained as a class, named ``Network``. -Note: Do not change the name of the below class. +Note: Do not change the name of the below class, always import as ``Network``. """ from bob.learn.pytorch.architectures import ConvAutoencoder as Network """ -Define the loss to be used for training. -Note: do not change the name of the below variable. -""" -loss_type = nn.MSELoss() - - -""" -OPTIONAL: if not defined loss will be computed in the training script. -See training script for details - -Define the function to compute the loss. Don't change the signature of this -function. +kwargs to be used for ``Network`` initialization. The name must be ``network_kwargs``. """ -# we don't define the loss_function for this configuration -#def loss_function(output, img, target): - - +network_kwargs = {} +network_kwargs['return_latent_embedding'] = True diff --git a/bob/ip/pytorch_extractor/utils.py b/bob/ip/pytorch_extractor/utils.py index 00982a8..cb5af63 100644 --- a/bob/ip/pytorch_extractor/utils.py +++ b/bob/ip/pytorch_extractor/utils.py @@ -131,6 +131,31 @@ def apply_transform_as_pil(img_array, transform): return pil_img +def _init_the_network(config_module): + """ + Initialize the network, given imported configuration module. + + Parameters + ---------- + config_module : object + Module containing Network configuration parameters. + + Returns + ------- + model : object + An instance of the Network class. + """ + + if "network_kwargs" in dir(config_module): + network_kwargs = config_module.network_kwargs + model = config_module.Network(**network_kwargs) + + else: + model = config_module.Network() + + return model + + # ============================================================================= def net_forward(feature, config_file, @@ -210,7 +235,7 @@ def net_forward(feature, feature_tensor = torch.Tensor(feature).unsqueeze(1) # Initialize the model - local_model = config_module.Network() + local_model = _init_the_network(config_module) model_state = torch.load(model_file, map_location=lambda storage,loc:storage) @@ -220,13 +245,7 @@ def net_forward(feature, # Model is used for evaluation only local_model.train(False) - if prediction_function is not None: - - output_tensor = prediction_function(local_model, Variable(feature_tensor)) - - else: - - output_tensor = local_model.forward(Variable(feature_tensor)) + output_tensor = local_model.forward(Variable(feature_tensor)) net_output = output_tensor.data.numpy().squeeze() -- GitLab From dc23895cc015977b2b7b85740fef74a129bedb82 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Tue, 29 Jan 2019 16:49:47 +0100 Subject: [PATCH 11/17] Refactored the and renamed net_forward(), and removed this function from MultiNetPatchExtractor --- .../MultiNetPatchExtractor.py | 23 +-- bob/ip/pytorch_extractor/test.py | 6 +- bob/ip/pytorch_extractor/utils.py | 169 +++++++++++------- 3 files changed, 118 insertions(+), 80 deletions(-) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py index d4aff78..707ad8c 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py @@ -14,7 +14,7 @@ import numpy as np from bob.ip.pytorch_extractor.utils import reshape_flat_patches from bob.ip.pytorch_extractor.utils import combinations -from bob.ip.pytorch_extractor.utils import net_forward +from bob.ip.pytorch_extractor.utils import transform_and_net_forward # ============================================================================= # Main body: @@ -52,11 +52,11 @@ class MultiNetPatchExtractor(Extractor, object): A path to the model file to be used for network initialization. The network structure is defined in the config file. - function_name : str - Name of the function to be applied to the input tensor. - Currently only "net_forward" function is supported. - function_kwargs : dict + + UPDATE THIS!!!! + + Key-word arguments for the function defined by ``function_name``. Note, that you can also specify one of the values in the dictionary as a list containing multiple elements. Then, ``function_kwargs`` will @@ -80,7 +80,6 @@ class MultiNetPatchExtractor(Extractor, object): def __init__(self, config_file, config_group, model_file, - function_name, function_kwargs, patches_num, patch_reshape_parameters = None): @@ -91,7 +90,6 @@ class MultiNetPatchExtractor(Extractor, object): super(MultiNetPatchExtractor, self).__init__(config_file = config_file, config_group = config_group, model_file = model_file, - function_name = function_name, function_kwargs = function_kwargs, patches_num = patches_num, patch_reshape_parameters = patch_reshape_parameters) @@ -99,7 +97,6 @@ class MultiNetPatchExtractor(Extractor, object): self.config_file = config_file self.config_group = config_group self.model_file = model_file - self.function_name = function_name self.function_kwargs = function_kwargs self.patches_num = patches_num self.patch_reshape_parameters = patch_reshape_parameters @@ -140,15 +137,13 @@ class MultiNetPatchExtractor(Extractor, object): for idx, patch in enumerate(patches_3d): - if self.function_name == 'net_forward': - - if len(function_kwargs) == 1: # patches are passed through the same network: + if len(function_kwargs) == 1: # patches are passed through the same network: - features = net_forward(feature = patch, **function_kwargs[0]) + features = transform_and_net_forward(feature = patch, **function_kwargs[0]) - else: # patches are passed through different networks: + else: # patches are passed through different networks: - features = net_forward(feature = patch, **function_kwargs[self.patches_num(idx)]) + features = transform_and_net_forward(feature = patch, **function_kwargs[self.patches_num(idx)]) # print ("The model we use for patch {} is:".format(str(idx))) # print (function_kwargs[self.patches_num(idx)]["model_file"]) diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index 58dba26..0015204 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -72,14 +72,11 @@ def test_multi_net_patch_extractor(): MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] - FUNCTION_NAME = "net_forward" # function to be used to extract features given input patch - - # kwargs for function defined by FUNCTION_NAME constant: + # kwargs for the transform_and_net_forward function: FUNCTION_KWARGS = {} FUNCTION_KWARGS["config_file"] = CONFIG_FILE FUNCTION_KWARGS["config_group"] = CONFIG_GROUP FUNCTION_KWARGS["model_file"] = MODEL_FILE - FUNCTION_KWARGS["invert_scores_flag"] = False FUNCTION_KWARGS["color_input_flag"] = True PATCHES_NUM = [0] # patches to be used in the feature extraction process @@ -89,7 +86,6 @@ def test_multi_net_patch_extractor(): image_extractor = MultiNetPatchExtractor(config_file = CONFIG_FILE, config_group = CONFIG_GROUP, model_file = MODEL_FILE, - function_name = FUNCTION_NAME, function_kwargs = FUNCTION_KWARGS, patches_num = PATCHES_NUM, patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) diff --git a/bob/ip/pytorch_extractor/utils.py b/bob/ip/pytorch_extractor/utils.py index cb5af63..5a6ece5 100644 --- a/bob/ip/pytorch_extractor/utils.py +++ b/bob/ip/pytorch_extractor/utils.py @@ -30,13 +30,14 @@ def reshape_flat_patches(patches, patch_reshape_parameters = None): """ Reshape a set of flattened patches into original dimensions, 2D or 3D - **Parameters:** + Parameters + ---------- - ``patches`` : 2D :py:class:`numpy.ndarray` + patches : 2D :py:class:`numpy.ndarray` An array containing flattened patches. The dimensions are: ``num_patches x len_of_flat_patch`` - ``patch_reshape_parameters`` : [int] or None + patch_reshape_parameters : [int] or None The parameters to be used for patch reshaping. The loaded patch is vectorized. Example: ``patch_reshape_parameters = [4, 8, 8]``, then the patch of the @@ -44,9 +45,10 @@ def reshape_flat_patches(patches, patch_reshape_parameters = None): patches are supported. Default: None. - **Returns:** + Returns + ------- - ``patches_3d`` : [2D or 3D :py:class:`numpy.ndarray`] + patches_3d : [2D or 3D :py:class:`numpy.ndarray`] A list of patches converted to the original dimensions. """ @@ -71,14 +73,16 @@ def combinations( input_dict ): """ Obtain all possible key-value combinations in the input dictionary. - **Parameters:** + Parameters + ---------- - ``input_dict`` : dict + input_dict : dict An input dictionary. - **Returns:** + Returns + ------- - ``combinations`` : [dict] + combinations : [dict] List of dictionaries containing the combinations. """ @@ -96,17 +100,19 @@ def apply_transform_as_pil(img_array, transform): Input image is in the Bob format. Before the transformation the input image is transformed to the PIL image. - **Parameters:** + Parameters + ---------- - ``img_array`` : 2D or 3D :py:class:`numpy.ndarray` + img_array : 2D or 3D :py:class:`numpy.ndarray` An input image / array. stored in Bob format for RGB images. - ``transform`` : torchvision.transforms.transforms.Compose + transform : torchvision.transforms.transforms.Compose Composed transfromation to be applied to the input image. - **Returns:** + Returns + ------- - ``features`` : Tensor + features : Tensor Transformed image. """ @@ -156,46 +162,98 @@ def _init_the_network(config_module): return model +def _transform(feature, config_module, color_input_flag): + """ + Apply transformation defined in the configuration module to the input data. + + Currently two types of the transformation are supported: + + First, Compose transformation of torchvision package. + + Second, custom transformation functions, to be applied to each feature + vector. For example, mean-std normalization. + + In both cases define transform() method in the ``config_module``. + + Parameters + ---------- + feature : :py:class:`numpy.ndarray` + ND feature array of the size (N_samples x dim1 x dim2 x ...). + + config_module : object + Module containing Network configuration parameters. + + color_input_flag : bool + If set to ``True``, the input is considered to be a color image of the + size ``(3, H, W)``. The tensor to be passed through the net will be + of the size ``(1, 3, H, W)``. + If set to ``False``, the input is considered to be a set of BW images + of the size ``(n_samples, H, W)``. The tensor to be passed through + the net will be of the size ``(n_samples, 1, H, W)``. + """ + + if "transform" in dir(config_module): + + if isinstance(config_module.transform, transforms.Compose): + + feature = apply_transform_as_pil(feature, config_module.transform) + + else: + + feature = np.stack([config_module.transform(item) for item in feature]) + + if color_input_flag: + # convert feature array to Tensor of size (1, 3, H, W) + feature_tensor = torch.Tensor(feature).unsqueeze(0) + + else: + # convert feature array to Tensor of size (n_samples, 1, H, W) + feature_tensor = torch.Tensor(feature).unsqueeze(1) + + return feature_tensor + + # ============================================================================= -def net_forward(feature, - config_file, - config_group, - model_file, - invert_scores_flag = False, - prediction_function = None, - color_input_flag = False): +def transform_and_net_forward(feature, + config_file, + config_group, + model_file, + color_input_flag = False): """ - **Parameters:** + This function performs the following steps: - ``feature`` : :py:class:`numpy.ndarray` + 1. Import config module. + + 2. Applies transformation defined in the config file to the input data. + + 3. Initializes the Network class with optional kwargs. + + 4. Pass the transformed data through ``forward()`` method of the Network + class. + + Parameters + ---------- + + feature : :py:class:`numpy.ndarray` ND feature array of the size (N_samples x dim1 x dim2 x ...). - ``config_file``: py:class:`string` + config_file: str Relative name of the config file defining the network, training data, and training parameters. The path should be relative to ``config_group``, for example: "autoencoder/netN.py". - ``config_group``: py:class:`string` + config_group : str Group/package name containing the configuration file. Usually all configs should be stored in this folder/place. For example: "bob.pad.face.config.pytorch". Both ``config_file`` and ``config_group`` are used to access the configuration module. - ``model_file`` : str + model_file : str A path to the model file to be used for network initialization. The network structure is defined in the config file. - ``invert_scores_flag`` : bool - If set to ``True`` output array will be multiplied by -1. - Default: ``False``. - - ``prediction_function`` : function - If defined, will be used insted of forward() method of the network - to compute the output. - Default: ``None``. - - ``color_input_flag`` : bool + color_input_flag : bool If set to ``True``, the input is considered to be a color image of the size ``(3, H, W)``. The tensor to be passed through the net will be of the size ``(1, 3, H, W)``. @@ -203,57 +261,46 @@ def net_forward(feature, of the size ``(n_samples, H, W)``. The tensor to be passed through the net will be of the size ``(n_samples, 1, H, W)``. - **Returns:** + Returns + ------- - ``net_output`` : [float] + net_output : [float] Output of the network per input sample/frame. """ + # ========================================================================= # Create relative module name given path: relative_mod_name = '.' + os.path.splitext(config_file)[0].replace(os.path.sep, '.') + # import configuration module: config_module = importlib.import_module(relative_mod_name, config_group) - # preprocess the features before passing to the NN: - - if "transform" in dir(config_module): - if isinstance(config_module.transform, transforms.Compose): + # ========================================================================= + # transform the input image or feature vector: + feature_tensor = _transform(feature, config_module, color_input_flag) - feature = apply_transform_as_pil(feature, config_module.transform) - - else: - - feature = np.stack([config_module.transform(item) for item in feature]) - - if color_input_flag: - # convert feature array to Tensor of size (1, 3, H, W) - feature_tensor = torch.Tensor(feature).unsqueeze(0) - - else: - # convert feature array to Tensor of size (n_samples, 1, H, W) - feature_tensor = torch.Tensor(feature).unsqueeze(1) + # ========================================================================= # Initialize the model local_model = _init_the_network(config_module) + # Load the pre-trained model into the network model_state = torch.load(model_file, map_location=lambda storage,loc:storage) # Initialize the state of the model: local_model.load_state_dict(model_state) - # Model is used for evaluation only + # Model is used for evaluation only: local_model.train(False) + + # ========================================================================= + # Pass the transformed feature vector through the network: output_tensor = local_model.forward(Variable(feature_tensor)) net_output = output_tensor.data.numpy().squeeze() net_output = net_output.flatten() - if invert_scores_flag: - - net_output = -1.*net_output - return net_output.astype(np.float) - -- GitLab From b61b412834d7b1945ee9db2a4686f7e00f9f04c6 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Tue, 29 Jan 2019 17:48:16 +0100 Subject: [PATCH 12/17] The renamed analog of net_forward() function is now hidden from the user in MultiNetPatchExtractor --- .../MultiNetPatchExtractor.py | 47 +++++++++++-------- bob/ip/pytorch_extractor/test.py | 13 ++--- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py index 707ad8c..e72516b 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py @@ -41,6 +41,10 @@ class MultiNetPatchExtractor(Extractor, object): The path should be relative to ``config_group``, for example: "autoencoder/net1_batl_3_layers_partial.py". + + ADD THE DOC on what should be in the config!!!!!!!!!!!!!!!!!!!!!! + + config_group: str Group/package name containing the configuration file. Usually all configs should be stored in this folder/place. @@ -48,21 +52,10 @@ class MultiNetPatchExtractor(Extractor, object): Both ``config_file`` and ``config_group`` are used to access the configuration module. - model_file : str - A path to the model file to be used for network initialization. + model_file : [str] + A list of paths to the model files to be used for network initialization. The network structure is defined in the config file. - function_kwargs : dict - - UPDATE THIS!!!! - - - Key-word arguments for the function defined by ``function_name``. - Note, that you can also specify one of the values in the dictionary - as a list containing multiple elements. Then, ``function_kwargs`` will - be different, for each patch you apply function, defined by - ``function_name``, to. See the ``__call__`` for more details. - patches_num : [int] A list of inices specifying which patches will be selected for processing/feature vector extraction. @@ -74,15 +67,24 @@ class MultiNetPatchExtractor(Extractor, object): size (256,) will be reshaped to (4,8,8) dimensions. Only 2D and 3D patches are supported. Default: None. + + color_input_flag : bool + If set to ``True``, the input is considered to be a color image of the + size ``(3, H, W)``. The tensor to be passed through the net will be + of the size ``(1, 3, H, W)``. + If set to ``False``, the input is considered to be a set of BW images + of the size ``(n_samples, H, W)``. The tensor to be passed through + the net will be of the size ``(n_samples, 1, H, W)``. + Default: ``False``. """ # ========================================================================= def __init__(self, config_file, config_group, model_file, - function_kwargs, patches_num, - patch_reshape_parameters = None): + patch_reshape_parameters = None, + color_input_flag = False): """ Init method. """ @@ -90,16 +92,16 @@ class MultiNetPatchExtractor(Extractor, object): super(MultiNetPatchExtractor, self).__init__(config_file = config_file, config_group = config_group, model_file = model_file, - function_kwargs = function_kwargs, patches_num = patches_num, - patch_reshape_parameters = patch_reshape_parameters) + patch_reshape_parameters = patch_reshape_parameters, + color_input_flag = color_input_flag) self.config_file = config_file self.config_group = config_group self.model_file = model_file - self.function_kwargs = function_kwargs self.patches_num = patches_num self.patch_reshape_parameters = patch_reshape_parameters + self.color_input_flag = color_input_flag # ========================================================================= @@ -121,8 +123,15 @@ class MultiNetPatchExtractor(Extractor, object): Feature vector. """ + # 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"] = self.color_input_flag + # convert all values in the dictionary to the list if not a list already: - function_kwargs = {k:[v] if not isinstance(v, list) else v for (k,v) in self.function_kwargs.items()} + function_kwargs = {k:[v] if not isinstance(v, list) else v for (k,v) in function_kwargs.items()} # compute all possible key-value combinations: function_kwargs = combinations(function_kwargs) # function_kwargs is now a list with kwargs diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index 0015204..410b139 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -72,23 +72,16 @@ def test_multi_net_patch_extractor(): MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] - # kwargs for the transform_and_net_forward function: - FUNCTION_KWARGS = {} - FUNCTION_KWARGS["config_file"] = CONFIG_FILE - FUNCTION_KWARGS["config_group"] = CONFIG_GROUP - FUNCTION_KWARGS["model_file"] = MODEL_FILE - FUNCTION_KWARGS["color_input_flag"] = True - PATCHES_NUM = [0] # patches to be used in the feature extraction process - PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network + COLOR_INPUT_FLAG = True image_extractor = MultiNetPatchExtractor(config_file = CONFIG_FILE, config_group = CONFIG_GROUP, model_file = MODEL_FILE, - function_kwargs = FUNCTION_KWARGS, patches_num = PATCHES_NUM, - patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS) + patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS, + color_input_flag = COLOR_INPUT_FLAG) # pass through encoder only, compute latent vector: latent_vector = image_extractor(patch_flat) -- GitLab From fc316fcd2820907703fe1d0af9affe5b3504d94e Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Wed, 30 Jan 2019 10:16:32 +0100 Subject: [PATCH 13/17] Updated the documentation of MultiNetPatchExtractor --- .../pytorch_extractor/MultiNetPatchExtractor.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py index e72516b..b822d79 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py @@ -37,13 +37,23 @@ class MultiNetPatchExtractor(Extractor, object): Attributes ----------- config_file: str - Relative name of the config file defining the network, and training parameters. + Relative name of the config file. The path should be relative to ``config_group``, for example: "autoencoder/net1_batl_3_layers_partial.py". + This file **must** contain at least the following definitions: - ADD THE DOC on what should be in the config!!!!!!!!!!!!!!!!!!!!!! + Function namely ``transform``, which is a Compose transformation of + torchvision package, to be applied to the input samples. + 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 want to use the latent embeddings of the autoencoder + class, set the kwargs accodingly. Note: in current extractor the + ``forward()`` method of the ``Network`` is used for feature extraction. config_group: str Group/package name containing the configuration file. Usually all @@ -163,3 +173,4 @@ class MultiNetPatchExtractor(Extractor, object): return features + -- GitLab From 4a357a02ca324d709104bcd11e06b38d4a80df6d Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Wed, 30 Jan 2019 11:49:16 +0100 Subject: [PATCH 14/17] Removed the network model used in the unit tests --- bob/ip/pytorch_extractor/test.py | 3 +-- ...del_pretrain_celeba_tune_batl_full_face.pth | Bin 101452 -> 0 bytes bob/ip/pytorch_extractor/utils.py | 7 ++++--- 3 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 bob/ip/pytorch_extractor/test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index 410b139..8f22535 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -69,8 +69,7 @@ def test_multi_net_patch_extractor(): CONFIG_GROUP = "bob.ip.pytorch_extractor" # use specific/unique model for each patch. Models pre-trained on CelebA and fine-tuned (3 layers) on BATL: - MODEL_FILE = [pkg_resources.resource_filename('bob.ip.pytorch_extractor', - 'test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth')] + MODEL_FILE = None PATCHES_NUM = [0] # patches to be used in the feature extraction process PATCH_RESHAPE_PARAMETERS = [3, 128, 128] # reshape vectorized patches to this dimensions before passing to the Network diff --git a/bob/ip/pytorch_extractor/test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth b/bob/ip/pytorch_extractor/test_data/conv_ae_model_pretrain_celeba_tune_batl_full_face.pth deleted file mode 100644 index 1cb97a261f2901a1632e50d651d1c136c8146da8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101452 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 z 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 diff --git a/bob/ip/pytorch_extractor/utils.py b/bob/ip/pytorch_extractor/utils.py index 5a6ece5..5cdc47c 100644 --- a/bob/ip/pytorch_extractor/utils.py +++ b/bob/ip/pytorch_extractor/utils.py @@ -286,10 +286,11 @@ def transform_and_net_forward(feature, local_model = _init_the_network(config_module) # Load the pre-trained model into the network - model_state = torch.load(model_file, map_location=lambda storage,loc:storage) + if model_file is not None: + model_state = torch.load(model_file, map_location=lambda storage,loc:storage) - # Initialize the state of the model: - local_model.load_state_dict(model_state) + # Initialize the state of the model: + local_model.load_state_dict(model_state) # Model is used for evaluation only: local_model.train(False) -- GitLab From 381520b900d2e482888fdd24544e733f3be15ed3 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Thu, 31 Jan 2019 11:09:06 +0100 Subject: [PATCH 15/17] Added a simple functionality allowing to load pre-trained models from urls --- .../MultiNetPatchExtractor.py | 44 +++++++++++++++++-- bob/ip/pytorch_extractor/test.py | 3 +- bob/ip/pytorch_extractor/utils.py | 39 ++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py index b822d79..3d1911f 100644 --- a/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py +++ b/bob/ip/pytorch_extractor/MultiNetPatchExtractor.py @@ -15,6 +15,7 @@ import numpy as np from bob.ip.pytorch_extractor.utils import reshape_flat_patches from bob.ip.pytorch_extractor.utils import combinations from bob.ip.pytorch_extractor.utils import transform_and_net_forward +from bob.ip.pytorch_extractor.utils import load_pretrained_model # ============================================================================= # Main body: @@ -86,6 +87,26 @@ class MultiNetPatchExtractor(Extractor, object): of the size ``(n_samples, H, W)``. The tensor to be passed through the net will be of the size ``(n_samples, 1, H, W)``. Default: ``False``. + + urls : [str] + List of URLs to download the pretrained models from. + If models are not available in the locations specified in the + ``model_file`` list, the system will try to download them from + ``urls``. The downloaded models **will be placed to the locations** + specified in ``model_file`` list. + + For example, the pretrained model for the autoencoder pre-trained on + RGB faces of the size (3(channels) x 128 x 128) and fine-tuned + on the BW-NIR-D data can be found here: + ["https://www.idiap.ch/software/bob/data/bob/bob.ip.pytorch_extractor/master/" + "conv_ae_model_pretrain_celeba_tune_batl_full_face.pth.tar.gz"] + + Default: None + + archive_extension : str + Extension of the archived files to download from above ``urls``. + + Default: '.tar.gz' """ # ========================================================================= @@ -94,7 +115,9 @@ class MultiNetPatchExtractor(Extractor, object): model_file, patches_num, patch_reshape_parameters = None, - color_input_flag = False): + color_input_flag = False, + urls = None, + archive_extension = '.tar.gz'): """ Init method. """ @@ -104,7 +127,9 @@ class MultiNetPatchExtractor(Extractor, object): model_file = model_file, patches_num = patches_num, patch_reshape_parameters = patch_reshape_parameters, - color_input_flag = color_input_flag) + color_input_flag = color_input_flag, + urls = urls, + archive_extension = archive_extension) self.config_file = config_file self.config_group = config_group @@ -112,6 +137,8 @@ class MultiNetPatchExtractor(Extractor, object): self.patches_num = patches_num self.patch_reshape_parameters = patch_reshape_parameters self.color_input_flag = color_input_flag + self.urls = urls + self.archive_extension = archive_extension # ========================================================================= @@ -154,15 +181,26 @@ class MultiNetPatchExtractor(Extractor, object): features_all_patches = [] + # make sure the model_file and urls are not None: + if self.model_file is None: + self.model_file = [self.model_file] + if self.urls is None: + self.urls = [self.urls] + for idx, patch in enumerate(patches_3d): + # try to load the model if not available, do nothing if available: + load_pretrained_model(model_path = self.model_file[self.patches_num[idx]], + url = self.urls[self.patches_num[idx]], + archive_extension = self.archive_extension) + if len(function_kwargs) == 1: # patches are passed through the same network: features = transform_and_net_forward(feature = patch, **function_kwargs[0]) else: # patches are passed through different networks: - features = transform_and_net_forward(feature = patch, **function_kwargs[self.patches_num(idx)]) + features = transform_and_net_forward(feature = patch, **function_kwargs[self.patches_num[idx]]) # print ("The model we use for patch {} is:".format(str(idx))) # print (function_kwargs[self.patches_num(idx)]["model_file"]) diff --git a/bob/ip/pytorch_extractor/test.py b/bob/ip/pytorch_extractor/test.py index 8f22535..950638f 100644 --- a/bob/ip/pytorch_extractor/test.py +++ b/bob/ip/pytorch_extractor/test.py @@ -80,7 +80,8 @@ def test_multi_net_patch_extractor(): model_file = MODEL_FILE, patches_num = PATCHES_NUM, patch_reshape_parameters = PATCH_RESHAPE_PARAMETERS, - color_input_flag = COLOR_INPUT_FLAG) + color_input_flag = COLOR_INPUT_FLAG, + urls = None) # pass through encoder only, compute latent vector: latent_vector = image_extractor(patch_flat) diff --git a/bob/ip/pytorch_extractor/utils.py b/bob/ip/pytorch_extractor/utils.py index 5cdc47c..fb64017 100644 --- a/bob/ip/pytorch_extractor/utils.py +++ b/bob/ip/pytorch_extractor/utils.py @@ -24,6 +24,10 @@ from torch.autograd import Variable import itertools as it +import bob.io.base + +from bob.extension.download import download_and_unzip + # ============================================================================= def reshape_flat_patches(patches, patch_reshape_parameters = None): @@ -287,6 +291,7 @@ def transform_and_net_forward(feature, # Load the pre-trained model into the network if model_file is not None: + model_state = torch.load(model_file, map_location=lambda storage,loc:storage) # Initialize the state of the model: @@ -305,3 +310,37 @@ def transform_and_net_forward(feature, net_output = net_output.flatten() return net_output.astype(np.float) + + +def load_pretrained_model(model_path, url, archive_extension = '.tar.gz'): + """ + Loads the model from the given ``url``, if the model specified in the + ``model_path`` is unavailable. The model will be saved to the location + defined in the ``model_path`` string, and will have the same filename. + + Arguments + --------- + model_path : str + Absolute file name pointing to the model. + + url : str + URL to download the model from. + + archive_extension : str + Extension of the archived file. Default: '.tar.gz' + """ + + if model_path is not None and url is not None: + + if not os.path.exists(model_path): + + print ("The model is not available at " + model_path) + print ("Trying to load it from " + url) + + bob.io.base.create_directories_safe(os.path.split(model_path)[0]) + + archive_file = os.path.join(os.path.split(model_path)[0], + os.path.splitext(os.path.split(model_path)[1])[0] + archive_extension) + + download_and_unzip(url, archive_file) + -- GitLab From 43ba333abe98376462497945208bd3c7220b8727 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Thu, 31 Jan 2019 11:56:34 +0100 Subject: [PATCH 16/17] Added an option to load the models without unzipping --- bob/ip/pytorch_extractor/utils.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/bob/ip/pytorch_extractor/utils.py b/bob/ip/pytorch_extractor/utils.py index fb64017..78ff2af 100644 --- a/bob/ip/pytorch_extractor/utils.py +++ b/bob/ip/pytorch_extractor/utils.py @@ -28,6 +28,8 @@ import bob.io.base from bob.extension.download import download_and_unzip +from bob.extension.download import download_file + # ============================================================================= def reshape_flat_patches(patches, patch_reshape_parameters = None): @@ -327,7 +329,12 @@ def load_pretrained_model(model_path, url, archive_extension = '.tar.gz'): URL to download the model from. archive_extension : str - Extension of the archived file. Default: '.tar.gz' + Extension of the archived file. + + If ``archive_extension`` is ``None`` the model is downloaded without + de-archivation. + + Default: '.tar.gz' """ if model_path is not None and url is not None: @@ -339,8 +346,13 @@ def load_pretrained_model(model_path, url, archive_extension = '.tar.gz'): bob.io.base.create_directories_safe(os.path.split(model_path)[0]) - archive_file = os.path.join(os.path.split(model_path)[0], - os.path.splitext(os.path.split(model_path)[1])[0] + archive_extension) + if archive_extension is None: # if file is not an archive, download it + + download_file(url, model_path) + + else: # download and de-archivate + + archive_file = os.path.splitext(model_path)[0] + archive_extension - download_and_unzip(url, archive_file) + download_and_unzip(url, archive_file) -- GitLab From 6c352a8d8db1a69edd68a8a355433836d4d92a03 Mon Sep 17 00:00:00 2001 From: Olegs NIKISINS Date: Tue, 5 Feb 2019 16:17:07 +0100 Subject: [PATCH 17/17] Removed pth from MANIFEST.in --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 955314e..666455f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,3 @@ include README.rst buildout.cfg develop.cfg COPYING version.txt requirements.txt recursive-include doc *.py *.rst -recursive-include bob/ip/pytorch_extractor *.pth + -- GitLab