MechSense AI — Engine Whisperer
Bearing fault detection from smartphone microphone audio — 4 seconds, 8 fault classes.
A seasoned mechanic takes 20 minutes with a stethoscope. This model does it in 4 seconds from outside the bonnet.
Model Description
Engine Whisperer is a convolutional neural network that classifies bearing faults from mel-spectrogram representations of engine audio. It was designed to run on-device via ONNX Runtime — the primary deployment target is a smartphone microphone, making professional-grade bearing diagnostics accessible without any specialist hardware.
The model is the core of MechSense AI, a final-year engineering capstone project combining bearing fault detection with driving style analysis.
Model Architecture
Input: (1, 1, 128, 87) mel-spectrogram ↓ 4× Conv Block (Conv2D → BatchNorm → ReLU → MaxPool → Dropout2D) Channels: 1 → 32 → 64 → 128 → 256 ↓ Adaptive Global Average Pool → (256,) ↓ FC(256 → 128) → ReLU → Dropout(0.4) → FC(128 → 8) ↓ Output: (1, 8) logits
- Parameters: 1,206,568
- Input: 2-second audio window at 22,050 Hz → 128-band mel-spectrogram
- Framework: PyTorch 2.6, exported to ONNX opset 17
- Inference: ONNX Runtime CPU (< 5ms per 2s window)
Training Strategy
The model was trained in two phases:
Phase 1 — Base training (CWRU + MFPT + IMS) Trained from scratch on three standard bearing fault benchmark datasets using:
- File-level
GroupShuffleSplitto prevent data leakage WeightedRandomSamplerfor class balance- SpecAugment (time + frequency masking) + Gaussian noise augmentation
- Cosine annealing LR schedule
- Result: 99.1% validation accuracy (file-level split, no leakage)
Phase 2 — Cross-domain fine-tuning (HUST + Paderborn) Fine-tuned on two additional datasets from independent test rigs with:
- Frozen first 2 encoder blocks (preserve low-level frequency features)
- Differential learning rates (backbone: 5×10⁻⁵, head: 5×10⁻⁴)
- Extra augmentation on minority classes (intra-class mixup + pitch shift)
- Result: 88.6% cross-domain validation accuracy
Fault Classes
| ID | Class | Description | Recommended Action |
|---|---|---|---|
| 0 | healthy |
No bearing fault detected | Regular servicing |
| 1 | inner_race_fault |
Inner race defect | Inspect within 1,000 km |
| 2 | inner_race_fault |
Inner race defect (severe) | Workshop within 200 km |
| 3 | outer_race_fault |
Outer race defect | Reduce speed, inspect soon |
| 4 | outer_race_fault |
Outer race defect (severe) | Immediate inspection |
| 5 | ball_fault |
Ball element defect | Monitor, next service |
| 6 | ball_fault |
Ball element defect (severe) | Workshop within 300 km |
| 7 | degradation |
Run-to-failure progressive wear | Plan bearing replacement |
Training Datasets
| Dataset | Source | Bearings | SR | Fault Types |
|---|---|---|---|---|
| CWRU | Case Western Reserve University | 6204 | 12 kHz | IR, OR, Ball (3 diameters × 4 loads) |
| MFPT | Machinery Failure Prevention Technology | Multiple | 97.6 kHz | IR, OR (varying loads) |
| IMS | NASA Ames PCOE | 6203 | 20 kHz | Run-to-failure (natural degradation) |
| HUST | Hanoi University of Science & Technology | 6204–6208 (5 types) | 51.2 kHz | IR, OR, Ball (3 load levels) |
| Paderborn | University of Paderborn KAt-DataCenter | 6203 | 64 kHz | IR, OR, real + artificial damage |
All datasets are publicly available for academic use. Links in the Dataset Sources section.
Performance
Cross-domain Validation (HUST + Paderborn, 956 windows, file-level split)
| Class | Precision | Recall | F1 | Support |
|---|---|---|---|---|
| healthy | 0.924 | 1.000 | 0.961 | 171 |
| inner_race_fault | 0.833 | 0.906 | 0.868 | 315 |
| outer_race_fault | 0.936 | 0.996 | 0.965 | 304 |
| ball_fault | 0.812 | 0.963 | 0.881 | 27 |
| degradation | 1.000 | 1.000 | 1.000 | 60 |
| Overall | 0.886 | 956 |
Note: Confidence level serves as a severity indicator — predictions above 85% confidence on a fault class suggest severe-stage faults requiring urgent attention.
Usage
Quick Start (Python + ONNX Runtime)
import numpy as np
import librosa
import onnxruntime as ort
CLASS_NAMES = [
"healthy", "inner_race_fault", "inner_race_fault",
"outer_race_fault", "outer_race_fault",
"ball_fault", "ball_fault", "degradation"
]
def preprocess_audio(audio_path: str, target_sr: int = 22050):
"""Load audio and convert to mel-spectrogram windows."""
audio, sr = librosa.load(audio_path, sr=target_sr, mono=True)
# Normalize
peak = np.max(np.abs(audio))
if peak > 0:
audio = audio / peak
# 2-second windows with 0.5s hop
window_samples = int(target_sr * 2.0)
hop_samples = int(target_sr * 0.5)
windows = []
for start in range(0, len(audio) - window_samples + 1, hop_samples):
w = audio[start:start + window_samples]
mel = librosa.feature.melspectrogram(
y=w, sr=target_sr, n_mels=128,
n_fft=2048, hop_length=512
)
mel_db = librosa.power_to_db(mel, ref=np.max)
mn, mx = mel_db.min(), mel_db.max()
if mx - mn > 0:
mel_db = (mel_db - mn) / (mx - mn)
windows.append(mel_db.astype(np.float32))
return np.array(windows)[:, np.newaxis, :, :] # (N, 1, 128, 87)
def predict(audio_path: str, model_path: str = "engine_whisperer_v2.onnx"):
sess = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])
specs = preprocess_audio(audio_path)
logits = sess.run(None, {"spectrogram": specs})[0] # (N, 8)
# Softmax + average over windows
exp = np.exp(logits - logits.max(axis=-1, keepdims=True))
probs = (exp / exp.sum(axis=-1, keepdims=True)).mean(axis=0) # (8,)
pred = CLASS_NAMES[probs.argmax()]
conf = float(probs.max())
return pred, conf, {CLASS_NAMES[i]: float(probs[i]) for i in range(8)}
fault_class, confidence, all_probs = predict("engine_audio.wav")
print(f"Fault: {fault_class} | Confidence: {confidence:.1%}")
Using from HuggingFace Hub
from huggingface_hub import hf_hub_download
model_path = hf_hub_download(
repo_id="YOUR_USERNAME/mechsense-engine-whisperer",
filename="engine_whisperer_v2.onnx"
)
fault_class, confidence, all_probs = predict(model_path)
Files
| File | Description | Size |
|---|---|---|
engine_whisperer_v2.onnx |
Main inference model (ONNX opset 17) | ~5 MB |
engine_whisperer_v2_best.pt |
PyTorch checkpoint (for fine-tuning) | ~5 MB |
config.json |
Class names, input specs, thresholds | < 1 KB |
Dataset Sources
- CWRU: engineering.case.edu/bearingdatacenter
- MFPT: mfpt.org/fault-data-sets
- IMS/NASA: ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository
- HUST: data.mendeley.com/datasets/cbv7jyx4p9/3
- Paderborn: mb.uni-paderborn.de/kat/forschung/bearing-datacenter
Citation
If you use this model in your research, please cite:
@misc{mechsense2026,
author = {Krishna Chandana Giri},
title = {MechSense AI: Smartphone-based Bearing Fault Detection and Driving Style Analysis},
year = {2026},
publisher = {Hugging Face},
url = {https://huggingface.co/YOUR_USERNAME/mechsense-engine-whisperer}
}
Project Links
- GitHub: github.com/YOUR_USERNAME/mechsense-ai
- Driving DNA Model: huggingface.co/YOUR_USERNAME/mechsense-driving-dna
- Live Demo: huggingface.co/spaces/YOUR_USERNAME/mechsense-demo
License
MIT License. Training datasets retain their original licenses — please refer to each dataset's terms before commercial use.
- Downloads last month
- 33
Evaluation results
- Cross-domain Validation Accuracy on CWRU + MFPT + IMS + HUST + Paderborn (combined)self-reported0.886