-
Notifications
You must be signed in to change notification settings - Fork 710
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
320 additions
and
408 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
157 changes: 157 additions & 0 deletions
157
docs/source/markdown/guides/how_to/pipelines/tiled_ensemble.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# Tiled ensemble | ||
|
||
This guide will show you how to use **The Tiled Ensemble** method for anomaly detection. For more details, refer to the official [Paper](https://openaccess.thecvf.com/content/CVPR2024W/VAND/html/Rolih_Divide_and_Conquer_High-Resolution_Industrial_Anomaly_Detection_via_Memory_Efficient_CVPRW_2024_paper.html). | ||
|
||
The tiled ensemble approach reduces memory consumption by dividing input images into a grid of tiles and training a dedicated model for each tile location. | ||
It is compatible with any existing image anomaly detection model without the need for any modification of the underlying architecture. | ||
|
||
![Tiled ensemble flow](../../../../images/tiled_ensemble/ensemble_flow.png) | ||
|
||
```{note} | ||
This feature is experimental and may not work as expected. | ||
For any problems refer to [Issues](https://github.com/openvinotoolkit/anomalib/issues) and feel free to ask any question in [Discussions](https://github.com/openvinotoolkit/anomalib/discussions). | ||
``` | ||
|
||
## Training | ||
|
||
You can train a tiled ensemble using the training script located inside `tools/tiled_ensemble` directory: | ||
|
||
```{code-block} bash | ||
python tools/tiled_ensemble/train_ensemble.py \ | ||
--config tools/tiled_ensemble/ens_config.yaml | ||
``` | ||
|
||
By default, the Padim model is trained on **MVTec AD bottle** category using image size of 256x256, divided into non-overlapping 128x128 tiles. | ||
You can modify these parameters in the [config file](#ensemble-configuration). | ||
|
||
## Evaluation | ||
|
||
After training, you can evaluate the tiled ensemble on test data using: | ||
|
||
```{code-block} bash | ||
python tools/tiled_ensemble/eval.py \ | ||
--config tools/tiled_ensemble/ens_config.yaml \ | ||
--root path_to_results_dir | ||
``` | ||
|
||
Ensure that `root` points to the directory containing the training results, typically `results/padim/mvtec/bottle/runX`. | ||
|
||
## Ensemble configuration | ||
|
||
Tiled ensemble is configured using `ens_config.yaml` file in the `tools/tiled_ensemble` directory. | ||
It contains general settings and tiled ensemble specific settings. | ||
|
||
### General | ||
|
||
General settings at the top of the config file are used to set up the random `seed`, `accelerator` (device) and the path to where results will be saved `default_root_dir`. | ||
|
||
```{code-block} yaml | ||
seed: 42 | ||
accelerator: "gpu" | ||
default_root_dir: "results" | ||
``` | ||
|
||
### Tiling | ||
|
||
This section contains the following settings, used for image tiling: | ||
|
||
```{code-block} yaml | ||
tiling: | ||
tile_size: 256 | ||
stride: 256 | ||
``` | ||
|
||
These settings determine the tile size and stride. Another important parameter is image_size from `data` section later in the config. It determines the original size of the image. | ||
|
||
Input image is split into tiles, where each tile is of shape set by `tile_size` and tiles are taken with step set by `stride`. | ||
For example: having image_size: 512, tile_size: 256, and stride: 256, results in 4 non-overlapping tile locations. | ||
|
||
### Normalization and thresholding | ||
|
||
Next up are the normalization and thresholding settings: | ||
|
||
```{code-block} yaml | ||
normalization_stage: image | ||
thresholding: | ||
method: F1AdaptiveThreshold | ||
stage: image | ||
``` | ||
|
||
- **Normalization**: Can be applied per each tile location separately (`tile` option), after combining prediction (`image` option), or skipped (`none` option). | ||
|
||
- **Thresholding**: Can also be applied at different stages, but it is limited to `tile` and `image`. Another setting for thresholding is the method used. It can be specified as a string or by the class path. | ||
|
||
### Data | ||
|
||
The `data` section is used to configure the input `image_size` and other parameters for the dataset used. | ||
|
||
```{code-block} yaml | ||
data: | ||
class_path: anomalib.data.MVTec | ||
init_args: | ||
root: ./datasets/MVTec | ||
category: bottle | ||
train_batch_size: 32 | ||
eval_batch_size: 32 | ||
num_workers: 8 | ||
task: segmentation | ||
transform: null | ||
train_transform: null | ||
eval_transform: null | ||
test_split_mode: from_dir | ||
test_split_ratio: 0.2 | ||
val_split_mode: same_as_test | ||
val_split_ratio: 0.5 | ||
image_size: [256, 256] | ||
``` | ||
|
||
Refer to [Data](../../reference/data/image/index.md) for more details on parameters. | ||
|
||
### SeamSmoothing | ||
|
||
This section contains settings for `SeamSmoothing` block of pipeline: | ||
|
||
```{code-block} yaml | ||
SeamSmoothing: | ||
apply: True | ||
sigma: 2 | ||
width: 0.1 | ||
``` | ||
|
||
SeamSmoothing job is responsible for smoothing of regions where tiles meet - called tile seams. | ||
|
||
- **apply**: If True, smoothing will be applied. | ||
- **sigma**: Controls the sigma of Gaussian filter used for smoothing. | ||
- **width**: Sets the percentage of the region around the seam to be smoothed. | ||
|
||
### TrainModels | ||
|
||
The last section `TrainModels` contains the setup for model training: | ||
|
||
```{code-block} yaml | ||
TrainModels: | ||
model: | ||
class_path: Fastflow | ||
metrics: | ||
pixel: AUROC | ||
image: AUROC | ||
trainer: | ||
max_epochs: 500 | ||
callbacks: | ||
- class_path: lightning.pytorch.callbacks.EarlyStopping | ||
init_args: | ||
patience: 42 | ||
monitor: pixel_AUROC | ||
mode: max | ||
``` | ||
|
||
- **Model**: Specifies the model used. Refer to [Models](../../reference/models/image/index.md) for more details on the model parameters. | ||
- **Metrics**: Defines evaluation metrics for pixel and image level. | ||
- **Trainer**: _optional_ parameters, used to control the training process. Refer to [Engine](../../reference/engine/index.md) for more details. |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
seed: 42 | ||
accelerator: "gpu" | ||
default_root_dir: "results" | ||
|
||
tiling: | ||
tile_size: [128, 128] | ||
stride: 128 | ||
|
||
normalization_stage: image # on what level we normalize, options: [tile, image, none] | ||
thresholding: | ||
method: F1AdaptiveThreshold # refer to documentation for thresholding methods | ||
stage: image # stage at which we apply threshold, options: [tile, image] | ||
|
||
data: | ||
class_path: anomalib.data.MVTec | ||
init_args: | ||
root: ./datasets/MVTec | ||
category: bottle | ||
train_batch_size: 32 | ||
eval_batch_size: 32 | ||
num_workers: 8 | ||
task: segmentation | ||
transform: null | ||
train_transform: null | ||
eval_transform: null | ||
test_split_mode: from_dir | ||
test_split_ratio: 0.2 | ||
val_split_mode: same_as_test | ||
val_split_ratio: 0.5 | ||
image_size: [256, 256] | ||
|
||
SeamSmoothing: | ||
apply: True # if this is applied, area around tile seams are is smoothed | ||
sigma: 2 # sigma of gaussian filter used to smooth this area | ||
width: 0.1 # width factor, multiplied by tile dimension gives the region width around seam which will be smoothed | ||
|
||
TrainModels: | ||
model: | ||
class_path: Padim | ||
|
||
metrics: | ||
pixel: AUROC | ||
image: AUROC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
"""Run tiled ensemble prediction.""" | ||
|
||
# Copyright (C) 2024 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
from pathlib import Path | ||
|
||
from jsonargparse import ArgumentParser | ||
|
||
from anomalib.pipelines.tiled_ensemble import EvalTiledEnsemble | ||
|
||
|
||
def get_parser() -> ArgumentParser: | ||
"""Create a new parser if none is provided.""" | ||
parser = ArgumentParser() | ||
parser.add_argument("--config", type=str | Path, help="Configuration file path.", required=True) | ||
parser.add_argument("--root", type=str | Path, help="Weights file path.", required=True) | ||
|
||
return parser | ||
|
||
|
||
if __name__ == "__main__": | ||
args = get_parser().parse_args() | ||
|
||
print("Running tiled ensemble test pipeline.") | ||
# pass the path to root dir with checkpoints | ||
test_pipeline = EvalTiledEnsemble(args.root) | ||
test_pipeline.run(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
"""Run tiled ensemble training.""" | ||
|
||
# Copyright (C) 2024 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
from anomalib.pipelines.tiled_ensemble import EvalTiledEnsemble, TrainTiledEnsemble | ||
|
||
if __name__ == "__main__": | ||
print("Running tiled ensemble train pipeline") | ||
train_pipeline = TrainTiledEnsemble() | ||
# run training | ||
train_pipeline.run() | ||
|
||
print("Running tiled ensemble test pipeline.") | ||
# pass the root dir from train run to load checkpoints | ||
test_pipeline = EvalTiledEnsemble(train_pipeline.root_dir) | ||
test_pipeline.run() |