Source code for bob.bio.gmm.algorithm.JFA

#!/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


from .GMM import GMM
from bob.bio.base.algorithm import Algorithm

import logging
logger = logging.getLogger("bob.bio.gmm")

class JFA (GMM):
  """Tool for computing Unified Background Models and Gaussian Mixture Models of the features and project it via JFA"""

  def __init__(
      self,
      # JFA training
      subspace_dimension_of_u,       # U subspace dimension
      subspace_dimension_of_v,       # V subspace dimension
      jfa_training_iterations = 10,  # Number of EM iterations for the JFA training
      # JFA enrollment
      jfa_enroll_iterations = 1,     # Number of iterations for the enrollment phase
      # parameters of the GMM
      **kwargs
  ):
    """Initializes the local UBM-GMM tool with the given file selector object"""
    # call base class constructor
    GMM.__init__(self, **kwargs)

    # call tool constructor to overwrite what was set before
    Algorithm.__init__(
        self,
        performs_projection = True,
        use_projected_features_for_enrollment = True,
        requires_enroller_training = True,

        subspace_dimension_of_u = subspace_dimension_of_u,
        subspace_dimension_of_v = subspace_dimension_of_v,
        jfa_training_iterations = jfa_training_iterations,
        jfa_enroll_iterations = jfa_enroll_iterations,

        multiple_model_scoring = None,
        multiple_probe_scoring = None,
        **kwargs
    )

    self.subspace_dimension_of_u = subspace_dimension_of_u
    self.subspace_dimension_of_v = subspace_dimension_of_v
    self.jfa_training_iterations = jfa_training_iterations
    self.jfa_enroll_iterations = jfa_enroll_iterations
    self.jfa_trainer = bob.learn.em.JFATrainer()


[docs] def load_projector(self, projector_file): """Reads the UBM model from file""" # Here, we just need to load the UBM from the projector file. self.load_ubm(projector_file)
####################################################### ################ JFA training #########################
[docs] def train_enroller(self, train_features, enroller_file): # assert that all training features are GMMStatistics for client_feature in train_features: for feature in client_feature: assert isinstance(feature, bob.learn.em.GMMStats) # create a JFABasemachine with the UBM from the base class self.jfa_base = bob.learn.em.JFABase(self.ubm, self.subspace_dimension_of_u, self.subspace_dimension_of_v) # train the JFA bob.learn.em.train_jfa(self.jfa_trainer, self.jfa_base, train_features, self.jfa_training_iterations, rng = bob.core.random.mt19937(self.init_seed)) # Save the JFA base AND the UBM into the same file self.jfa_base.save(bob.io.base.HDF5File(enroller_file, "w"))
####################################################### ################## JFA model enroll ####################
[docs] def load_enroller(self, enroller_file): """Reads the JFA base from file""" # now, load the JFA base, if it is included in the file self.jfa_base = bob.learn.em.JFABase(bob.io.base.HDF5File(enroller_file)) # add UBM model from base class self.jfa_base.ubm = self.ubm
# TODO: Why is the rng re-initialized here? #self.rng = bob.core.random.mt19937(self.init_seed)
[docs] def read_feature(self, feature_file): """Reads the projected feature to be enrolled as a model""" return bob.learn.em.GMMStats(bob.io.base.HDF5File(feature_file))
[docs] def enroll(self, enroll_features): """Enrolls a GMM using MAP adaptation""" machine = bob.learn.em.JFAMachine(self.jfa_base) self.jfa_trainer.enroll(machine, enroll_features, self.jfa_enroll_iterations) # return the resulting gmm return machine
###################################################### ################ Feature comparison ##################
[docs] def read_model(self, model_file): """Reads the JFA Machine that holds the model""" machine = bob.learn.em.JFAMachine(bob.io.base.HDF5File(model_file)) machine.jfa_base = self.jfa_base return machine
read_probe = read_feature
[docs] def score(self, model, probe): """Computes the score for the given model and the given probe""" assert isinstance(model, bob.learn.em.JFAMachine) assert isinstance(probe, bob.learn.em.GMMStats) return model.log_likelihood(probe)
[docs] def score_for_multiple_probes(self, model, probes): """This function computes the score between the given model and several probes.""" # TODO: Check if this is correct # logger.warn("This function needs to be verified!") raise NotImplementedError('Multiple probes is not yet supported')
#scores = numpy.ndarray((len(probes),), 'float64') #model.forward(probes, scores) #return scores[0]