Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ The paper can be found [here](https://openreview.net/forum?id=iMmsCI0JsS).

For installation and usage guides please refer to the [documentation](https://timesead.readthedocs.io/en/latest).

## Third-party models

TimeSeAD includes the NeuTraL-AD (Neural Transformation Learning for Anomaly Detection) implementation, which is
licensed under the AGPL-3.0 license by Robert Bosch GmbH. See `timesead/models/other/neutral_ad.py` for the license
header and make sure the AGPL requirements are compatible with your intended use.

## Citation and Contact

If you use our work, please consider citing the paper
Expand Down
46 changes: 46 additions & 0 deletions experiment_configs/recon/other/train_neutral_ad_recon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
params:
training_experiment: other.train_neutral_ad
validation_metric: best_ts_f1_score
evaluation_metrics:
- best_ts_f1_score
- ts_auprc
- best_ts_f1_score_classic
- ts_auprc_unweighted
- best_f1_score
- auprc
dataset:
name: SMDMiniDataset
training_param_updates:
dataset:
name: SMDMiniDataset
training:
epochs: 25
batch_size: 32
drop_last: True
loss:
args:
temperature: 0.1
use_euclidean: False
training_param_grid:
model_params:
num_trans:
- 4
trans_type:
- residual
enc_hdim:
- 32
enc_nlayers:
- 4
trans_nlayers:
- 4
latent_dim:
- 32
batch_norm:
- False
enc_bias:
- False
training:
optimizer:
args:
lr:
- 1.0e-3
46 changes: 46 additions & 0 deletions experiment_configs/smd/other/train_neutral_ad_on_smd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
params:
training_experiment: other.train_neutral_ad
validation_metric: best_ts_f1_score
evaluation_metrics:
- best_ts_f1_score
- ts_auprc
- best_ts_f1_score_classic
- ts_auprc_unweighted
- best_f1_score
- auprc
dataset:
name: SMDDataset
training_param_updates:
dataset:
name: SMDDataset
training:
epochs: 100
batch_size: 32
drop_last: True
loss:
args:
temperature: 0.1
use_euclidean: False
training_param_grid:
model_params:
num_trans:
- 4
trans_type:
- residual
enc_hdim:
- 32
enc_nlayers:
- 4
trans_nlayers:
- 4
latent_dim:
- 32
batch_norm:
- False
enc_bias:
- False
training:
optimizer:
args:
lr:
- 1.0e-3
2 changes: 1 addition & 1 deletion timesead/data/transforms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
TranslateXTransform,
)
from .target_transforms import ReconstructionTargetTransform, OneVsRestTargetTransform, PredictionTargetTransform, \
OverlapPredictionTargetTransform
OverlapPredictionTargetTransform, WindowLabelFilterTransform
from .window_transform import WindowTransform

from .dataset_source import DatasetSource, make_dataset_split
Expand Down
26 changes: 26 additions & 0 deletions timesead/data/transforms/target_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,29 @@ def seq_len(self) -> Union[int, List[int]]:
return parent_seq_len - self.offset

return [slen - self.offset for slen in parent_seq_len]


class WindowLabelFilterTransform(Transform):
"""
Filters windows based on their label values.

By default, only windows whose labels are entirely normal (all zeros) are kept.
"""
def __init__(self, parent: Transform, label_index: int = 0, normal_value: int = 0, keep_normal: bool = True):
super().__init__(parent)
self.label_index = label_index
self.normal_value = normal_value
self.keep_normal = keep_normal
self.indices = []
for idx in range(len(parent)):
_, targets = parent.get_datapoint(idx)
labels = targets[label_index]
is_normal = torch.all(labels == normal_value).item()
if is_normal == keep_normal:
self.indices.append(idx)

def _get_datapoint_impl(self, item: int) -> Tuple[Tuple[torch.Tensor, ...], Tuple[torch.Tensor, ...]]:
return self.parent.get_datapoint(self.indices[item])

def __len__(self) -> Optional[int]:
return len(self.indices)
3 changes: 2 additions & 1 deletion timesead/models/other/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .lstm_ae_ocsvm import LSTMAEOCSVMAnomalyDetector
from .mtad_gat import MTAD_GATLoss, MTAD_GATAnomalyDetector, MTAD_GAT
from .ncad import NCAD, NCADAnomalyDetector, NCADTrainer
from .thoc import THOC, THOCAnomalyDetector, THOCLoss, THOCTrainer
from .neutral_ad import NeutralAD, NeutralADAnomalyDetector, NeutralADLoss
from .thoc import THOC, THOCAnomalyDetector, THOCLoss, THOCTrainer
Loading