Skip to content

Commit

Permalink
🗑️ Remove numba (#2313)
Browse files Browse the repository at this point in the history
* remove numba

Signed-off-by: Ashwin Vaidya <[email protected]>

* fix pre-commit checks

Signed-off-by: Ashwin Vaidya <[email protected]>

* add third-party-programs.txt

Signed-off-by: Ashwin Vaidya <[email protected]>

---------

Signed-off-by: Ashwin Vaidya <[email protected]>
  • Loading branch information
ashwinvaidya17 authored Sep 23, 2024
1 parent 29cb912 commit c768f92
Show file tree
Hide file tree
Showing 14 changed files with 55 additions and 303 deletions.
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ test = [
"coverage[toml]",
"tox",
]
extra = ["numba>=0.58.1"]
full = ["anomalib[core,openvino,loggers,notebooks,extra]"]
full = ["anomalib[core,openvino,loggers,notebooks]"]
dev = ["anomalib[full,docs,test]"]

[project.scripts]
Expand Down
3 changes: 1 addition & 2 deletions src/anomalib/metrics/per_image/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# SPDX-License-Identifier: Apache-2.0

from .binclf_curve import per_image_binclf_curve, per_image_fpr, per_image_tpr
from .binclf_curve_numpy import BinclfAlgorithm, BinclfThreshsChoice
from .binclf_curve_numpy import BinclfThreshsChoice
from .pimo import AUPIMO, PIMO, AUPIMOResult, PIMOResult, aupimo_scores, pimo_curves
from .utils import (
compare_models_pairwise_ttest_rel,
Expand All @@ -20,7 +20,6 @@

__all__ = [
# constants
"BinclfAlgorithm",
"BinclfThreshsChoice",
"StatsOutliersPolicy",
"StatsRepeatedPolicy",
Expand Down
115 changes: 0 additions & 115 deletions src/anomalib/metrics/per_image/_binclf_curve_numba.py

This file was deleted.

4 changes: 2 additions & 2 deletions src/anomalib/metrics/per_image/_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def is_masks(masks: ndarray) -> None:
if masks.dtype.kind == "b":
pass

elif masks.dtype.kind in ("i", "u"):
elif masks.dtype.kind in {"i", "u"}:
masks_unique_vals = np.unique(masks)
if np.any((masks_unique_vals != 0) & (masks_unique_vals != 1)):
msg = (
Expand Down Expand Up @@ -243,7 +243,7 @@ def is_images_classes(images_classes: ndarray) -> None:

if images_classes.dtype.kind == "b":
pass
elif images_classes.dtype.kind in ("i", "u"):
elif images_classes.dtype.kind in {"i", "u"}:
unique_vals = np.unique(images_classes)
if np.any((unique_vals != 0) & (unique_vals != 1)):
msg = (
Expand Down
5 changes: 1 addition & 4 deletions src/anomalib/metrics/per_image/binclf_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from torch import Tensor

from . import _validate, binclf_curve_numpy
from .binclf_curve_numpy import BinclfAlgorithm, BinclfThreshsChoice
from .binclf_curve_numpy import BinclfThreshsChoice

# =========================================== ARGS VALIDATION ===========================================

Expand All @@ -47,7 +47,6 @@ def _validate_is_binclf_curves(binclf_curves: Tensor, valid_threshs: Tensor | No
def per_image_binclf_curve(
anomaly_maps: Tensor,
masks: Tensor,
algorithm: BinclfAlgorithm | str = BinclfAlgorithm.NUMBA,
threshs_choice: BinclfThreshsChoice | str = BinclfThreshsChoice.MINMAX_LINSPACE,
threshs_given: Tensor | None = None,
num_threshs: int | None = None,
Expand All @@ -59,7 +58,6 @@ def per_image_binclf_curve(
Args:
anomaly_maps (Tensor): Anomaly score maps of shape (N, H, W [, D, ...])
masks (Tensor): Binary ground truth masks of shape (N, H, W [, D, ...])
algorithm (str, optional): Algorithm to use. Defaults to ALGORITHM_NUMBA.
threshs_choice (str, optional): Sequence of thresholds to use. Defaults to THRESH_SEQUENCE_MINMAX_LINSPACE.
return_result_object (bool, optional): Whether to return a `PerImageBinClfCurveResult` object. Defaults to True.
Expand Down Expand Up @@ -115,7 +113,6 @@ def per_image_binclf_curve(
threshs_array, binclf_curves_array = binclf_curve_numpy.per_image_binclf_curve(
anomaly_maps=anomaly_maps_array,
masks=masks_array,
algorithm=algorithm,
threshs_choice=threshs_choice,
threshs_given=threshs_given_array,
num_threshs=num_threshs,
Expand Down
49 changes: 8 additions & 41 deletions src/anomalib/metrics/per_image/binclf_curve_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,13 @@
import numpy as np
from numpy import ndarray

try:
import numba # noqa: F401
except ImportError:
HAS_NUMBA = False
else:
HAS_NUMBA = True


if HAS_NUMBA:
from . import _binclf_curve_numba

from . import _validate

logger = logging.getLogger(__name__)

# =========================================== CONSTANTS ===========================================


class BinclfAlgorithm(Enum):
"""Algorithm to use (relates to the low-level implementation)."""

PYTHON: str = "python"
NUMBA: str = "numba"


class BinclfThreshsChoice(Enum):
"""Sequence of thresholds to use."""

Expand Down Expand Up @@ -95,8 +77,8 @@ def _validate_is_gts_batch(gts_batch: ndarray) -> None:
# =========================================== PYTHON VERSION ===========================================


def _binclf_one_curve_python(scores: ndarray, gts: ndarray, threshs: ndarray) -> ndarray:
"""One binary classification matrix at each threshold (PYTHON implementation).
def _binclf_one_curve(scores: ndarray, gts: ndarray, threshs: ndarray) -> ndarray:
"""One binary classification matrix at each threshold.
In the case where the thresholds are given (i.e. not considering all possible thresholds based on the scores),
this weird-looking function is faster than the two options in `torchmetrics` on the CPU:
Expand Down Expand Up @@ -167,10 +149,10 @@ def score_less_than_thresh(score: float, thresh: float) -> bool:
).transpose(0, 2, 1)


_binclf_multiple_curves_python = np.vectorize(_binclf_one_curve_python, signature="(n),(n),(k)->(k,2,2)")
_binclf_multiple_curves_python.__doc__ = """
Multiple binary classification matrix at each threshold (PYTHON implementation).
vectorized version of `_binclf_one_curve_python` (see above)
_binclf_multiple_curves = np.vectorize(_binclf_one_curve, signature="(n),(n),(k)->(k,2,2)")
_binclf_multiple_curves.__doc__ = """
Multiple binary classification matrix at each threshold.
vectorized version of `_binclf_one_curve` (see above)
"""

# =========================================== INTERFACE ===========================================
Expand All @@ -180,7 +162,6 @@ def binclf_multiple_curves(
scores_batch: ndarray,
gts_batch: ndarray,
threshs: ndarray,
algorithm: BinclfAlgorithm | str = BinclfAlgorithm.NUMBA.value,
) -> ndarray:
"""Multiple binary classification matrix (per-instance scope) at each threshold (shared).
Expand Down Expand Up @@ -220,23 +201,12 @@ def binclf_multiple_curves(
Thresholds are sorted in ascending order.
"""
algorithm = BinclfAlgorithm(algorithm)
_validate_is_scores_batch(scores_batch)
_validate_is_gts_batch(gts_batch)
_validate.is_same_shape(scores_batch, gts_batch)
_validate.is_threshs(threshs)

if algorithm == BinclfAlgorithm.NUMBA:
if HAS_NUMBA:
return _binclf_curve_numba.binclf_multiple_curves_numba(scores_batch, gts_batch, threshs)

logger.warning(
f"Algorithm '{BinclfAlgorithm.NUMBA.value}' was selected, but Numba is not installed. "
f"Falling back to '{BinclfAlgorithm.PYTHON.value}' implementation.",
"Notice that the performance will be slower. Consider installing Numba for faster computation.",
)

return _binclf_multiple_curves_python(scores_batch, gts_batch, threshs)
return _binclf_multiple_curves(scores_batch, gts_batch, threshs)


# ========================================= PER-IMAGE BINCLF CURVE =========================================
Expand All @@ -258,7 +228,6 @@ def _get_threshs_minmax_linspace(anomaly_maps: ndarray, num_threshs: int) -> nda
def per_image_binclf_curve(
anomaly_maps: ndarray,
masks: ndarray,
algorithm: BinclfAlgorithm | str = BinclfAlgorithm.NUMBA.value,
threshs_choice: BinclfThreshsChoice | str = BinclfThreshsChoice.MINMAX_LINSPACE.value,
threshs_given: ndarray | None = None,
num_threshs: int | None = None,
Expand All @@ -268,7 +237,6 @@ def per_image_binclf_curve(
Args:
anomaly_maps (ndarray): Anomaly score maps of shape (N, H, W)
masks (ndarray): Binary ground truth masks of shape (N, H, W)
algorithm (str, optional): Algorithm to use. Defaults to ALGORITHM_NUMBA.
threshs_choice (str, optional): Sequence of thresholds to use. Defaults to THRESH_SEQUENCE_MINMAX_LINSPACE.
#
# `threshs_choice`-dependent arguments
Expand Down Expand Up @@ -308,7 +276,6 @@ def per_image_binclf_curve(
Thresholds are sorted in ascending order.
"""
BinclfAlgorithm(algorithm)
threshs_choice = BinclfThreshsChoice(threshs_choice)
_validate.is_anomaly_maps(anomaly_maps)
_validate.is_masks(masks)
Expand Down Expand Up @@ -350,7 +317,7 @@ def per_image_binclf_curve(
scores_batch = anomaly_maps.reshape(anomaly_maps.shape[0], -1)
gts_batch = masks.reshape(masks.shape[0], -1).astype(bool) # make sure it is boolean

binclf_curves = binclf_multiple_curves(scores_batch, gts_batch, threshs, algorithm=algorithm)
binclf_curves = binclf_multiple_curves(scores_batch, gts_batch, threshs)

num_images = anomaly_maps.shape[0]

Expand Down
Loading

0 comments on commit c768f92

Please sign in to comment.