Skip to content
Snippets Groups Projects
Commit f91e4f8c authored by Manuel Günther's avatar Manuel Günther
Browse files

Improved tests for PCA and LDA

parent 6b585852
No related branches found
No related tags found
No related merge requests found
...@@ -49,8 +49,8 @@ class Algorithm: ...@@ -49,8 +49,8 @@ class Algorithm:
self.split_training_features_by_client = split_training_features_by_client self.split_training_features_by_client = split_training_features_by_client
self.use_projected_features_for_enrollment = performs_projection and use_projected_features_for_enrollment self.use_projected_features_for_enrollment = performs_projection and use_projected_features_for_enrollment
self.requires_enroller_training = requires_enroller_training self.requires_enroller_training = requires_enroller_training
self.m_model_fusion_function = utils.score_fusion_strategy(multiple_model_scoring) self.model_fusion_function = utils.score_fusion_strategy(multiple_model_scoring)
self.m_probe_fusion_function = utils.score_fusion_strategy(multiple_probe_scoring) self.probe_fusion_function = utils.score_fusion_strategy(multiple_probe_scoring)
self._kwargs = kwargs self._kwargs = kwargs
self._kwargs.update({'multiple_model_scoring':multiple_model_scoring, 'multiple_probe_scoring':multiple_probe_scoring}) self._kwargs.update({'multiple_model_scoring':multiple_model_scoring, 'multiple_probe_scoring':multiple_probe_scoring})
...@@ -80,9 +80,9 @@ class Algorithm: ...@@ -80,9 +80,9 @@ class Algorithm:
and fuses the scores using the fusion method specified in the constructor of this class. and fuses the scores using the fusion method specified in the constructor of this class.
Usually this function is called from derived class 'score' functions.""" Usually this function is called from derived class 'score' functions."""
if isinstance(models, list): if isinstance(models, list):
return self.m_model_fusion_function([self.score(model, probe) for model in models]) return self.model_fusion_function([self.score(model, probe) for model in models])
elif isinstance(models, numpy.ndarray): elif isinstance(models, numpy.ndarray):
return self.m_model_fusion_function([self.score(models[i,:], probe) for i in range(models.shape[0])]) return self.model_fusion_function([self.score(models[i,:], probe) for i in range(models.shape[0])])
else: else:
raise ValueError("The model does not have the desired format (list, array, ...)") raise ValueError("The model does not have the desired format (list, array, ...)")
...@@ -92,7 +92,7 @@ class Algorithm: ...@@ -92,7 +92,7 @@ class Algorithm:
In this base class implementation, it computes the scores for each probe file using the 'score' method, In this base class implementation, it computes the scores for each probe file using the 'score' method,
and fuses the scores using the fusion method specified in the constructor of this class.""" and fuses the scores using the fusion method specified in the constructor of this class."""
if isinstance(probes, list): if isinstance(probes, list):
return self.m_probe_fusion_function([self.score(model, probe) for probe in probes]) return self.probe_fusion_function([self.score(model, probe) for probe in probes])
else: else:
# only one probe feature -> use the default scoring function # only one probe feature -> use the default scoring function
return self.score(model, probes) return self.score(model, probes)
......
...@@ -54,10 +54,13 @@ class LDA (Algorithm): ...@@ -54,10 +54,13 @@ class LDA (Algorithm):
self.uses_variances = uses_variances self.uses_variances = uses_variances
def _check_feature(self, feature): def _check_feature(self, feature, projected=False):
"""Checks that the features are appropriate""" """Checks that the features are appropriate"""
if not isinstance(feature, numpy.ndarray) or len(feature.shape) != 1 or feature.dtype != numpy.float64: if not isinstance(feature, numpy.ndarray) or len(feature.shape) != 1 or feature.dtype != numpy.float64:
raise ValueError("The given feature is not appropriate") raise ValueError("The given feature is not appropriate")
index = 1 if projected else 0
if self.machine is not None and feature.shape[0] != self.machine.shape[index]:
raise ValueError("The given feature is expected to have %d elements, but it has %d" % (self.machine.shape[index], feature.shape[0]))
def _arrange_data(self, training_files): def _arrange_data(self, training_files):
...@@ -164,13 +167,14 @@ class LDA (Algorithm): ...@@ -164,13 +167,14 @@ class LDA (Algorithm):
def enroll(self, enroll_features): def enroll(self, enroll_features):
"""Enrolls the model by storing all given input vectors""" """Enrolls the model by storing all given input vectors"""
assert len(enroll_features) assert len(enroll_features)
[self._check_feature(feature) for feature in enroll_features] [self._check_feature(feature, True) for feature in enroll_features]
# just store all the features # just store all the features
return numpy.vstack(enroll_features) return numpy.vstack(enroll_features)
def score(self, model, probe): def score(self, model, probe):
"""Computes the distance of the model to the probe using the distance function""" """Computes the distance of the model to the probe using the distance function"""
self._check_feature(probe, True)
# return the negative distance (as a similarity measure) # return the negative distance (as a similarity measure)
if len(model.shape) == 2: if len(model.shape) == 2:
# we have multiple models, so we use the multiple model scoring # we have multiple models, so we use the multiple model scoring
......
...@@ -46,10 +46,13 @@ class PCA (Algorithm): ...@@ -46,10 +46,13 @@ class PCA (Algorithm):
self.uses_variances = uses_variances self.uses_variances = uses_variances
def _check_feature(self, feature): def _check_feature(self, feature, projected=False):
"""Checks that the features are appropriate""" """Checks that the features are appropriate"""
if not isinstance(feature, numpy.ndarray) or len(feature.shape) != 1 or feature.dtype != numpy.float64: if not isinstance(feature, numpy.ndarray) or len(feature.shape) != 1 or feature.dtype != numpy.float64:
raise ValueError("The given feature is not appropriate") raise ValueError("The given feature is not appropriate")
index = 1 if projected else 0
if self.machine is not None and feature.shape[0] != self.machine.shape[index]:
raise ValueError("The given feature is expected to have %d elements, but it has %d" % (self.machine.shape[index], feature.shape[0]))
def train_projector(self, training_features, projector_file): def train_projector(self, training_features, projector_file):
...@@ -104,13 +107,14 @@ class PCA (Algorithm): ...@@ -104,13 +107,14 @@ class PCA (Algorithm):
def enroll(self, enroll_features): def enroll(self, enroll_features):
"""Enrolls the model by storing all given input vectors""" """Enrolls the model by storing all given input vectors"""
assert len(enroll_features) assert len(enroll_features)
[self._check_feature(feature) for feature in enroll_features] [self._check_feature(feature, True) for feature in enroll_features]
# just store all the features # just store all the features
return numpy.vstack(enroll_features) return numpy.vstack(enroll_features)
def score(self, model, probe): def score(self, model, probe):
"""Computes the distance of the model to the probe using the distance function""" """Computes the distance of the model to the probe using the distance function"""
self._check_feature(probe, True)
# return the negative distance (as a similarity measure) # return the negative distance (as a similarity measure)
if len(model.shape) == 2: if len(model.shape) == 2:
# we have multiple models, so we use the multiple model scoring # we have multiple models, so we use the multiple model scoring
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment