From 09ffb6577a08020d1ae9760a492bd5efdee2d1b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:12:08 +0000 Subject: [PATCH 1/4] Update torch requirement from <2.2.0,>=2 to >=2,<2.3.0 Updates the requirements on [torch](https://github.com/pytorch/pytorch) to permit the latest version. - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](https://github.com/pytorch/pytorch/compare/v2.0.0...v2.2.2) --- updated-dependencies: - dependency-name: torch dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6ab726bcef..f8e5ce0337 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ core = [ "pandas>=1.1.0", "timm>=0.5.4,<=0.9.16", "lightning>2,<2.2.0", - "torch>=2,<2.2.0", + "torch>=2,<2.3.0", "torchmetrics>=1.3.2", "open-clip-torch>=2.23.0", ] From 93dcf46e2d24e9a30062d32808e6b92fe5a72767 Mon Sep 17 00:00:00 2001 From: Samet Akcay Date: Thu, 4 Apr 2024 14:34:30 +0100 Subject: [PATCH 2/4] Update model.eval based on the new lightning Signed-off-by: Samet Akcay --- pyproject.toml | 4 ++-- src/anomalib/models/image/cflow/lightning_model.py | 2 +- src/anomalib/models/image/csflow/lightning_model.py | 3 +-- .../models/image/fastflow/lightning_model.py | 4 +--- src/anomalib/models/image/padim/lightning_model.py | 6 ++---- src/anomalib/models/image/padim/torch_model.py | 9 ++++++--- .../models/image/patchcore/lightning_model.py | 2 -- src/anomalib/models/image/patchcore/torch_model.py | 2 +- .../image/reverse_distillation/lightning_model.py | 4 +--- src/anomalib/models/image/stfpm/lightning_model.py | 2 -- src/anomalib/models/image/stfpm/torch_model.py | 3 +-- .../models/image/uflow/feature_extraction.py | 12 +++++------- src/anomalib/models/image/uflow/torch_model.py | 1 - tests/integration/model/test_models.py | 9 +++------ 14 files changed, 24 insertions(+), 39 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f8e5ce0337..99a15349bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,8 +34,8 @@ core = [ "opencv-python>=4.5.3.56", "pandas>=1.1.0", "timm>=0.5.4,<=0.9.16", - "lightning>2,<2.2.0", - "torch>=2,<2.3.0", + "lightning>=2.2", + "torch>=2", "torchmetrics>=1.3.2", "open-clip-torch>=2.23.0", ] diff --git a/src/anomalib/models/image/cflow/lightning_model.py b/src/anomalib/models/image/cflow/lightning_model.py index b5f47bff86..5818f911bb 100644 --- a/src/anomalib/models/image/cflow/lightning_model.py +++ b/src/anomalib/models/image/cflow/lightning_model.py @@ -84,6 +84,7 @@ def __init__( # TODO(ashwinvaidya17): LR should be part of optimizer in config.yaml since cflow has custom optimizer. # CVS-122670 self.learning_rate = lr + self.model.encoder.eval() def configure_optimizers(self) -> Optimizer: """Configure optimizers for each decoder. @@ -119,7 +120,6 @@ def training_step(self, batch: dict[str, str | torch.Tensor], *args, **kwargs) - del args, kwargs # These variables are not used. opt = self.optimizers() - self.model.encoder.eval() images: torch.Tensor = batch["image"] activation = self.model.encoder(images) diff --git a/src/anomalib/models/image/csflow/lightning_model.py b/src/anomalib/models/image/csflow/lightning_model.py index 22161255a2..a759000aa2 100644 --- a/src/anomalib/models/image/csflow/lightning_model.py +++ b/src/anomalib/models/image/csflow/lightning_model.py @@ -6,7 +6,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - import logging from typing import Any @@ -68,6 +67,7 @@ def _setup(self) -> None: clamp=self.clamp, num_channels=self.num_channels, ) + self.model.feature_extractor.eval() def training_step(self, batch: dict[str, str | torch.Tensor], *args, **kwargs) -> STEP_OUTPUT: """Perform the training step of CS-Flow. @@ -82,7 +82,6 @@ def training_step(self, batch: dict[str, str | torch.Tensor], *args, **kwargs) - """ del args, kwargs # These variables are not used. - self.model.feature_extractor.eval() z_dist, jacobians = self.model(batch["image"]) loss = self.loss(z_dist, jacobians) self.log("train_loss", loss.item(), on_epoch=True, prog_bar=True, logger=True) diff --git a/src/anomalib/models/image/fastflow/lightning_model.py b/src/anomalib/models/image/fastflow/lightning_model.py index 32e216d17e..e6f2df0780 100644 --- a/src/anomalib/models/image/fastflow/lightning_model.py +++ b/src/anomalib/models/image/fastflow/lightning_model.py @@ -6,7 +6,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from typing import Any import torch @@ -52,9 +51,8 @@ def __init__( self.conv3x3_only = conv3x3_only self.hidden_ratio = hidden_ratio - self.loss = FastflowLoss() - self.model: FastflowModel + self.loss = FastflowLoss() def _setup(self) -> None: if self.input_size is None: diff --git a/src/anomalib/models/image/padim/lightning_model.py b/src/anomalib/models/image/padim/lightning_model.py index 5da69e3c8f..95bee8ec1b 100644 --- a/src/anomalib/models/image/padim/lightning_model.py +++ b/src/anomalib/models/image/padim/lightning_model.py @@ -6,7 +6,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - import logging import torch @@ -52,7 +51,8 @@ def __init__( pre_trained=pre_trained, layers=layers, n_features=n_features, - ).eval() + ) + self.model.feature_extractor.eval() self.stats: list[torch.Tensor] = [] self.embeddings: list[torch.Tensor] = [] @@ -75,9 +75,7 @@ def training_step(self, batch: dict[str, str | torch.Tensor], *args, **kwargs) - """ del args, kwargs # These variables are not used. - self.model.feature_extractor.eval() embedding = self.model(batch["image"]) - self.embeddings.append(embedding.cpu()) def fit(self) -> None: diff --git a/src/anomalib/models/image/padim/torch_model.py b/src/anomalib/models/image/padim/torch_model.py index c1200cf01d..e24e8a03a2 100644 --- a/src/anomalib/models/image/padim/torch_model.py +++ b/src/anomalib/models/image/padim/torch_model.py @@ -3,7 +3,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from random import sample from typing import TYPE_CHECKING @@ -67,8 +66,8 @@ class PadimModel(nn.Module): def __init__( self, - layers: list[str], backbone: str = "resnet18", + layers: list[str] = ["layer1", "layer2", "layer3"], # noqa: B006 pre_trained: bool = True, n_features: int | None = None, ) -> None: @@ -77,7 +76,11 @@ def __init__( self.backbone = backbone self.layers = layers - self.feature_extractor = TimmFeatureExtractor(backbone=self.backbone, layers=layers, pre_trained=pre_trained) + self.feature_extractor = TimmFeatureExtractor( + backbone=self.backbone, + layers=layers, + pre_trained=pre_trained, + ).eval() self.n_features_original = sum(self.feature_extractor.out_dims) self.n_features = n_features or _N_FEATURES_DEFAULTS.get(self.backbone) if self.n_features is None: diff --git a/src/anomalib/models/image/patchcore/lightning_model.py b/src/anomalib/models/image/patchcore/lightning_model.py index 3451e7ffd2..ca0b2081d4 100644 --- a/src/anomalib/models/image/patchcore/lightning_model.py +++ b/src/anomalib/models/image/patchcore/lightning_model.py @@ -78,9 +78,7 @@ def training_step(self, batch: dict[str, str | torch.Tensor], *args, **kwargs) - """ del args, kwargs # These variables are not used. - self.model.feature_extractor.eval() embedding = self.model(batch["image"]) - self.embeddings.append(embedding) def fit(self) -> None: diff --git a/src/anomalib/models/image/patchcore/torch_model.py b/src/anomalib/models/image/patchcore/torch_model.py index fd2a5e865f..5b26a12ee3 100644 --- a/src/anomalib/models/image/patchcore/torch_model.py +++ b/src/anomalib/models/image/patchcore/torch_model.py @@ -49,7 +49,7 @@ def __init__( backbone=self.backbone, pre_trained=pre_trained, layers=self.layers, - ) + ).eval() self.feature_pooler = torch.nn.AvgPool2d(3, 1, 1) self.anomaly_map_generator = AnomalyMapGenerator() diff --git a/src/anomalib/models/image/reverse_distillation/lightning_model.py b/src/anomalib/models/image/reverse_distillation/lightning_model.py index d035f965de..5684e52f1e 100644 --- a/src/anomalib/models/image/reverse_distillation/lightning_model.py +++ b/src/anomalib/models/image/reverse_distillation/lightning_model.py @@ -6,7 +6,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from collections.abc import Sequence from typing import Any @@ -50,9 +49,8 @@ def __init__( self.layers = layers self.anomaly_map_mode = anomaly_map_mode - self.loss = ReverseDistillationLoss() - self.model: ReverseDistillationModel + self.loss = ReverseDistillationLoss() def _setup(self) -> None: if self.input_size is None: diff --git a/src/anomalib/models/image/stfpm/lightning_model.py b/src/anomalib/models/image/stfpm/lightning_model.py index 34aeb8c7d4..59cc5df98d 100644 --- a/src/anomalib/models/image/stfpm/lightning_model.py +++ b/src/anomalib/models/image/stfpm/lightning_model.py @@ -6,7 +6,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from collections.abc import Sequence from typing import Any @@ -61,7 +60,6 @@ def training_step(self, batch: dict[str, str | torch.Tensor], *args, **kwargs) - """ del args, kwargs # These variables are not used. - self.model.teacher_model.eval() teacher_features, student_features = self.model.forward(batch["image"]) loss = self.loss(teacher_features, student_features) self.log("train_loss", loss.item(), on_epoch=True, prog_bar=True, logger=True) diff --git a/src/anomalib/models/image/stfpm/torch_model.py b/src/anomalib/models/image/stfpm/torch_model.py index 98ddf5d46a..58beabea0e 100644 --- a/src/anomalib/models/image/stfpm/torch_model.py +++ b/src/anomalib/models/image/stfpm/torch_model.py @@ -3,7 +3,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from collections.abc import Sequence from typing import TYPE_CHECKING @@ -36,7 +35,7 @@ def __init__( self.tiler: Tiler | None = None self.backbone = backbone - self.teacher_model = TimmFeatureExtractor(backbone=self.backbone, pre_trained=True, layers=layers) + self.teacher_model = TimmFeatureExtractor(backbone=self.backbone, pre_trained=True, layers=layers).eval() self.student_model = TimmFeatureExtractor( backbone=self.backbone, pre_trained=False, diff --git a/src/anomalib/models/image/uflow/feature_extraction.py b/src/anomalib/models/image/uflow/feature_extraction.py index fb35af3ec8..1e6385fc4d 100644 --- a/src/anomalib/models/image/uflow/feature_extraction.py +++ b/src/anomalib/models/image/uflow/feature_extraction.py @@ -32,15 +32,13 @@ def get_feature_extractor(backbone: str, input_size: tuple[int, int] = (256, 256 msg = f"Feature extractor must be one of {AVAILABLE_EXTRACTORS}." raise ValueError(msg) + feature_extractor: nn.Module if backbone in ["resnet18", "wide_resnet50_2"]: - return FeatureExtractor(backbone, input_size, layers=("layer1", "layer2", "layer3")) + feature_extractor = FeatureExtractor(backbone, input_size, layers=("layer1", "layer2", "layer3")).eval() if backbone == "mcait": - return MCaitFeatureExtractor() - msg = ( - "`backbone` must be one of `[mcait, resnet18, wide_resnet50_2]`. These are the only feature extractors tested. " - "It does not mean that other feature extractors will not work." - ) - raise ValueError(msg) + feature_extractor = MCaitFeatureExtractor().eval() + + return feature_extractor class FeatureExtractor(TimmFeatureExtractor): diff --git a/src/anomalib/models/image/uflow/torch_model.py b/src/anomalib/models/image/uflow/torch_model.py index 221ae488c6..dfbad59bec 100644 --- a/src/anomalib/models/image/uflow/torch_model.py +++ b/src/anomalib/models/image/uflow/torch_model.py @@ -3,7 +3,6 @@ # Copyright (C) 2023-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - import torch from FrEIA import framework as ff from FrEIA import modules as fm diff --git a/tests/integration/model/test_models.py b/tests/integration/model/test_models.py index 4be832d20b..8cf2a5a9e1 100644 --- a/tests/integration/model/test_models.py +++ b/tests/integration/model/test_models.py @@ -6,7 +6,6 @@ # Copyright (C) 2023-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from pathlib import Path import pytest @@ -144,12 +143,10 @@ def test_export( dataset_path (Path): Root to dataset from fixture. project_path (Path): Path to temporary project folder from fixture. """ - if model_name == "reverse_distillation": - # TODO(ashwinvaidya17): Restore this test after fixing reverse distillation + if model_name in ("reverse_distillation", "rkde"): + # TODO(ashwinvaidya17): Restore this test after fixing the issue # https://github.com/openvinotoolkit/anomalib/issues/1513 - pytest.skip("Reverse distillation fails to convert to ONNX") - elif model_name == "rkde" and export_type == ExportType.OPENVINO: - pytest.skip("RKDE fails to convert to OpenVINO") + pytest.skip(f"{model_name} fails to convert to ONNX and OpenVINO") model, dataset, engine = self._get_objects( model_name=model_name, From 41188bb7e7afe71442d38a2d41655e410db0d7cd Mon Sep 17 00:00:00 2001 From: Samet Akcay Date: Thu, 4 Apr 2024 14:36:35 +0100 Subject: [PATCH 3/4] Call eval within CFlow torch model Signed-off-by: Samet Akcay --- src/anomalib/models/image/cflow/lightning_model.py | 1 - src/anomalib/models/image/cflow/torch_model.py | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/anomalib/models/image/cflow/lightning_model.py b/src/anomalib/models/image/cflow/lightning_model.py index 5818f911bb..9275cc75d4 100644 --- a/src/anomalib/models/image/cflow/lightning_model.py +++ b/src/anomalib/models/image/cflow/lightning_model.py @@ -84,7 +84,6 @@ def __init__( # TODO(ashwinvaidya17): LR should be part of optimizer in config.yaml since cflow has custom optimizer. # CVS-122670 self.learning_rate = lr - self.model.encoder.eval() def configure_optimizers(self) -> Optimizer: """Configure optimizers for each decoder. diff --git a/src/anomalib/models/image/cflow/torch_model.py b/src/anomalib/models/image/cflow/torch_model.py index 90ee8b551a..dfd7c564b3 100644 --- a/src/anomalib/models/image/cflow/torch_model.py +++ b/src/anomalib/models/image/cflow/torch_model.py @@ -3,7 +3,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from collections.abc import Sequence import einops @@ -58,7 +57,11 @@ def __init__( self.dec_arch = decoder self.pool_layers = layers - self.encoder = TimmFeatureExtractor(backbone=self.backbone, layers=self.pool_layers, pre_trained=pre_trained) + self.encoder = TimmFeatureExtractor( + backbone=self.backbone, + layers=self.pool_layers, + pre_trained=pre_trained, + ).eval() self.pool_dims = self.encoder.out_dims self.decoders = nn.ModuleList( [ From 10a35322bbcf569b8075817591c8c8555240a515 Mon Sep 17 00:00:00 2001 From: Samet Akcay Date: Thu, 4 Apr 2024 14:38:41 +0100 Subject: [PATCH 4/4] Call eval within csflow Signed-off-by: Samet Akcay --- src/anomalib/models/image/csflow/torch_model.py | 3 +-- src/anomalib/models/image/padim/lightning_model.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/anomalib/models/image/csflow/torch_model.py b/src/anomalib/models/image/csflow/torch_model.py index 82239ecf20..13fa98f5ac 100644 --- a/src/anomalib/models/image/csflow/torch_model.py +++ b/src/anomalib/models/image/csflow/torch_model.py @@ -10,7 +10,6 @@ # Copyright (C) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - from math import exp import numpy as np @@ -562,7 +561,7 @@ def __init__( self.input_dims = (num_channels, *input_size) self.clamp = clamp self.cross_conv_hidden_channels = cross_conv_hidden_channels - self.feature_extractor = MultiScaleFeatureExtractor(n_scales=3, input_size=input_size) + self.feature_extractor = MultiScaleFeatureExtractor(n_scales=3, input_size=input_size).eval() self.graph = CrossScaleFlow( input_dims=self.input_dims, n_coupling_blocks=n_coupling_blocks, diff --git a/src/anomalib/models/image/padim/lightning_model.py b/src/anomalib/models/image/padim/lightning_model.py index 95bee8ec1b..4912553291 100644 --- a/src/anomalib/models/image/padim/lightning_model.py +++ b/src/anomalib/models/image/padim/lightning_model.py @@ -52,7 +52,6 @@ def __init__( layers=layers, n_features=n_features, ) - self.model.feature_extractor.eval() self.stats: list[torch.Tensor] = [] self.embeddings: list[torch.Tensor] = []