Tabular Classification
PyTorch
LiteRT
TF-Keras
ONNX
LiteRT
industrial
edge-ai
tensorflow
synthetic-data
Instructions to use sankalpsthakur/forge-tiny-drift-multiruntime with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use sankalpsthakur/forge-tiny-drift-multiruntime with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 4,273 Bytes
4483e82 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | from __future__ import annotations
import json
from collections.abc import Iterable
from dataclasses import dataclass
from pathlib import Path
import numpy as np
WINDOW_SIZE = 50
FEATURE_NAMES = (
"force_slope_kn_per_cycle",
"force_shift_kn",
"force_std_kn",
"max_deviation_mm",
"last_deviation_mm",
"force_range_kn",
)
DEFAULT_CENTER = np.asarray([0.05, 2.0, 0.8, 0.12, 0.12, 3.0], dtype=np.float32)
DEFAULT_SCALE = np.asarray([0.05, 2.0, 0.8, 0.08, 0.08, 3.0], dtype=np.float32)
DEFAULT_WEIGHT = np.asarray([2.8, 1.6, 0.5, 0.8, 0.6, 0.4], dtype=np.float32)
DEFAULT_BIAS = np.float32(-0.4)
def as_telemetry_array(values: Iterable) -> np.ndarray:
array = np.asarray(values, dtype=np.float32)
if array.ndim == 2:
array = array[None, ...]
if array.ndim != 3 or array.shape[1:] != (WINDOW_SIZE, 2):
raise ValueError(f"telemetry must have shape [batch,{WINDOW_SIZE},2]")
if not np.isfinite(array).all():
raise ValueError("telemetry contains non-finite values")
return array
def extract_features_numpy(values: Iterable) -> np.ndarray:
telemetry = as_telemetry_array(values)
force = telemetry[:, :, 0]
deviation = telemetry[:, :, 1]
x = np.arange(WINDOW_SIZE, dtype=np.float32)
x_centered = x - x.mean()
slope = (force * x_centered).sum(axis=1) / np.square(x_centered).sum()
shift = force[:, -10:].mean(axis=1) - force[:, :10].mean(axis=1)
std = force.std(axis=1)
max_deviation = deviation.max(axis=1)
last_deviation = deviation[:, -1]
force_range = force.max(axis=1) - force.min(axis=1)
return np.stack(
[slope, shift, std, max_deviation, last_deviation, force_range],
axis=1,
).astype(np.float32)
@dataclass(frozen=True)
class DriftPrediction:
probability: float
drift_detected: bool
features: dict[str, float]
runtime: str
model_version: str
def as_dict(self) -> dict:
return {
"probability": self.probability,
"drift_detected": self.drift_detected,
"features": self.features,
"runtime": self.runtime,
"model_version": self.model_version,
}
class NumpyDriftRuntime:
"""Dependency-light reference runtime used by the CPU-only Space."""
def __init__(self, weights_path: str | Path | None = None) -> None:
if weights_path is None:
weights_path = (
Path(__file__).resolve().parents[3] / "models" / "artifacts" / "weights.json"
)
path = Path(weights_path)
if path.exists():
payload = json.loads(path.read_text())
self.center = np.asarray(payload["feature_center"], dtype=np.float32)
self.scale = np.asarray(payload["feature_scale"], dtype=np.float32)
self.weight = np.asarray(payload["linear_weight"], dtype=np.float32)
self.bias = np.float32(payload["linear_bias"])
self.model_version = payload["model_version"]
else:
self.center = DEFAULT_CENTER
self.scale = DEFAULT_SCALE
self.weight = DEFAULT_WEIGHT
self.bias = DEFAULT_BIAS
self.model_version = "bootstrap-untrained"
def predict_batch(self, values: Iterable) -> tuple[np.ndarray, np.ndarray]:
features = extract_features_numpy(values)
normalized = (features - self.center) / self.scale
logits = normalized @ self.weight + self.bias
probability = 1.0 / (1.0 + np.exp(-logits))
return probability.astype(np.float32), features
def predict(self, values: Iterable, threshold: float = 0.5) -> DriftPrediction:
probabilities, features = self.predict_batch(values)
if len(probabilities) != 1:
raise ValueError("predict expects exactly one telemetry window")
probability = float(probabilities[0])
return DriftPrediction(
probability=round(probability, 6),
drift_detected=probability >= threshold,
features={
name: round(float(value), 6)
for name, value in zip(FEATURE_NAMES, features[0], strict=True)
},
runtime="numpy-reference",
model_version=self.model_version,
)
|