Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d6aa4bb
feat: add EfficientAD algorithm package
DeepKnowledge1 Aug 27, 2026
8ca3122
feat: implement EfficientAD with native AnomaVision interface
DeepKnowledge1 Aug 27, 2026
be5e7d1
fix: align EfficientAD student and teacher feature strides
DeepKnowledge1 Aug 27, 2026
b42cc12
fix: keep EfficientAD compatible with shared normalized dataset
DeepKnowledge1 Aug 27, 2026
99459b4
feat: expose EfficientAD from AnomaVision API
DeepKnowledge1 Aug 27, 2026
1f1b120
feat: route training through configurable EfficientAD implementation
DeepKnowledge1 Aug 27, 2026
536ac36
refactor: preserve training workflow while adding EfficientAD
DeepKnowledge1 Aug 27, 2026
0b0b8ec
feat: support model.name as a native algorithm selector
DeepKnowledge1 Aug 27, 2026
a29eeef
docs: add EfficientAD configuration options and selector
DeepKnowledge1 Aug 27, 2026
f66626a
docs: add EfficientAD CPU example configuration
DeepKnowledge1 Aug 27, 2026
c110401
test: add EfficientAD fit and validation coverage
DeepKnowledge1 Aug 27, 2026
fdfe45f
docs: document native EfficientAD workflow
DeepKnowledge1 Aug 27, 2026
e915967
docs: clean EfficientAD documentation
DeepKnowledge1 Aug 27, 2026
d4e3ef8
docs: document EfficientAD as a first-class algorithm
DeepKnowledge1 Aug 27, 2026
fb2d93b
test: validate native model.name algorithm selection
DeepKnowledge1 Aug 27, 2026
d8923db
refactor: preserve existing training CLI and add EfficientAD routing
DeepKnowledge1 Aug 27, 2026
73d365a
docs: add EfficientAD configuration reference
DeepKnowledge1 Aug 27, 2026
a2aad29
fix: make EfficientAD ONNX export free of data-dependent training check
DeepKnowledge1 Aug 27, 2026
c917a9e
cofig
DeepKnowledge1 Aug 27, 2026
8945f40
fix(efficientad): make ONNX export skip data-dependent training check
DeepKnowledge1 Aug 27, 2026
6ba2daf
fix: add EfficientAD inference threshold
DeepKnowledge1 Aug 27, 2026
fd9908a
docs: document EfficientAD-specific thresholding
DeepKnowledge1 Aug 27, 2026
99ac8c8
fix: lower EfficientAD detection threshold
DeepKnowledge1 Aug 27, 2026
e6e195e
fix: calibrate EfficientAD threshold from normal training scores
DeepKnowledge1 Aug 27, 2026
34ba07d
feat: persist calibrated EfficientAD threshold
DeepKnowledge1 Aug 27, 2026
7b3cb62
config: remove hard-coded EfficientAD threshold
DeepKnowledge1 Aug 27, 2026
fd6f225
feat: load calibrated EfficientAD thresholds for detection
DeepKnowledge1 Aug 27, 2026
75a4e6f
feat: auto-load EfficientAD threshold in detect CLI
DeepKnowledge1 Aug 27, 2026
a7cf0f1
fix: resolve EfficientAD algorithm from config before threshold load
DeepKnowledge1 Aug 27, 2026
82aeb13
test: verify EfficientAD threshold calibration
DeepKnowledge1 Aug 27, 2026
2895b06
test: verify persisted EfficientAD threshold loading
DeepKnowledge1 Aug 27, 2026
5f0cdf2
docs: remove EfficientAD hard-coded threshold from example
DeepKnowledge1 Aug 27, 2026
567d11b
fix EfficientAD pipeline, calibration, and localization
DeepKnowledge1 Aug 27, 2026
7177d64
fix EfficientAD inference tensor autograd conflict
DeepKnowledge1 Aug 27, 2026
5ffac4f
fix EfficientAD scoring and inference performance
DeepKnowledge1 Aug 27, 2026
929234b
make EfficientAD artifact directly exportable
DeepKnowledge1 Aug 27, 2026
6ed047f
fix EfficientAD threshold loading for exported models
DeepKnowledge1 Aug 27, 2026
509c602
fix EfficientAD threshold sidecar format
DeepKnowledge1 Aug 27, 2026
e95b4b3
restore detection timing and performance reporting
DeepKnowledge1 Aug 27, 2026
dfa29b4
add EfficientAD support to autopilot
DeepKnowledge1 Aug 27, 2026
d99de17
test
DeepKnowledge1 Aug 27, 2026
f8090c1
fix autopilot EfficientAD support and restore HTML report
DeepKnowledge1 Aug 27, 2026
ce2a4ca
restore rich autopilot HTML dashboard
DeepKnowledge1 Aug 27, 2026
afb4230
fix autopilot JSON serialization for numpy metrics
DeepKnowledge1 Aug 27, 2026
d111d76
fix autopilot test compatibility and preserve rich report
DeepKnowledge1 Aug 27, 2026
fe8966e
test: match autopilot report metric capitalization
DeepKnowledge1 Aug 28, 2026
97e50f1
readme autopilot and pre-commit
DeepKnowledge1 Aug 28, 2026
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
105 changes: 54 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@

