diff --git a/.github/workflows/CI-responsibleai-text-vision-pytest.yml b/.github/workflows/CI-responsibleai-text-vision-pytest.yml index b762c56083..0c420e69ca 100644 --- a/.github/workflows/CI-responsibleai-text-vision-pytest.yml +++ b/.github/workflows/CI-responsibleai-text-vision-pytest.yml @@ -88,7 +88,9 @@ jobs: - if: ${{ (matrix.packageDirectory == 'responsibleai_vision') && ((matrix.pythonVersion == '3.7') || (matrix.pythonVersion == '3.8')) }} name: Install automl dependencies shell: bash -l {0} + # pycocotools is a downstream dependency of automl requirements, but fails to install with pip run: | + conda install pycocotools==2.0.4 -c conda-forge pip install -r ${{ matrix.packageDirectory }}/requirements-automl.txt - name: Install package diff --git a/responsibleai_vision/requirements.txt b/responsibleai_vision/requirements.txt index ab5b5077dc..97e350b85a 100644 --- a/responsibleai_vision/requirements.txt +++ b/responsibleai_vision/requirements.txt @@ -1,5 +1,7 @@ numpy>=1.17.2 pandas>=0.25.1,<2.0.0 # TODO: remove ceiling on version. +Pillow>=10.0.0; python_version>"3.7" # due to breaking changes in v10.0.0 (https://pillow.readthedocs.io/en/latest/releasenotes/10.0.0.html) +Pillow<10.0.0; python_version<="3.7" # Pillow v10.0.0 is only available starting with Python 3.8 scikit-learn>=0.22.1 scipy>=1.4.1 semver~=2.13.0 diff --git a/responsibleai_vision/responsibleai_vision/managers/explainer_manager.py b/responsibleai_vision/responsibleai_vision/managers/explainer_manager.py index 83c627b895..6b95eca14d 100644 --- a/responsibleai_vision/responsibleai_vision/managers/explainer_manager.py +++ b/responsibleai_vision/responsibleai_vision/managers/explainer_manager.py @@ -266,14 +266,23 @@ def compute_single_explanation(self, # get_drise_saliency_map only recognizes GPU and CPU if device == Device.AUTO.value: device = None - fl, _, _, = get_drise_saliency_map(img, - self._model, - len(self._classes), - savename=str(index), - nummasks=self._num_masks, - maskres=mask_res_tuple, - devicechoice=device, - max_figures=5000) + try: + fl, _, _, = get_drise_saliency_map( + img, + self._model, + len(self._classes), + savename=str(index), + nummasks=self._num_masks, + maskres=mask_res_tuple, + devicechoice=device, + max_figures=5000) + except ValueError as ve: + if str(ve) == 'No detections found': + raise UserConfigValidationException( + "No detections found in image. " + "Please increase num_masks or mask_res.") + else: + raise ve if object_index is None: return fl b64_string = fl[object_index] @@ -577,11 +586,13 @@ def _is_object_detection_task(self): return self._task_type == ModelTask.OBJECT_DETECTION def _get_fail_str(self): - fail = Image.new('RGB', (100, 100)) + fail = Image.new('RGB', (250, 250)) draw = ImageDraw.Draw(fail) font = ImageFont.load_default() text = "saliency map could not be created" - textwidth, textheight = draw.textsize(text, font) + left, top, right, bottom = draw.textbbox((0, 0), text, font) + textwidth = right - left + textheight = bottom - top x = (fail.width - textwidth) // 2 y = (fail.height - textheight) // 2 draw.text((x, y), text, fill="white", font=font)