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 GroupShuffleSplit to prevent data leakage
  • WeightedRandomSampler for 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

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

License

MIT License. Training datasets retain their original licenses — please refer to each dataset's terms before commercial use.

Downloads last month
33
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Evaluation results

  • Cross-domain Validation Accuracy on CWRU + MFPT + IMS + HUST + Paderborn (combined)
    self-reported
    0.886