From 210d354eab1f9dea49cd4aa0f4c1a88a3b22385a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20K=C3=BCmmerer?= Date: Tue, 26 Mar 2024 00:12:46 +0100 Subject: [PATCH 1/4] Cleanup imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Kümmerer --- pysaliency/__init__.py | 1 + pysaliency/external_models/__init__.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pysaliency/__init__.py b/pysaliency/__init__.py index e8c9f54..1d4f639 100755 --- a/pysaliency/__init__.py +++ b/pysaliency/__init__.py @@ -5,6 +5,7 @@ from . import models from . import external_models from . import external_datasets +from . import utils from .datasets import ( Fixations, diff --git a/pysaliency/external_models/__init__.py b/pysaliency/external_models/__init__.py index 69803eb..e976563 100644 --- a/pysaliency/external_models/__init__.py +++ b/pysaliency/external_models/__init__.py @@ -11,4 +11,9 @@ CovSal, ) -from .utils import ExternalModelMixin \ No newline at end of file +from .deepgaze import ( + DeepGazeI, + DeepGazeIIE, +) + +from .utils import ExternalModelMixin From 2dfb64c37f2b923164c2b219ed6e2f6b8c3caa97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20K=C3=BCmmerer?= Date: Tue, 26 Mar 2024 00:26:06 +0100 Subject: [PATCH 2/4] BUG: AUC with average=image fails if there are images without fixations" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now images without fixations are ignored, in consistency with how it is handled in information_gain and NSS. Signed-off-by: Matthias Kümmerer --- pysaliency/saliency_map_models.py | 13 +++++++++++++ tests/test_saliency_map_models.py | 25 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/pysaliency/saliency_map_models.py b/pysaliency/saliency_map_models.py index b02c0ac..c45fffc 100644 --- a/pysaliency/saliency_map_models.py +++ b/pysaliency/saliency_map_models.py @@ -413,6 +413,11 @@ def AUC_per_image(self, stimuli, fixations, nonfixations='uniform', thresholds=' out = self.saliency_map(stimuli.stimulus_objects[n]) check_prediction_shape(out, stimuli[n]) inds = fixations.n == n + + if not inds.sum(): + rocs_per_image.append(np.nan) + continue + positives = np.asarray(out[fixations.y_int[inds], fixations.x_int[inds]]) if nonfixations == 'uniform': negatives = out.flatten() @@ -482,6 +487,14 @@ def AUC(self, stimuli, fixations, nonfixations='uniform', average='fixation', th return np.average(aucs, weights=weights) elif average == 'image': + stimulus_indices = set(fixations.n) + nan_value_indices = np.nonzero(np.isnan(aucs))[0] + + if stimulus_indices.intersection(nan_value_indices): + raise ValueError("Some images with fixations returned AUC of nan, which should not happen") + + aucs = aucs[~np.isnan(aucs)] + return np.mean(aucs) else: raise ValueError(average) diff --git a/tests/test_saliency_map_models.py b/tests/test_saliency_map_models.py index 20f4e98..3131949 100644 --- a/tests/test_saliency_map_models.py +++ b/tests/test_saliency_map_models.py @@ -184,6 +184,31 @@ def test_auc_gauss(stimuli, fixation_trains): np.testing.assert_allclose(aucs_single, aucs_combined) +def test_auc_per_image(stimuli, fixation_trains): + gsmm = GaussianSaliencyMapModel() + + aucs = gsmm.AUC_per_image(stimuli, fixation_trains) + np.testing.assert_allclose(aucs, + [0.196625, 0.313125], + rtol=1e-6) + + +def test_auc_per_image_images_without_fixations(stimuli, fixation_trains): + gsmm = GaussianSaliencyMapModel() + + aucs = gsmm.AUC_per_image(stimuli, fixation_trains[:5],) + np.testing.assert_allclose(aucs, + [0.196625, np.nan], + rtol=1e-6) + + +def test_auc_image_average_with_images_without_fixations(stimuli, fixation_trains): + gsmm = GaussianSaliencyMapModel() + + auc = gsmm.AUC(stimuli, fixation_trains[:5], average='image') + np.testing.assert_allclose(auc, 0.196625, rtol=1e-6) + + def test_nss_gauss(stimuli, fixation_trains): gsmm = GaussianSaliencyMapModel() From dab8ffd6cfcd6025cc62a7f910a54c9b78c5135f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20K=C3=BCmmerer?= Date: Tue, 26 Mar 2024 00:36:15 +0100 Subject: [PATCH 3/4] Ignore log warnings in uniform model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Kümmerer --- pysaliency/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pysaliency/models.py b/pysaliency/models.py index 0366151..5ad5cca 100755 --- a/pysaliency/models.py +++ b/pysaliency/models.py @@ -416,7 +416,9 @@ def log_likelihoods(self, stimuli, fixations, verbose=False): for stimulus_index in stimulus_indices: stimulus_shapes[stimulus_index] = stimuli.stimulus_objects[stimulus_index].size - stimulus_log_likelihoods = -np.log(stimulus_shapes).sum(axis=1) + with np.errstate(divide='ignore'): # ignore log(0) warnings, we won't use them anyway + stimulus_log_likelihoods = -np.log(stimulus_shapes).sum(axis=1) + return stimulus_log_likelihoods[fixations.n] From 78d45f684d209f0708e5bde5182285e6c414f0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20K=C3=BCmmerer?= Date: Tue, 26 Mar 2024 00:52:11 +0100 Subject: [PATCH 4/4] ENH: avoid computing saliency maps for AUC on images without fixations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Kümmerer --- pysaliency/saliency_map_models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pysaliency/saliency_map_models.py b/pysaliency/saliency_map_models.py index c45fffc..ff7d005 100644 --- a/pysaliency/saliency_map_models.py +++ b/pysaliency/saliency_map_models.py @@ -410,14 +410,14 @@ def AUC_per_image(self, stimuli, fixations, nonfixations='uniform', thresholds=' nonfixations = FullShuffledNonfixationProvider(stimuli, fixations) for n in tqdm(range(len(stimuli)), disable=not verbose): - out = self.saliency_map(stimuli.stimulus_objects[n]) - check_prediction_shape(out, stimuli[n]) inds = fixations.n == n - if not inds.sum(): rocs_per_image.append(np.nan) continue + out = self.saliency_map(stimuli.stimulus_objects[n]) + check_prediction_shape(out, stimuli[n]) + positives = np.asarray(out[fixations.y_int[inds], fixations.x_int[inds]]) if nonfixations == 'uniform': negatives = out.flatten()