Skip to content

Metrics redesign #2326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d8ce588
refactor metrics callback
djdameln Sep 10, 2024
2b4fb42
add Evaluator class
djdameln Sep 23, 2024
396056d
remove unused import
djdameln Sep 26, 2024
a280f47
add AnomalibMetric base class
djdameln Sep 26, 2024
717e605
cleanup
djdameln Sep 26, 2024
604a4e5
add create_anomalib_metric function
djdameln Sep 27, 2024
6d72cc4
use new AnomalibMetric class
djdameln Sep 27, 2024
00c64b3
verify keys when updating metric
djdameln Sep 27, 2024
e4fa11d
use anomalib PR curve for f1max
djdameln Sep 27, 2024
2b2c251
replace evaluator with metrics arg
djdameln Sep 27, 2024
72007e7
revert removing exportable transform method
djdameln Sep 27, 2024
62e8ac2
fix unit tests
djdameln Sep 27, 2024
a016c47
add kwargs to lightning models
djdameln Sep 27, 2024
7c36eab
fix pre-commit issues
djdameln Sep 27, 2024
87ef744
remove kwargs key from update config
djdameln Sep 27, 2024
eaf03de
add Evaluator to metrics init
djdameln Sep 27, 2024
1e4beb5
set default evaluator for image-only models
djdameln Sep 27, 2024
29905bf
fix cfa tests
djdameln Sep 27, 2024
69275be
fix model tests
djdameln Sep 27, 2024
13fe339
solve conflicts
djdameln Sep 27, 2024
c319a07
update changelog
djdameln Sep 27, 2024
9097096
remove tests of deprecated callback modules
djdameln Sep 27, 2024
1d86a93
fix engine tests
djdameln Sep 27, 2024
c613327
fix 201 notebook
djdameln Sep 27, 2024
8e021f1
fix 600 notebook
djdameln Sep 27, 2024
fdb104a
add default evaluator to fastflow
djdameln Sep 27, 2024
bf2bbb0
revert cfa changes and fix pred score computation
djdameln Oct 21, 2024
e754ddd
Merge branch 'feature/v2' into redesign-metrics
djdameln Oct 24, 2024
46acb1e
simplify evaluator argument
djdameln Oct 25, 2024
f8f4dab
validate metrics in evaluator
djdameln Oct 25, 2024
3cbeb29
remove unused import
djdameln Oct 25, 2024
4f3cb9a
fix pred_label shape validation
djdameln Oct 25, 2024
b719c95
fix method name
djdameln Oct 29, 2024
ecd6e68
fix pred_label validator
djdameln Oct 29, 2024
c29b439
update validator tests
djdameln Oct 29, 2024
161d8ed
fix method name in fastflow
djdameln Oct 29, 2024
dba5aca
add AnomalibMetric functionality to PIMO
djdameln Oct 29, 2024
3aa9542
add optional default fields and implement for pimo
djdameln Oct 29, 2024
1c0f910
update aupimo notebooks
djdameln Oct 29, 2024
4d6f6fb
use explicit args in lightning model signature
djdameln Nov 4, 2024
71d0904
remove kwargs from evaluator
djdameln Nov 4, 2024
11f638e
add _resolve_evaluator method
djdameln Nov 5, 2024
c388e91
fix config upgrade test
djdameln Nov 5, 2024
5f4c5b5
do not force pypi install in mlflow notebook
djdameln Nov 7, 2024
de2eaba
do not force pypi install in mlflow notebook
djdameln Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### Changed