AnomaVision is a computer vision project for finding **defects and unusual patterns** in images.

It supports two anomaly detection methods:
It supports three anomaly detection methods:

- **PaDiM** β€” a simple and fast baseline.
- **PatchCore** β€” a lightweight memory-based method.
- **EfficientAD** β€” a student/teacher model with a compact reconstruction branch for fast anomaly detection.

You only need **normal (`good`) images** to train the anomaly detector.

Expand All @@ -43,6 +44,7 @@ You only need **normal (`good`) images** to train the anomaly detector.
- Create anomaly heatmaps showing where the problem is.
- Export models to **ONNX, OpenVINO, and TensorRT**.
- Export and compile **PaDiM and PatchCore to XModel for the AMD/Xilinx Kria KV260**.
- Switch between PaDiM, PatchCore, and EfficientAD without changing the CLI workflow.

## Quick start

Expand All @@ -53,31 +55,19 @@ You only need **normal (`good`) images** to train the anomaly detector.
```bash
git clone https://github.com/DeepKnowledge1/AnomaVision.git
cd AnomaVision

# Create and activate a virtual environment
uv venv --python 3.11 .venv
source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1

# Install with your hardware extra
source .venv/bin/activate # Windows: .venv\\Scripts\\Activate.ps1
uv sync --extra cpu # CPU
uv sync --extra cu121 # CUDA 12.1
```

---

#### Option B β€” From PyPI (production / quick start)

```bash
# CPU Β· Mac, CI runners, edge devices
uv pip install "anomavision[cpu]"

# NVIDIA GPU Β· pick your CUDA version
uv pip install "anomavision[cu118]" # CUDA 11.8
uv pip install "anomavision[cu121]" # CUDA 12.1
uv pip install "anomavision[cu124]" # CUDA 12.4
uv pip install "anomavision[cu121]"
```


For other environments, see [Installation](docs/installation.md).

### 2. Prepare your images
Expand All @@ -88,9 +78,6 @@ Use a simple MVTec-style folder structure:
dataset/
└── bottle/
β”œβ”€β”€ ground_truth/
β”‚ β”œβ”€β”€ broken_large/
β”‚ β”œβ”€β”€ broken_small/
β”‚ └── contamination/
β”œβ”€β”€ test/
β”‚ β”œβ”€β”€ broken_large/
β”‚ β”œβ”€β”€ broken_small/
Expand All @@ -102,33 +89,56 @@ dataset/

Training uses the **good** images. Test images can contain defects.

### 3. Train
### 3. Choose an algorithm

The existing configuration format works unchanged:

```yaml
algorithm: padim
```

Switch to EfficientAD by changing one value:

```yaml
algorithm: efficientad
```

You can also use the native model selector:

```yaml
model:
name: efficientad
```

Create or edit `config.yml` and point `dataset_path` to your dataset.
The CLI commands remain the same.

Then run:
### 4. Train

```bash
anomavision train --config config.yml
```

PaDiM is the default model. For PatchCore, set `algorithm: patchcore` in the configuration.
For a quick EfficientAD configuration, see [`examples/efficientad_cpu.yml`](examples/efficientad_cpu.yml).

### 4. Detect
### 5. Detect

```bash
anomavision detect --config config.yml --img_path ./dataset/bottle/test
anomavision detect --config config.yml --model model.pt --img_path ./test_images
```

### 5. Export
### 6. Export

For a portable model, ONNX is a good place to start:
```bash
anomavision export --config config.yml --model model.pt --format onnx
```

### 7. Evaluate

```bash
anomavision export --config config.yml --format onnx
anomavision eval --config config.yml --model model.pt --class_name bottle
```

For more export options, see [Export and deployment](docs/production_deployment.md).
For EfficientAD-specific options and limitations, see [EfficientAD](docs/efficientad.md).

