sisa-routineguard / README.md
koreashin's picture
Add ONNX exports (7 stages, 1.4GB) for Jetson Nano inference
a1f45db verified
metadata
language: ko
library_name: pytorch
tags:
  - anomaly-detection
  - wearable-sensors
  - elderly-monitoring
  - imu
  - heart-rate
  - edge-deployment
  - onnx
  - jetson-nano
license: mit

SISA-RoutineGuard v5b — ONNX Edition

노인 일상 패턴 이상 감지 (Galaxy Watch + Jetson Orin Nano Super)
ONNX exports for fast Jetson inference (TensorRT compatible).

📦 ONNX Models (Jetson deploy)

File Size Stage Input Output
patch_encoder.onnx 0.9 MB 1 (Phone) acc [6, 250, 3] tokens [6, 256]
minute_encoder.onnx 192.5 MB 2 patch_tokens [B, 6, 256] minute_embed [B, 768]
feature_adapter.onnx 2.7 MB 2 feature [B, 12] embed [B, 768]
hourslot_encoder.onnx 570.9 MB 3 minute_embeds [B, 60, 768] slot [B, 1024], slot_minutes [B, 60, 1024]
history_encoder.onnx 567.7 MB 4 slot_embeds [B, 90, 1024] + meta history_embeds [B, 90, 1024]
vitalguard.onnx 48.2 MB 6 vital_features [B, 60, 5] + hrv hr_residual_z + trend + context
output_heads.onnx 6.3 MB cls_pooled [B, 1024] anomaly + reason + confidence

QueryRefiner ONNX 는 cross-attention shape 복잡으로 미지원 (PyTorch ckpt만).

Total ONNX: ~1.4 GB

🚀 Jetson Inference Example

import onnxruntime as ort
import numpy as np

# TensorRT EP (Jetson에서 자동 가속)
providers = [
    'TensorrtExecutionProvider',  # Jetson Orin Nano TensorRT
    'CUDAExecutionProvider',       # fallback CUDA
    'CPUExecutionProvider',        # last resort
]

# 1. Phone 측 PatchEncoder (Phone ONNX)
phone_sess = ort.InferenceSession("patch_encoder.onnx", providers=['CPUExecutionProvider'])
patches = phone_sess.run(None, {"acc": acc_array})  # [6, 250, 3] → [6, 256]

# 2. Jetson Pipeline
me_sess = ort.InferenceSession("minute_encoder.onnx", providers=providers)
minute = me_sess.run(None, {"patch_tokens": patches.reshape(1, 6, 256)})[0]

hs_sess = ort.InferenceSession("hourslot_encoder.onnx", providers=providers)
slot, slot_minutes = hs_sess.run(None, {"minute_embeds": minute_batch})  # [B, 60, 768]

# ... history, query, heads chain

🎯 모델 사이즈 — 444.66M params

Component Params Deploy
PatchEncoder 0.22M Phone (ONNX)
MinuteEncoder 48.09M Jetson
FeatureAdapter 0.66M Jetson
HourSlotEncoder 142.60M Jetson
HistoryEncoder 141.86M Jetson
QueryRefiner 97.65M Jetson
VitalGuard 12.01M Jetson
OutputHeads 1.58M Jetson
Total 444.66M

📊 성능 (OOD: HAR-70+ 노인 70-95세, 학습 X)

시나리오 Score AUC Reason
Normal 0.0004
walk_missing 0.9995 1.000 0%
prolonged_inactivity 0.9987 1.000 5%
routine_time_shift 0.9995 1.000 100%
activity_drop 0.7145 0.950 28%
Overall 0.987

🔧 Train/Val Split + Early Stopping

  • Train/Val: 80/20 (3,277 / 819 samples)
  • Best epoch = 1, val_loss = 0.2814 (saved)
  • Early stop at epoch 13 (patience=10)
  • Overfitting 방지 검증됨

📁 PyTorch checkpoints (학습 reproducibility용)

File Size Purpose
stage1_patch.pt 879 KB PatchEncoder (also ONNX)
stage2_minute.pt 192 MB MinuteEncoder (also ONNX)
stage2_adapter.pt 2.7 MB FeatureAdapter (also ONNX)
stage3_hourslot.pt 570 MB HourSlotEncoder (also ONNX)
stage4_history.pt 567 MB HistoryEncoder (also ONNX)
stage4_refiner.pt 390 MB QueryRefiner (PyTorch only)
stage5_full.pt 1.78 GB Full model (val-split best)
stage6_vitalguard.pt 48 MB VitalGuard (also ONNX)
normalizer.pkl 405 B Feature normalizer

학습 데이터

CAPTURE-24 (151) + ArWISE V3 (10명/76일) + PPG-DaLiA (15) + WESAD (15) + MHEALTH (10). HAR-70+ (18명 70-95세)는 OOD 평가에만 사용.

Code

https://github.com/tlstngud/sisa-routineguard (PRESENTATION.md 포함)