diff --git a/examples/timeseries/anomaly.py b/examples/timeseries/anomaly.py new file mode 100644 index 0000000000..0476923012 --- /dev/null +++ b/examples/timeseries/anomaly.py @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +import torch + +import sdm + +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + +time = torch.arange(200, device=device, dtype=torch.float32) +x = torch.stack([torch.sin(time / 12), torch.cos(time / 20)], dim=-1) +x[140:149] += 3 # Add anomalies. + +model = sdm.models.KumoAnomaly(device=device) + +# Higher reconstruction error scores indicate more likely anomalies: +score = model(x).numerical.squeeze(-1) +print(score[131:158]) diff --git a/examples/timeseries/quickstart.py b/examples/timeseries/forecast.py similarity index 100% rename from examples/timeseries/quickstart.py rename to examples/timeseries/forecast.py diff --git a/sdm/models/kumo/timeseries/anomaly/model.py b/sdm/models/kumo/timeseries/anomaly/model.py index e24c35a047..f15f06a94d 100644 --- a/sdm/models/kumo/timeseries/anomaly/model.py +++ b/sdm/models/kumo/timeseries/anomaly/model.py @@ -256,8 +256,9 @@ def forward( dim=0, ) - out = out.view(x.size())[:, :R, :D] - out = (out - x[:, :R, :D]).abs().mean(dim=-1) + out = out.view(x.size())[:, :R, :D].clamp(-1e8, 1e8) + x = x[:, :R, :D].clamp(-1e8, 1e8) + out = (out - x).abs().mean(dim=-1).clamp(max=1e8) return out.view(*B, R) def reconstruct(