- Implement new design for metrics by @djdameln https://github.com/openvinotoolkit/anomalib/pull/2326
- Set permissions for github workflows by @djdameln in https://github.com/openvinotoolkit/anomalib/pull/2127
- Update timm requirement from <=1.0.3,>=0.5.4 to >=0.5.4,<=1.0.7 by @dependabot in https://github.com/openvinotoolkit/anomalib/pull/2151
- πŸš€ Use gh actions runners for pre-commit checks by @ashwinvaidya17 in https://github.com/openvinotoolkit/anomalib/pull/2160
Expand Down
1 change: 0 additions & 1 deletion notebooks/200_models/201_fastflow.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@
"source": [
"engine = Engine(\n",
" callbacks=callbacks,\n",
" pixel_metrics=\"AUROC\",\n",
" accelerator=\"auto\", # \\<\"cpu\", \"gpu\", \"tpu\", \"ipu\", \"hpu\", \"auto\">,\n",
" devices=1,\n",
" logger=False,\n",
Expand Down
5 changes: 2 additions & 3 deletions notebooks/600_loggers/601_mlflow_logging.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"metadata": {},
"outputs": [],
"source": [
"%pip install -qU anomalib"
"%pip install anomalib"
]
},
{
Expand All @@ -56,7 +56,7 @@
"metadata": {},
"outputs": [],
"source": [
"%pip install -qU anomalib[loggers]"
"%pip install anomalib[loggers]"
]
},
{
Expand Down Expand Up @@ -307,7 +307,6 @@
"\n",
"engine = Engine(\n",
" callbacks=callbacks,\n",
" pixel_metrics=\"AUROC\",\n",
" accelerator=\"auto\",\n",
" devices=1,\n",
" logger=mlflow_logger, # Logger is set here\n",
Expand Down
223 changes: 47 additions & 176 deletions notebooks/700_metrics/701a_aupimo.ipynb

Large diffs are not rendered by default.

326 changes: 47 additions & 279 deletions notebooks/700_metrics/701b_aupimo_advanced_i.ipynb

Large diffs are not rendered by default.

174 changes: 29 additions & 145 deletions notebooks/700_metrics/701c_aupimo_advanced_ii.ipynb

Large diffs are not rendered by default.

185 changes: 0 additions & 185 deletions src/anomalib/callbacks/metrics.py

This file was deleted.

4 changes: 0 additions & 4 deletions src/anomalib/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,6 @@ def add_arguments_to_parser(parser: ArgumentParser) -> None:
``Engine`` class should be reflected manually.
"""
parser.add_argument("--task", type=TaskType | str, default=TaskType.SEGMENTATION)
parser.add_argument("--metrics.image", type=list[str] | str | None, default=None)
parser.add_argument("--metrics.pixel", type=list[str] | str | None, default=None, required=False)
parser.add_argument("--logging.log_graph", type=bool, help="Log the model to the logger", default=False)
if hasattr(parser, "subcommand") and parser.subcommand not in {"export", "predict"}:
parser.link_arguments("task", "data.init_args.task")
Expand Down Expand Up @@ -323,8 +321,6 @@ def instantiate_engine(self) -> None:

engine_args = {
"task": self._get(self.config_init, "task"),
"image_metrics": self._get(self.config_init, "metrics.image"),
"pixel_metrics": self._get(self.config_init, "metrics.pixel"),
}
trainer_config = {**self._get(self.config_init, "trainer", default={}), **engine_args}
key = "callbacks"
Expand Down
14 changes: 10 additions & 4 deletions src/anomalib/data/validators/torch/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,10 +585,16 @@ def validate_pred_label(pred_label: torch.Tensor | None) -> torch.Tensor | None:
if pred_label.ndim > 2:
msg = f"Predicted label must be 1-dimensional or 2-dimensional, got shape {pred_label.shape}."
raise ValueError(msg)
if pred_label.ndim == 2 and pred_label.shape[1] != 1:
msg = f"Predicted label with 2 dimensions must have shape [N, 1], got shape {pred_label.shape}."
raise ValueError(msg)

if pred_label.ndim == 2:
if pred_label.shape[0] == 1:
pred_label = pred_label.squeeze(0)
elif pred_label.shape[1] == 1:
pred_label = pred_label.squeeze(1)
else:
msg = (
f"Predicted label with 2 dimensions must have shape [N, 1] or [1, N], got shape {pred_label.shape}."
)
raise ValueError(msg)
return pred_label.to(torch.bool)

@staticmethod
Expand Down
12 changes: 2 additions & 10 deletions src/anomalib/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

from anomalib import LearningType, TaskType
from anomalib.callbacks.checkpoint import ModelCheckpoint
from anomalib.callbacks.metrics import _MetricsCallback
from anomalib.callbacks.timer import TimerCallback
from anomalib.data import AnomalibDataModule, AnomalibDataset, PredictDataset
from anomalib.deploy import CompressionType, ExportType
Expand Down Expand Up @@ -116,8 +115,6 @@ def __init__(
self,
callbacks: list[Callback] | None = None,
task: TaskType | str = TaskType.SEGMENTATION,
image_metrics: list[str] | str | dict[str, dict[str, Any]] | None = None,
pixel_metrics: list[str] | str | dict[str, dict[str, Any]] | None = None,
logger: Logger | Iterable[Logger] | bool | None = None,
default_root_dir: str | Path = "results",
**kwargs,
Expand All @@ -137,12 +134,6 @@ def __init__(
)

self.task = TaskType(task)
self.image_metric_names = image_metrics if image_metrics else ["AUROC", "F1Max"]

# pixel metrics are only used for segmentation tasks.
self.pixel_metric_names = None
if self.task == TaskType.SEGMENTATION:
self.pixel_metric_names = pixel_metrics if pixel_metrics is not None else ["AUROC", "F1Max"]

self._trainer: Trainer | None = None

Expand Down Expand Up @@ -375,7 +366,8 @@ def _setup_anomalib_callbacks(self, model: AnomalyModule) -> None:
_callbacks.append(model.post_processor)

# Add the metrics callback.
_callbacks.append(_MetricsCallback(self.task, self.image_metric_names, self.pixel_metric_names))
if isinstance(model.evaluator, Callback):
_callbacks.append(model.evaluator)

# Add the image visualizer callback if it is passed by the user.
if not any(isinstance(callback, ImageVisualizer) for callback in self._cache.args["callbacks"]):
Expand Down
Loading
Loading