## KV260 support

Expand All @@ -142,32 +152,29 @@ PyTorch β†’ INT8 quantization β†’ XModel β†’ KV260 DPU compilation

Both PaDiM and PatchCore currently compile with **1 DPU subgraph** in the KV260 compiler.

The complete setup and commands are in:

**[KV260 XModel Guide](docs/kv260_xmodel.md)**
The complete setup and commands are in the [KV260 XModel Guide](docs/kv260_xmodel.md).

> XModel compilation has been validated in the Vitis AI environment. Final on-device KV260 validation requires the physical hardware.


## Production Autopilot

**Production Autopilot is the easiest way to move from two trained models to one deployable choice.** It compares PaDiM and ultra-light PatchCore on the same labeled test split, calibrates a separate threshold for each, profiles median and P95 latency on your hardware, checks localization health, and packages the selected artifact with a self-contained HTML dashboard.

Train both candidate models first, then run the complete labeled split on CPU:

```bash
anomavision autopilot \
--config config.yml \
--padim_model ./distributions/padim/bottle/anomav_exp/model.pt \
--patchcore_model ./distributions/patchcore/bottle/anomav_exp/model.pt \
--device cpu \
--validation_split 1.0 \
--target_latency_ms 50 \
anomavision autopilot `
--config config.yml `
--padim_model ./distributions/padim/bottle/anomav_exp/model.pt `
--patchcore_model ./distributions/patchcore/bottle/anomav_exp/model.pt `
--efficientad_model ./distributions/efficientad/bottle/anomav_exp/model.onnx `
--device cpu `
--validation_split 1.0 `
--target_latency_ms 50 `
--output_dir ./production_package
```

Open `production_package/production_autopilot_report.html` to see the selected model, AUROC, calibrated threshold, localization diagnostics, memory, median latency, P95 latency, and deployment recommendation. The package also contains `deployment_manifest.json`, `localization_report.md`, and the selected model artifact. See [`docs/production_deployment.md`](docs/production_deployment.md) for GPU, TensorRT, INT8, and packaging details.

Open `production_package/production_autopilot_report.html` to see the selected model, AUROC, calibrated threshold, localization diagnostics, memory, median latency, P95 latency, and deployment recommendation. See [`docs/production_deployment.md`](docs/production_deployment.md) for details.

## Documentation

Expand All @@ -176,6 +183,7 @@ Open `production_package/production_autopilot_report.html` to see the selected m
| Quick start | [`docs/quickstart.md`](docs/quickstart.md) |
| Installation | [`docs/installation.md`](docs/installation.md) |
| CLI and configuration | [`docs/cli.md`](docs/cli.md), [`docs/config.md`](docs/config.md) |
| EfficientAD | [`docs/efficientad.md`](docs/efficientad.md) |
| Python API | [`docs/api.md`](docs/api.md) |
| KV260 / XModel | [`docs/kv260_xmodel.md`](docs/kv260_xmodel.md) |
| Production deployment | [`docs/production_deployment.md`](docs/production_deployment.md) |
Expand All @@ -186,23 +194,18 @@ Open `production_package/production_autopilot_report.html` to see the selected m

## Python example

You can also use AnomaVision directly from Python:

```python
import torch
from torch.utils.data import DataLoader
import anomavision
from torch.utils.data import DataLoader

train_set = anomavision.AnodetDataset("./dataset/bottle/train/good")
train_loader = DataLoader(train_set, batch_size=16, shuffle=False)

model = anomavision.Padim(backbone="resnet18", device=torch.device("cpu"))
model.fit(train_loader)
train_loader = DataLoader(train_set, batch_size=1, shuffle=False)

batch = next(iter(train_loader))
if isinstance(batch, (tuple, list)):
batch = batch[0]
model = anomavision.EfficientAD(device=torch.device("cpu"))
model.fit(train_loader, epochs=1)

batch = next(iter(train_loader))[0]
scores, maps = model.predict(batch)
```

Expand Down
1 change: 1 addition & 0 deletions anomavision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"""

from .algorithm.common.feature_extraction import ResnetEmbeddingsExtractor
from .algorithm.efficientad import EfficientAD
from .algorithm.padim import Padim
from .algorithm.patchcore import PatchCore
from .datasets.dataset import AnodetDataset
Expand Down
5 changes: 5 additions & 0 deletions anomavision/algorithm/efficientad/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""EfficientAD anomaly detection algorithm."""

from .efficientad import EfficientAD

__all__ = ["EfficientAD"]
Loading
Loading