From f147e798418151d359718b6ea9d60468864b33fb Mon Sep 17 00:00:00 2001 From: Pavel Korshunov Date: Thu, 28 Sep 2017 00:35:25 +0200 Subject: [PATCH 1/5] allow missing files projector --- bob/pad/base/tools/algorithm.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/bob/pad/base/tools/algorithm.py b/bob/pad/base/tools/algorithm.py index 6a52b9b..f8ee01b 100644 --- a/bob/pad/base/tools/algorithm.py +++ b/bob/pad/base/tools/algorithm.py @@ -115,13 +115,31 @@ def project(algorithm, extractor, groups=None, indices=None, allow_missing_files feature_file = str(feature_files[i]) projected_file = str(projected_files[i]) + if not os.path.exists(feature_file): + if allow_missing_files: + logger.debug("... Cannot find extracted feature file %s; skipping", feature_file) + continue + else: + logger.error("Cannot find extracted feature file %s", feature_file) + if not utils.check_file(projected_file, force, 1000): - logger.info("- Projection: projecting file: %s", feature_file) + logger.debug("... Projecting features for file '%s'", feature_file) + # load feature feature = extractor.read_feature(feature_file) # project feature projected = algorithm.project(feature) + + if projected is None: + if allow_missing_files: + logger.debug("... Projection for extracted file %s failed; skipping", feature_file) + continue + else: + raise RuntimeError("Projection of file '%s' was not successful" % feature_file) # write it bob.io.base.create_directories_safe(os.path.dirname(projected_file)) algorithm.write_feature(projected, projected_file) + else: + logger.debug("... Skipping feature file '%s' since projected file '%s' exists", feature_file, projected_file) + -- GitLab From bf936a428eac5f569c567bbd4009cf2483b54fbf Mon Sep 17 00:00:00 2001 From: Pavel Korshunov Date: Thu, 28 Sep 2017 10:07:05 +0200 Subject: [PATCH 2/5] allow missing files projector --- bob/pad/base/tools/scoring.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/bob/pad/base/tools/scoring.py b/bob/pad/base/tools/scoring.py index 7c5639a..2aa81a7 100644 --- a/bob/pad/base/tools/scoring.py +++ b/bob/pad/base/tools/scoring.py @@ -22,20 +22,26 @@ from .FileSelector import FileSelector from bob.bio.base import utils -def _compute_scores(algorithm, toscore_objects): - """Compute scores for the given list of objectis using provided algorithm. +def _compute_scores(algorithm, toscore_objects, allow_missing_files): + """Compute scores for the given list of objects using provided algorithm. """ - # the scores to be computed - scores = [] + # the scores to be computed; initialized with NaN + scores = numpy.ones((1, len(toscore_objects)), numpy.float64) * numpy.nan + scores = numpy.reshape(scores, [len(toscore_objects)]) + # Loops over the toscore sets for i, toscore_element in enumerate(toscore_objects): + # filter missing files + if allow_missing_files and not os.path.exists(toscore_element): + # we keep the NaN score + continue # read toscore toscore = algorithm.read_toscore_object(toscore_element) # compute score if isinstance(toscore, list) or isinstance(toscore[0], numpy.ndarray): - scores.insert(i, algorithm.score_for_multiple_projections(toscore)) + scores[i] = algorithm.score_for_multiple_projections(toscore) else: - scores.insert(i, algorithm.score(toscore)) + scores[i] = algorithm.score(toscore) # Returns the scores return scores @@ -100,8 +106,11 @@ def _save_scores(score_file, scores, toscore_objects, write_compressed=False): for i, toscore_object in enumerate(toscore_objects): id_str = (str(toscore_object.client_id)).zfill(3) sample_name = str(toscore_object.make_path()) + + # scores[i] is a list, so + # each sample is allowed to have multiple scores for score in scores[i]: - if not toscore_object.attack_type or toscore_object.attack_type=="None": + if not toscore_object.attack_type or toscore_object.attack_type == "None": _write(f, "%s %s %s %.12f\n" % (id_str, id_str, sample_name, score), write_compressed) else: attackname = toscore_object.attack_type @@ -110,7 +119,7 @@ def _save_scores(score_file, scores, toscore_objects, write_compressed=False): _close_written(score_file, f, write_compressed) -def _scores_all(algorithm, group, force, write_compressed=False): +def _scores_all(algorithm, group, force, allow_missing_files=False, write_compressed=False): """Computes scores for all (real, attack) files in a given group using the provided algorithm.""" # the file selector object fs = FileSelector.instance() @@ -136,7 +145,7 @@ def _scores_all(algorithm, group, force, write_compressed=False): # get the attack files current_files = fs.get_paths(current_objects, 'projected' if algorithm.performs_projection else 'extracted') # compute scores for the list of File objects - cur_scores = _compute_scores(algorithm, current_files) + cur_scores = _compute_scores(algorithm, current_files, allow_missing_files) total_scores += cur_scores # Save scores to text file _save_scores(score_file, cur_scores, current_objects, write_compressed) @@ -175,4 +184,4 @@ def compute_scores(algorithm, force=False, groups=['dev', 'eval'], allow_missing algorithm.load_projector(fs.projector_file) for group in groups: - _scores_all(algorithm, group, force, write_compressed) + _scores_all(algorithm, group, force, allow_missing_files, write_compressed) -- GitLab From d6e7ca120bb8f1c5a8a928b101f88fe51bc3acd1 Mon Sep 17 00:00:00 2001 From: Pavel Korshunov Date: Thu, 28 Sep 2017 10:36:05 +0200 Subject: [PATCH 3/5] allow missing files scoring --- bob/pad/base/tools/scoring.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bob/pad/base/tools/scoring.py b/bob/pad/base/tools/scoring.py index 2aa81a7..aa5a53c 100644 --- a/bob/pad/base/tools/scoring.py +++ b/bob/pad/base/tools/scoring.py @@ -25,9 +25,8 @@ from bob.bio.base import utils def _compute_scores(algorithm, toscore_objects, allow_missing_files): """Compute scores for the given list of objects using provided algorithm. """ - # the scores to be computed; initialized with NaN - scores = numpy.ones((1, len(toscore_objects)), numpy.float64) * numpy.nan - scores = numpy.reshape(scores, [len(toscore_objects)]) + # the scores to be computed + scores = [] # Loops over the toscore sets for i, toscore_element in enumerate(toscore_objects): @@ -39,9 +38,9 @@ def _compute_scores(algorithm, toscore_objects, allow_missing_files): toscore = algorithm.read_toscore_object(toscore_element) # compute score if isinstance(toscore, list) or isinstance(toscore[0], numpy.ndarray): - scores[i] = algorithm.score_for_multiple_projections(toscore) + scores.insert(i, algorithm.score_for_multiple_projections(toscore)) else: - scores[i] = algorithm.score(toscore) + scores.insert(i, algorithm.score(toscore)) # Returns the scores return scores @@ -107,6 +106,10 @@ def _save_scores(score_file, scores, toscore_objects, write_compressed=False): id_str = (str(toscore_object.client_id)).zfill(3) sample_name = str(toscore_object.make_path()) + # we can have empty score list if allow_missing_files was true in _compute_scores() + if not scores[i]: + scores[i] = [numpy.nan] # create a NaN score for such + # scores[i] is a list, so # each sample is allowed to have multiple scores for score in scores[i]: -- GitLab From f1a048c6818b976dba839fe61e938013568e38e4 Mon Sep 17 00:00:00 2001 From: Pavel Korshunov Date: Thu, 28 Sep 2017 10:47:25 +0200 Subject: [PATCH 4/5] allow missing files scoring --- bob/pad/base/tools/scoring.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bob/pad/base/tools/scoring.py b/bob/pad/base/tools/scoring.py index aa5a53c..adf5c2a 100644 --- a/bob/pad/base/tools/scoring.py +++ b/bob/pad/base/tools/scoring.py @@ -32,7 +32,8 @@ def _compute_scores(algorithm, toscore_objects, allow_missing_files): for i, toscore_element in enumerate(toscore_objects): # filter missing files if allow_missing_files and not os.path.exists(toscore_element): - # we keep the NaN score + # we keep NaN score for such elements + scores.insert(i, [numpy.nan]) continue # read toscore toscore = algorithm.read_toscore_object(toscore_element) @@ -106,10 +107,6 @@ def _save_scores(score_file, scores, toscore_objects, write_compressed=False): id_str = (str(toscore_object.client_id)).zfill(3) sample_name = str(toscore_object.make_path()) - # we can have empty score list if allow_missing_files was true in _compute_scores() - if not scores[i]: - scores[i] = [numpy.nan] # create a NaN score for such - # scores[i] is a list, so # each sample is allowed to have multiple scores for score in scores[i]: -- GitLab From 5633d16379e5555e503c8836bb1402595df0c520 Mon Sep 17 00:00:00 2001 From: Pavel Korshunov Date: Thu, 28 Sep 2017 10:58:03 +0200 Subject: [PATCH 5/5] allow missing files scoring --- bob/pad/base/tools/scoring.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/bob/pad/base/tools/scoring.py b/bob/pad/base/tools/scoring.py index adf5c2a..1194773 100644 --- a/bob/pad/base/tools/scoring.py +++ b/bob/pad/base/tools/scoring.py @@ -131,6 +131,7 @@ def _scores_all(algorithm, group, force, allow_missing_files=False, write_compre type_objects = ['real', 'attack'] total_scores = [] + one_score_file_exists = False for i in range(0, 2): current_objects = current_toscore_objects[i] obj_type = type_objects[i] @@ -141,6 +142,7 @@ def _scores_all(algorithm, group, force, allow_missing_files=False, write_compre if utils.check_file(score_file, force): logger.warn("Score file '%s' already exists.", score_file) total_scores = [] + one_score_file_exists = True else: # get the attack files current_files = fs.get_paths(current_objects, 'projected' if algorithm.performs_projection else 'extracted') @@ -152,8 +154,13 @@ def _scores_all(algorithm, group, force, allow_missing_files=False, write_compre if total_scores != [] and not utils.check_file(fs.score_file_combined(group), force): # save all scores together in one file - _save_scores(fs.score_file_combined(group), total_scores, - current_toscore_objects[0]+current_toscore_objects[1], write_compressed) + if one_score_file_exists: + logger.warn("Since at least one score file already pre-existed, " + "we skip combining individual score files together. " + "You can do it manually, using 'cat' or similar utilities.") + else: + _save_scores(fs.score_file_combined(group), total_scores, + current_toscore_objects[0]+current_toscore_objects[1], write_compressed) def compute_scores(algorithm, force=False, groups=['dev', 'eval'], allow_missing_files=False, write_compressed=False): -- GitLab