Files
wehub-resource-sync 593b94c120
pytest / Unit Tests (push) Has been cancelled
pytest / Integration (integration_tests_a) (push) Has been cancelled
pytest / Integration (integration_tests_b) (push) Has been cancelled
pytest / Integration (integration_tests_c) (push) Has been cancelled
pytest / Integration (integration_tests_d) (push) Has been cancelled
pytest / Integration (integration_tests_e) (push) Has been cancelled
pytest / Integration (integration_tests_f) (push) Has been cancelled
pytest / Integration (integration_tests_g) (push) Has been cancelled
pytest / Integration (integration_tests_h) (push) Has been cancelled
pytest / Integration (integration_tests_i) (push) Has been cancelled
pytest / Integration (integration_tests_j) (push) Has been cancelled
pytest / Distributed (distributed_a) (push) Has been cancelled
pytest / Distributed (distributed_b) (push) Has been cancelled
pytest / Distributed (distributed_c) (push) Has been cancelled
pytest / Distributed (distributed_d) (push) Has been cancelled
pytest / Distributed (distributed_e) (push) Has been cancelled
pytest / Distributed (distributed_f) (push) Has been cancelled
pytest / Minimal Install (push) Has been cancelled
pytest / Event File (push) Has been cancelled
pytest (slow) / py-slow (push) Has been cancelled
Publish JSON Schema / publish-schema (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:49:20 +08:00
..

Anomaly Detection with Deep SVDD, SAD, and DROCC

Open In Colab

This example shows how to train an anomaly detection model with Ludwig using the anomaly output feature type. The model learns a compact representation of "normal" sensor data using three complementary hypersphere-based objectives:

  • Deep SVDD — unsupervised, trains only on normal samples
  • Deep SAD — semi-supervised, uses a small set of labeled anomalies at training time
  • DROCC — unsupervised with adversarial robustness, recommended for expressive encoders

At inference time each sample receives an anomaly_score equal to its squared distance from the learned hypersphere centre. Higher scores indicate more anomalous samples.

Prerequisites

pip install ludwig

Dataset

The example uses a synthetic sensor dataset with four numeric features (sensor_a, sensor_b, sensor_c, timestamp_hour). Normal samples are drawn from a Gaussian distribution centred at the origin; anomalous samples have a large offset. The train split contains only normal samples; the test split contains both normal and anomalous samples for evaluation.

Loss variants

Deep SVDD (unsupervised)

output_features:
  - name: anomaly
    type: anomaly
    loss:
      type: deep_svdd
      nu: 0.1   # fraction of points allowed outside the hypersphere

Hard-boundary objective: minimise the mean squared distance of all normal training representations to the hypersphere centre c. The nu parameter controls soft-boundary relaxation (set to 0 for hard SVDD).

Full config: config_deep_svdd.yaml

Deep SAD (semi-supervised)

output_features:
  - name: anomaly
    type: anomaly
    loss:
      type: deep_sad
      eta: 1.0   # weight for the labeled anomaly repulsion term

Extends Deep SVDD with labeled anomaly support. Normal and unlabeled samples (label 0 or -1) are pulled toward c; labeled anomalies (label 1) are pushed away. Provide a small fraction of labeled anomaly rows in the training data with anomaly=1.

Full config: config_deep_sad.yaml

DROCC (robust unsupervised)

output_features:
  - name: anomaly
    type: anomaly
    loss:
      type: drocc
      perturbation_strength: 0.1
      num_perturbation_steps: 5

Prevents hypersphere collapse via an adversarial perturbation regulariser. Recommended when using expressive encoders (e.g. transformers) that are prone to degenerate solutions where all representations collapse to a single point.

Full config: config_drocc.yaml

Running the example

CLI

# Train
ludwig train --config config_deep_svdd.yaml --dataset /tmp/sensors_train.csv

# Predict (score test samples)
ludwig predict --model_path results/experiment_run/model \
               --dataset /tmp/sensors_test.csv

# Evaluate (requires labeled anomaly column in test CSV)
ludwig evaluate --model_path results/experiment_run/model \
                --dataset /tmp/sensors_test.csv

Python API

import pandas as pd
from ludwig.api import LudwigModel

# Load data
train_df = pd.read_csv("/tmp/sensors_train.csv")
test_df = pd.read_csv("/tmp/sensors_test.csv")

# Train
model = LudwigModel("config_deep_svdd.yaml", logging_level="ERROR")
results = model.train(dataset=train_df)

# Predict — returns a DataFrame with anomaly_score_predictions column
predictions, _ = model.predict(dataset=test_df)
print(predictions[["anomaly_anomaly_score_predictions"]].describe())

For a full walkthrough including score distribution plots and AUC comparison, open the notebook in Colab:

Open In Colab

Files

File Description
anomaly_detection.ipynb End-to-end Colab notebook
config_deep_svdd.yaml Deep SVDD config
config_deep_sad.yaml Deep SAD (semi-supervised) config
config_drocc.yaml DROCC config
train.py Standalone training and evaluation script