Views
No views yet
lstm_style.onnx)(1, 10, 20) — 10 consecutive 30-second feature windows, 20 features each(1, 3) logits → [normal, drowsy, aggressive]57.4% vs 33.3% random baseline — cross-driver generalisation is inherently limited with 6 drivers. Performance scales with more diverse training drivers.
driver_encoder.onnx)(1, 10, 20) — same format as LSTM(1, 32) — L2-normalised driver embeddingwear_predictor.onnx)(1, 20) — 20 driving features(1, 3) → [clutch_mult, brake_mult, tyre_mult] in range [1.0, 3.0]1features = [
2 mean_magnitude, std_magnitude, max_magnitude, pct95_magnitude, # 0-3
3 mean_longitudinal, std_longitudinal, max_longitudinal, pct95_long, # 4-7
4 mean_lateral, std_lateral, max_lateral, # 8-10
5 mean_jerk, std_jerk, max_jerk, # 11-13
6 braking_events, acceleration_events, direction_changes, # 14-16
7 smoothness_magnitude, smoothness_longitudinal, std_vertical, # 17-19
8]| Dataset | Drivers | Duration | Behaviours | Sensors |
|---|---|---|---|---|
| UAH-DriveSet | 6 | 500+ min | Normal, Drowsy, Aggressive | Accelerometer, Gyroscope, GPS |
1import numpy as np
2import onnxruntime as ort
3from huggingface_hub import hf_hub_download
4
5REPO = "YOUR_USERNAME/mechsense-driving-dna"
6
7# Download models
8lstm_path = hf_hub_download(REPO, "lstm_style.onnx")
9encoder_path = hf_hub_download(REPO, "driver_encoder.onnx")
10wear_path = hf_hub_download(REPO, "wear_predictor.onnx")
11
12# Load sessions
13lstm_sess = ort.InferenceSession(lstm_path, providers=["CPUExecutionProvider"])
14encoder_sess = ort.InferenceSession(encoder_path, providers=["CPUExecutionProvider"])
15wear_sess = ort.InferenceSession(wear_path, providers=["CPUExecutionProvider"])
16
17STYLE_NAMES = ["normal", "drowsy", "aggressive"]
18COMPONENTS = ["clutch", "brake", "tyre"]
19BASELINE_KM = {"clutch": 80000, "brake": 40000, "tyre": 50000}
20
21def analyse_session(features: np.ndarray):
22 """
23 features: (N, 20) array of driving feature windows
24 N >= 10 recommended for LSTM (padded with zeros if shorter)
25 """
26 SEQ_LEN = 10
27 if len(features) >= SEQ_LEN:
28 seq = features[-SEQ_LEN:][np.newaxis, :, :].astype(np.float32)
29 else:
30 pad = np.zeros((SEQ_LEN - len(features), 20), dtype=np.float32)
31 seq = np.concatenate([pad, features], axis=0)[np.newaxis]
32
33 # Driving style
34 logits = lstm_sess.run(None, {"input": seq})[0]
35 exp = np.exp(logits - logits.max(axis=-1, keepdims=True))
36 probs = exp / exp.sum(axis=-1, keepdims=True)
37 style = STYLE_NAMES[probs[0].argmax()]
38
39 # Driver embedding
40 emb = encoder_sess.run(None, {"input": seq})[0][0] # (32,)
41 emb = emb / (np.linalg.norm(emb) + 1e-8)
42
43 # Wear prediction
44 wear_preds = wear_sess.run(
45 None, {"input": features.astype(np.float32)}
46 )[0] # (N, 3)
47 mean_wear = wear_preds.mean(axis=0)
48
49 wear_result = {}
50 for i, comp in enumerate(COMPONENTS):
51 mult = float(np.clip(mean_wear[i], 1.0, 3.0))
52 wear_result[comp] = {
53 "multiplier" : round(mult, 3),
54 "km_remaining" : int(BASELINE_KM[comp] / mult),
55 }
56
57 return {
58 "style" : style,
59 "confidence": float(probs[0].max()),
60 "wear" : wear_result,
61 "embedding": emb.tolist(),
62 }| File | Description |
|---|---|
lstm_style.onnx | LSTM driving style classifier |
driver_encoder.onnx | Siamese encoder — 32-dim driver embedding |
wear_predictor.onnx | Component wear MLP |
lstm_style_best.pt | PyTorch LSTM checkpoint |
siamese_driver_best.pt | PyTorch Siamese checkpoint |
wear_predictor_best.pt | PyTorch wear predictor checkpoint |
config.json | Feature names, class labels, baselines |
1@misc{mechsense2026,
2 author = {Krishna Chandana Giri},
3 title = {MechSense AI: Smartphone-based Bearing Fault Detection and Driving Style Analysis},
4 year = {2026},
5 publisher = {Hugging Face},
6 url = {https://huggingface.co/YOUR_USERNAME/mechsense-driving-dna}
7}