--- license: apache-2.0 library_name: pytorch pipeline_tag: tabular-classification tags: - executorch - zephyr - tinyml - anomaly-detection - time-series - industrial - cortex-m - int8 datasets: - eoinedge/heater-anomaly-windows metrics: - accuracy - precision - recall model-index: - name: AnomalyNet results: - task: type: tabular-classification name: Temperature-window anomaly detection dataset: type: eoinedge/heater-anomaly-windows name: heater-anomaly-windows (test split) metrics: - type: accuracy value: 0.9962 - type: precision value: 1.0 - type: recall value: 0.9925 --- # AnomalyNet An 842-parameter MLP that looks at 32 consecutive temperature samples (3.2 s at 10 Hz) and says whether the window is normal or contains an anomaly: a spike, a dropout, a runaway ramp or a burst of noise. It is the "second brain" in my dual-brain PLC demos: ExecuTorch runs it on the microcontroller next to a ladder-logic scan task or a Linux SoC, and only a shared variable (`p(anomaly)`) crosses between them. ``` fc1 32->24, ReLU fc2 24->2 logits [normal, anomaly] ``` Input: `(1, 32)` float, Celsius normalised as `(t - 50) / 20`. Output: 2 logits; softmax gives `p(anomaly)`. ## Files | File | What | |---|---| | `anomaly_net.py` | model definition and the normalisation constants | | `anomaly_net.pt` | trained state dict, fp32 | | `executorch/fp32.pte` | ExecuTorch program, portable fp32 kernels (5.5 KB) | | `executorch/int8-cmsis-m0plus.pte`, `-m4.pte`, `-m33.pte`, `-m7.pte` | int8 via the ExecuTorch Cortex-M quantizer (3.6 KB) | | `tflite/fp32.tflite`, `tflite/int8.tflite` | the same weights through a Keras twin for TensorFlow Lite Micro | | `test_vectors.h` | one normal and one anomaly window with reference logits | ## Results Held-out synthetic windows (dataset test split, 4,000 windows, 50 % anomalies): | Metric | Value | |---|---| | Accuracy | 99.62 % | | Precision | 100 % | | Recall | 99.25 % | | Parameters | 842 | | Inference, STM32U585 @ 160 MHz, fp32 | 1.6 ms | | Inference, nRF52833 @ 64 MHz, fp32 | 4.3 ms | | Inference, nRF9160 @ 64 MHz, fp32 | 4.0 ms | ## Training Synthetic data only: the generator in `train/train_anomaly.py` of the [UNO Q repo](https://github.com/eoinjordan/executorch-zephyr-arduino-uno-q) simulates a heater loop around 50 C with slow drift and sensor noise, and injects four anomaly types. The same generator produced the [heater-anomaly-windows](https://huggingface.co/datasets/eoinedge/heater-anomaly-windows) dataset. Adam, cross-entropy, a few hundred epochs on CPU in under a minute. ## Where it runs - [executorch-zephyr-arduino-uno-q](https://github.com/eoinjordan/executorch-zephyr-arduino-uno-q): STM32U585 + Linux side, 13x8 LED matrix chart - [executorch-zephyr-arduino-opta](https://github.com/eoinjordan/executorch-zephyr-arduino-opta): beside a ladder-logic scan task on a PLC - micro:bit v2, Thingy:91, LAUNCHXL-CC1352P1 self-tests, and the [ExecuTorch vs TFLM benchmarks](https://github.com/eoinjordan/executorch-vs-tflm-benchmarks) Background: [AI for Industrial Control Systems: Bringing Edge AI to PLCs](https://www.edgeimpulse.com/blog/transform-industrial-control-systems-with-ai-anomaly-detection-made-easy/). ## License Apache-2.0.