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.
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
All datasets are publicly available for academic use. Links in the Dataset Sources section.
1import numpy as np
2import librosa
3import onnxruntime as ort
4
5CLASS_NAMES = [
6 "healthy", "inner_race_fault", "inner_race_fault",
7 "outer_race_fault", "outer_race_fault",
8 "ball_fault", "ball_fault", "degradation"
9]
10
11def preprocess_audio(audio_path: str, target_sr: int = 22050):
12 """Load audio and convert to mel-spectrogram windows."""
13 audio, sr = librosa.load(audio_path, sr=target_sr, mono=True)
14
15 # Normalize
16 peak = np.max(np.abs(audio))
17 if peak > 0:
18 audio = audio / peak
19
20 # 2-second windows with 0.5s hop
21 window_samples = int(target_sr * 2.0)
22 hop_samples = int(target_sr * 0.5)
23 windows = []
24 for start in range(0, len(audio) - window_samples + 1, hop_samples):
25 w = audio[start:start + window_samples]
26 mel = librosa.feature.melspectrogram(
27 y=w, sr=target_sr, n_mels=128,
28 n_fft=2048, hop_length=512
29 )
30 mel_db = librosa.power_to_db(mel, ref=np.max)
31 mn, mx = mel_db.min(), mel_db.max()
32 if mx - mn > 0:
33 mel_db = (mel_db - mn) / (mx - mn)
34 windows.append(mel_db.astype(np.float32))
35
36 return np.array(windows)[:, np.newaxis, :, :] # (N, 1, 128, 87)
37
38
39def predict(audio_path: str, model_path: str = "engine_whisperer_v2.onnx"):
40 sess = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])
41 specs = preprocess_audio(audio_path)
42 logits = sess.run(None, {"spectrogram": specs})[0] # (N, 8)
43
44 # Softmax + average over windows
45 exp = np.exp(logits - logits.max(axis=-1, keepdims=True))
46 probs = (exp / exp.sum(axis=-1, keepdims=True)).mean(axis=0) # (8,)
47
48 pred = CLASS_NAMES[probs.argmax()]
49 conf = float(probs.max())
50 return pred, conf, {CLASS_NAMES[i]: float(probs[i]) for i in range(8)}
51
52
53fault_class, confidence, all_probs = predict("engine_audio.wav")
54print(f"Fault: {fault_class} | Confidence: {confidence:.1%}")
1from huggingface_hub import hf_hub_download
2
3model_path = hf_hub_download(
4 repo_id="YOUR_USERNAME/mechsense-engine-whisperer",
5 filename="engine_whisperer_v2.onnx"
6)
7fault_class, confidence, all_probs = predict(model_path)
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-engine-whisperer}
7}
MIT License. Training datasets retain their original licenses — please refer to each
dataset's terms before commercial use.