Source code for facereclib.tools.ISV

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Manuel Guenther <Manuel.Guenther@idiap.ch>

import bob.core
import bob.io.base
import bob.learn.em

import numpy
import types

from .Tool import Tool
from .UBMGMM import UBMGMM
from .. import utils


[docs]class ISV (UBMGMM): """Tool for computing Unified Background Models and Gaussian Mixture Models of the features""" def __init__( self, # ISV training subspace_dimension_of_u, # U subspace dimension isv_training_iterations = 10, # Number of EM iterations for the ISV training # ISV enrollment isv_enroll_iterations = 1, # Number of iterations for the enrollment phase multiple_probe_scoring = None, # scoring when multiple probe files are available # parameters of the GMM **kwargs ): """Initializes the local UBM-GMM tool with the given file selector object""" # call base class constructor with its set of parameters UBMGMM.__init__(self, **kwargs) # call tool constructor to overwrite what was set before Tool.__init__( self, performs_projection = True, use_projected_features_for_enrollment = True, requires_enroller_training = False, # not needed anymore because it's done while training the projector split_training_features_by_client = True, subspace_dimension_of_u = subspace_dimension_of_u, isv_training_iterations = isv_training_iterations, isv_enroll_iterations = isv_enroll_iterations, multiple_model_scoring = None, multiple_probe_scoring = multiple_probe_scoring, **kwargs ) self.m_subspace_dimension_of_u = subspace_dimension_of_u self.m_isv_training_iterations = isv_training_iterations self.m_isv_enroll_iterations = isv_enroll_iterations def _train_isv(self, data): """Train the ISV model given a dataset""" utils.info(" -> Training ISV enroller") self.m_isvbase = bob.learn.em.ISVBase(self.m_ubm, self.m_subspace_dimension_of_u) # train ISV model trainer = bob.learn.em.ISVTrainer(self.m_relevance_factor) bob.learn.em.train(trainer, self.m_isvbase, data, self.m_isv_training_iterations, rng=self.m_rng)
[docs] def train_projector(self, train_features, projector_file): """Train Projector and Enroller at the same time""" data1 = numpy.vstack([feature for client in train_features for feature in client]) UBMGMM._train_projector_using_array(self, data1) # to save some memory, we might want to delete these data del data1 # project training data utils.info(" -> Projecting training data") data = [] for client_features in train_features: list = [] for feature in client_features: # Initializes GMMStats object self.m_gmm_stats = bob.learn.em.GMMStats(*self.m_ubm.shape) list.append(UBMGMM.project(self, feature)) data.append(list) # train ISV self._train_isv(data) # Save the ISV base AND the UBM into the same file self.save_projector(projector_file)
[docs] def save_projector(self, projector_file): """Save the GMM and the ISV model in the same HDF5 file""" hdf5file = bob.io.base.HDF5File(projector_file, "w") hdf5file.create_group('Projector') hdf5file.cd('Projector') self.m_ubm.save(hdf5file) hdf5file.cd('/') hdf5file.create_group('Enroller') hdf5file.cd('Enroller') self.m_isvbase.save(hdf5file)
[docs] def load_isv(self, isv_file): hdf5file = bob.io.base.HDF5File(isv_file) self.m_isvbase = bob.learn.em.ISVBase(hdf5file) # add UBM model from base class self.m_isvbase.ubm = self.m_ubm
[docs] def load_projector(self, projector_file): """Load the GMM and the ISV model from the same HDF5 file""" hdf5file = bob.io.base.HDF5File(projector_file) # Load Projector hdf5file.cd('/Projector') self.load_ubm(hdf5file) # Load Enroller hdf5file.cd('/Enroller') self.load_isv(hdf5file) self.m_machine = bob.learn.em.ISVMachine(self.m_isvbase) self.m_trainer = bob.learn.em.ISVTrainer(self.m_relevance_factor) self.m_rng = bob.core.random.mt19937(self.m_init_seed)
####################################################### ################ ISV training #########################
[docs] def project_isv(self, projected_ubm): projected_isv = numpy.ndarray(shape=(self.m_ubm.shape[0]*self.m_ubm.shape[1],), dtype=numpy.float64) model = bob.learn.em.ISVMachine(self.m_isvbase) model.estimate_ux(projected_ubm, projected_isv) return projected_isv
[docs] def project(self, feature_array): """Computes GMM statistics against a UBM, then corresponding Ux vector""" projected_ubm = UBMGMM.project(self,feature_array) projected_isv = self.project_isv(projected_ubm) return [bob.learn.em.GMMStats(projected_ubm), projected_isv]
####################################################### ################## ISV model enroll ####################
[docs] def save_feature(self, data, feature_file): gmmstats = data[0] Ux = data[1] hdf5file = bob.io.base.HDF5File(feature_file, "w") if isinstance(feature_file, str) else feature_file hdf5file.create_group('gmmstats') hdf5file.cd('gmmstats') gmmstats.save(hdf5file) hdf5file.cd('..') hdf5file.set('Ux', Ux)
[docs] def read_feature(self, feature_file): """Read the type of features that we require, namely GMMStats""" hdf5file = bob.io.base.HDF5File(feature_file) hdf5file.cd('gmmstats') gmmstats = bob.learn.em.GMMStats(hdf5file) return gmmstats
[docs] def enroll(self, enroll_features): """Performs ISV enrollment""" self.m_trainer.enroll(self.m_machine, enroll_features, self.m_isv_enroll_iterations) # return the resulting gmm return self.m_machine
###################################################### ################ Feature comparison ##################
[docs] def read_model(self, model_file): """Reads the ISV Machine that holds the model""" machine = bob.learn.em.ISVMachine(bob.io.base.HDF5File(model_file)) machine.isv_base = self.m_isvbase return machine
[docs] def read_probe(self, probe_file): """Read the type of features that we require, namely GMMStats""" hdf5file = bob.io.base.HDF5File(probe_file) hdf5file.cd('gmmstats') gmmstats = bob.learn.em.GMMStats(hdf5file) hdf5file.cd('..') Ux = hdf5file.read('Ux') return [gmmstats, Ux]
[docs] def score(self, model, probe): """Computes the score for the given model and the given probe.""" gmmstats = probe[0] Ux = probe[1] return model.forward_ux(gmmstats, Ux)
[docs] def score_for_multiple_probes(self, model, probes): """This function computes the score between the given model and several given probe files.""" if self.m_probe_fusion_function is not None: # When a multiple probe fusion function is selected, use it return Tool.score_for_multiple_probes(self, model, probes) else: # Otherwise: compute joint likelihood of all probe features # create GMM statistics from first probe statistics gmmstats_acc = bob.learn.em.GMMStats(probes[0][0]) # add all other probe statistics for i in range(1,len(probes)): gmmstats_acc += probes[i][0] # compute ISV score with the accumulated statistics projected_isv_acc = numpy.ndarray(shape=(self.m_ubm.shape[0]*self.m_ubm.shape[1],), dtype=numpy.float64) model.estimate_ux(gmmstats_acc, projected_isv_acc) return model.forward_ux(gmmstats_acc, projected_isv_acc)