Skip to content
Snippets Groups Projects
Commit a1d08d1b authored by Tiago de Freitas Pereira's avatar Tiago de Freitas Pereira
Browse files

Implemented S-Norm score normalization

parent b72b8022
No related branches found
No related tags found
2 merge requests!190Implementation of S-norm,!180[dask] Preparing bob.bio.base for dask pipelines
Pipeline #40127 passed
......@@ -110,6 +110,7 @@ class ZTNormPipeline(object):
return z_normed_scores
# T NORM
t_normed_scores, t_scores, t_biometric_references = self.compute_tnorm_scores(
t_biometric_reference_samples,
probe_features,
......@@ -128,8 +129,14 @@ class ZTNormPipeline(object):
t_scores,
allow_scoring_with_all_biometric_references,
)
# S-norm
s_normed_scores = self.compute_snorm_scores(z_normed_scores, t_normed_scores)
return raw_scores, z_normed_scores, t_normed_scores, zt_normed_scores
return raw_scores, z_normed_scores, t_normed_scores, zt_normed_scores, s_normed_scores
def train_background_model(self, background_model_samples):
return self.vanilla_biometrics_pipeline.train_background_model(
......@@ -227,6 +234,19 @@ class ZTNormPipeline(object):
return zt_normed_scores
def compute_snorm_scores(
self,
znormed_scores,
tnormed_scores
):
s_normed_scores = self.ztnorm_solver.compute_snorm_scores(
znormed_scores, tnormed_scores
)
return s_normed_scores
def write_scores(self, scores):
return self.vanilla_biometrics_pipeline.write_scores(scores)
......@@ -395,6 +415,33 @@ class ZTNorm(object):
return self._tnorm_samplesets(probe_scores, stats)
def _snorm(self, z_score, t_score):
return 0.5*(z_score + t_score)
def _snorm_samplesets(self, znormed_scores, tnormed_scores):
s_normed_samplesets = []
for z, t in zip(znormed_scores, tnormed_scores):
s_normed_scores = SampleSet([], parent=z)
for b_z, b_t in zip(z, t):
score = self._snorm(b_z.data, b_t.data)
new_sample = Sample(score, parent=b_z)
s_normed_scores.samples.append(new_sample)
s_normed_samplesets.append(s_normed_scores)
return s_normed_samplesets
def compute_snorm_scores(
self,
znormed_scores,
tnormed_scores
):
return self._snorm_samplesets(znormed_scores, tnormed_scores)
class ZTNormDaskWrapper(object):
"""
Wrap :any:`ZTNorm` to work with DASK
......@@ -435,6 +482,13 @@ class ZTNormDaskWrapper(object):
return probe_scores.map_partitions(self.ztnorm._tnorm_samplesets, stats)
def compute_snorm_scores(
self,
znormed_scores,
tnormed_scores
):
return znormed_scores.map_partitions(self.ztnorm._snorm_samplesets, tnormed_scores)
class ZTNormCheckpointWrapper(object):
"""
......@@ -488,6 +542,29 @@ class ZTNormCheckpointWrapper(object):
return z_normed_score
def _apply_tnorm(self, probe_score, stats):
path = os.path.join(self.tnorm_score_path, str(probe_score.key) + ".pkl")
if self.force or not os.path.exists(path):
t_normed_score = self.ztnorm._apply_tnorm(probe_score, path)
self.write_scores(t_normed_score.samples)
t_normed_score = SampleSet(
[
DelayedSample(
functools.partial(self._load, path), parent=probe_score
)
],
parent=probe_score,
)
else:
t_normed_score = SampleSet(self._load(path), parent=probe_score)
return t_normed_score
def compute_znorm_scores(
self, probe_scores, sampleset_for_znorm, biometric_references
):
......@@ -499,11 +576,18 @@ class ZTNormCheckpointWrapper(object):
def compute_tnorm_scores(
self, probe_scores, sampleset_for_tnorm, t_biometric_references
):
return self.ztnorm.compute_tnorm_scores(
probe_scores, sampleset_for_tnorm, t_biometric_references
)
def compute_snorm_scores(
self,
znormed_scores,
tnormed_scores
):
return self.ztnorm.compute_snorm_scores(znormed_scores, tnormed_scores)
def _compute_stats(self, sampleset_for_norm, biometric_references, axis=0):
return self.ztnorm._compute_stats(
sampleset_for_norm, biometric_references, axis=axis
......@@ -514,3 +598,6 @@ class ZTNormCheckpointWrapper(object):
def _tnorm_samplesets(self, probe_scores, stats):
return self.ztnorm._tnorm_samplesets(probe_scores, stats)
def _snorm_samplesets(self, probe_scores, stats):
return self.ztnorm._snorm_samplesets(probe_scores, stats)
......@@ -127,7 +127,11 @@ def zt_norm_stubs(references, probes, t_references, z_probes):
zt_normed_scores = _norm(z_normed_scores, z_t_scores, axis=0)
assert zt_normed_scores.shape == (n_reference, n_probes)
return raw_scores, z_normed_scores, t_normed_scores, zt_normed_scores
s_normed_scores = (z_normed_scores+t_normed_scores)*0.5
assert s_normed_scores.shape == (n_reference, n_probes)
return raw_scores, z_normed_scores, t_normed_scores, zt_normed_scores, s_normed_scores
def test_norm_mechanics():
......@@ -191,6 +195,7 @@ def test_norm_mechanics():
z_normed_scores_ref,
t_normed_scores_ref,
zt_normed_scores_ref,
s_normed_scores_ref,
) = zt_norm_stubs(references, probes, t_references, z_probes)
############
......@@ -338,6 +343,7 @@ def test_norm_mechanics():
z_normed_score_samples,
t_normed_score_samples,
zt_normed_score_samples,
s_normed_score_samples,
) = zt_vanilla_pipeline(
[],
biometric_reference_sample_sets,
......@@ -360,6 +366,11 @@ def test_norm_mechanics():
scheduler="single-threaded"
)
s_normed_score_samples = s_normed_score_samples.compute(
scheduler="single-threaded"
)
raw_scores = _dump_scores_from_samples(
raw_score_samples, shape=(n_probes, n_references)
)
......@@ -380,6 +391,14 @@ def test_norm_mechanics():
)
assert np.allclose(zt_normed_scores, zt_normed_scores_ref)
s_normed_scores = _dump_scores_from_samples(
s_normed_score_samples, shape=(n_probes, n_references)
)
assert np.allclose(s_normed_scores, s_normed_scores_ref)
# No dask
run(False) # On memory
......@@ -418,7 +437,7 @@ def test_znorm_on_memory():
vanilla_biometrics_pipeline, npartitions=2
)
raw_scores, z_scores, t_scores, zt_scores = vanilla_biometrics_pipeline(
raw_scores, z_scores, t_scores, zt_scores, s_scores = vanilla_biometrics_pipeline(
database.background_model_samples(),
database.references(),
database.probes(),
......@@ -448,15 +467,22 @@ def test_znorm_on_memory():
t_scores = _concatenate(
vanilla_biometrics_pipeline, t_scores, "scores-dev_tscores"
)
zt_scores = _concatenate(
vanilla_biometrics_pipeline, zt_scores, "scores-dev_ztscores"
)
s_scores = _concatenate(
vanilla_biometrics_pipeline, s_scores, "scores-dev_sscores"
)
if with_dask:
raw_scores = raw_scores.compute(scheduler="single-threaded")
z_scores = z_scores.compute(scheduler="single-threaded")
t_scores = t_scores.compute(scheduler="single-threaded")
zt_scores = zt_scores.compute(scheduler="single-threaded")
s_scores = s_scores.compute(scheduler="single-threaded")
if isinstance(score_writer, CSVScoreWriter):
n_lines = 51 if with_dask else 101
......@@ -465,12 +491,14 @@ def test_znorm_on_memory():
assert len(open(z_scores[0], "r").readlines()) == n_lines
assert len(open(t_scores[0], "r").readlines()) == n_lines
assert len(open(zt_scores[0], "r").readlines()) == n_lines
assert len(open(s_scores[0], "r").readlines()) == n_lines
else:
assert len(raw_scores) == 10
assert len(z_scores) == 10
assert len(t_scores) == 10
assert len(zt_scores) == 10
assert len(s_scores) == 10
run_pipeline(False)
run_pipeline(False) # Testing checkpoint
......
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