Skip to content

Commit

Permalink
✨ Add GANomaly (#70)
Browse files Browse the repository at this point in the history
* ✨ Add GANomaly
  • Loading branch information
ashwinvaidya17 committed Feb 2, 2022
1 parent f1c8a6b commit 18ce474
Show file tree
Hide file tree
Showing 11 changed files with 677 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ where the currently available models are:
- [STFPM](anomalib/models/stfpm)
- [DFM](anomalib/models/dfm)
- [DFKDE](anomalib/models/dfkde)
- [GANomaly](anomalib/models/ganomaly)

## Inference

Expand Down
2 changes: 1 addition & 1 deletion anomalib/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def get_model(config: Union[DictConfig, ListConfig]) -> AnomalyModule:
AnomalyModule: Anomaly Model
"""
openvino_model_list: List[str] = ["stfpm"]
torch_model_list: List[str] = ["padim", "stfpm", "dfkde", "dfm", "patchcore", "cflow"]
torch_model_list: List[str] = ["padim", "stfpm", "dfkde", "dfm", "patchcore", "cflow", "ganomaly"]
model: AnomalyModule

if config.openvino:
Expand Down
30 changes: 30 additions & 0 deletions anomalib/models/ganomaly/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# GANomaly: Semi-Supervised Anomaly Detection via Adversarial Training

This is the implementation of the [GANomaly](https://arxiv.org/abs/1805.06725) paper.

Model Type: Classification

## Description

GANomaly uses the conditional GAN approach to train a Generator to produce images of the normal data. This Generator consists of an encoder-decoder-encoder architecture to generate the normal images. The distance between the latent vector $z$ between the first encoder-decoder and the output vector $\hat{z}$ is minimized during training.

The key idea here is that, during inference, when an anomalous image is passed through the first encoder the latent vector $z$ will not be able to capture the data correctly. This would leave to poor reconstruction $\hat{x}$ thus resulting in a very different $\hat{z}$. The difference between $z$ and $\hat{z}$ gives the anomaly score.

## Architecture

![GANomaly Architecture](../../../docs/source/images/ganomaly/architecture.jpg "GANomaly Architecture")

## Usage

`python tools/train.py --model ganomaly`

## Benchmark

All results gathered with seed `42`.

## [MVTec Dataset](https://www.mvtec.com/company/research/datasets/mvtec-ad)

### Image-Level AUC


### Image F1 Score
19 changes: 19 additions & 0 deletions anomalib/models/ganomaly/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""GANomaly Model."""

# Copyright (C) 2020 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions
# and limitations under the License.

from .model import GanomalyLightning

__all__ = ["GanomalyLightning"]
120 changes: 120 additions & 0 deletions anomalib/models/ganomaly/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
dataset:
name: mvtec
format: mvtec
path: ./datasets/MVTec
url: ftp://guest:GU.205dldo@ftp.softronics.ch/mvtec_anomaly_detection/mvtec_anomaly_detection.tar.xz
category: bottle
task: classification
label_format: None
tiling:
apply: true
tile_size: 64
stride: null
remove_border_count: 0
use_random_tiling: False
random_tile_count: 16
image_size: 256
train_batch_size: 32
test_batch_size: 32
inference_batch_size: 32
num_workers: 32

model:
name: ganomaly
latent_vec_size: 100
n_features: 64
extra_layers: 0
add_final_conv: true
early_stopping:
patience: 3
metric: image_AUROC
mode: max
lr: 0.0002
beta1: 0.5
beta2: 0.999
wadv: 1
wcon: 50
wenc: 1
threshold:
image_default: 0
adaptive: true

project:
seed: 0
path: ./results
log_images_to: []
logger: false
save_to_csv: false

optimization:
compression:
apply: false
nncf:
apply: false
input_info:
sample_size: null
compression:
algorithm: quantization
initializer:
range:
num_init_samples: 256
update_config:
init_weights: snapshot.ckpt
hyperparameter_search:
parameters:
lr:
min: 1e-4
max: 1e-2

# PL Trainer Args. Don't add extra parameter here.
trainer:
accelerator: null
accumulate_grad_batches: 1
amp_backend: native
amp_level: O2
auto_lr_find: false
auto_scale_batch_size: false
auto_select_gpus: false
benchmark: false
check_val_every_n_epoch: 2
checkpoint_callback: true
default_root_dir: null
deterministic: true
distributed_backend: null
fast_dev_run: false
flush_logs_every_n_steps: 100
gpus: 1
gradient_clip_val: 0
limit_predict_batches: 1.0
limit_test_batches: 1.0
limit_train_batches: 1.0
limit_val_batches: 1.0
log_every_n_steps: 50
log_gpu_memory: null
max_epochs: 100
max_steps: null
min_epochs: null
min_steps: null
move_metrics_to_cpu: false
multiple_trainloader_mode: max_size_cycle
num_nodes: 1
num_processes: 1
num_sanity_val_steps: 0
overfit_batches: 0.0
plugins: null
precision: 32
prepare_data_per_node: true
process_position: 0
profiler: null
progress_bar_refresh_rate: null
reload_dataloaders_every_epoch: false
replace_sampler_ddp: true
stochastic_weight_avg: false
sync_batchnorm: false
terminate_on_nan: false
tpu_cores: null
track_grad_norm: -1
truncated_bptt_steps: null
val_check_interval: 1.0
weights_save_path: null
weights_summary: top
Loading

0 comments on commit 18ce474

Please sign in to comment.