YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
π Motor Sound Classifier
Six deep learning architectures β GRU, LSTM, LSTM-GRU, and three custom Transformer variants β trained from scratch to classify industrial motor audio into three operational states.
π§ Overview
This project classifies the operational state of an industrial motor from raw .wav audio. Six architectures are trained and compared end-to-end on log-mel spectrogram features extracted at 16 kHz. A live Streamlit app supports single-model inference, configurable ensemble inference, and full audio visualization.
| Class | Label | Description |
|---|---|---|
engine1_good |
β Good | Motor running normally |
engine2_broken |
β οΈ Broken | Motor with fault or damage |
engine3_heavyload |
π΄ Heavy Load | Motor under heavy mechanical load |
π₯οΈ Live Demo
The app is deployed on HuggingFace Spaces:
π motor-sound-classification-syoldbw2wrk6rmcb2ckeei.streamlit.app
Upload any .wav file and get instant predictions from all six models plus an ensemble view.
ποΈ Model Architectures
Six models are trained and compared, split across two families.
Recurrent Family
| Model | Architecture | Checkpoint Size |
|---|---|---|
| GRU | 2-layer bidirectional GRU + LayerNorm | 26 MB |
| LSTM | 2-layer bidirectional LSTM + LayerNorm | 35 MB |
| LSTM-GRU | Interleaved BiLSTM β BiGRU Γ 2 + LayerNorm | 73 MB |
All recurrent models operate on mel frames as a sequence (T, 80), use hidden size 512, and pool via the final hidden state.
Transformer Family (AudioModel)
A shared AudioEncoder backbone with three positional encoding strategies:
Input (B, 1, T, 80)
β Linear projection β (B, 1, T, 1024)
β 12 Γ AudioAttentionBlock [MHA + PE + residual]
β LayerNorm + MLP (feed-forward)
β mean pool over T
β Linear classifier β 3 logits
| Model | PE Strategy | Checkpoint Size |
|---|---|---|
| AudioModel (Rotational PE) | RoPE applied per-head to Q and K vectors | 236 MB |
| AudioModel (Sinusoidal PE) | Fixed sinusoidal encoding added to input | 244 MB |
| AudioModel (Relative PE) | Learnable relative bias added to attention logits | 252 MB |
Transformer config: embed_dim=1024 Β· num_heads=16 Β· n_blocks=12 Β· max_seq_len=2048
ποΈ Audio Processing Pipeline
WAV file (any sample rate, mono or stereo)
β Resample β 16 000 Hz
β Mono mix (mean over channels if stereo)
β MelSpectrogram (n_fft=1024, hop=512, n_mels=80)
β log1p (dynamic range compression)
β z-score normalisation (per clip, std + 1e-1 for stability)
β Tensor (1, T, 80) β all six models
ποΈ Repository Structure
Motor-Sound-Classification/ β HuggingFace Space (this repo)
βββ app.py # Streamlit inference app
βββ models/
β βββ load_model.py # Downloads weights from HF Hub
βββ inference-notebook.ipynb # Step-by-step inference walkthrough
βββ motor-sound-classification.ipynb # Full training notebook
Eddy-Emmanuel/Motor_Sound_Classifier β Weights repo (separate HF repo)
βββ gru_model.pt
βββ lstm_model.pt
βββ lstm_gru_model.pt
βββ rotational_pe.pt
βββ sinusodal_pe.pt
βββ relative_pe.pt
π Run Locally
1. Clone the Space repo
git clone https://huggingface.co/spaces/Eddy-Emmanuel/Motor-Sound-Classification
cd Motor-Sound-Classification
pip install -r requirements.txt
2. Set up your HuggingFace token
Create a .env file in the project root:
HF_TOKEN=hf_your_token_here
Model weights (~866 MB total) are downloaded automatically from Eddy-Emmanuel/Motor_Sound_Classifier on first run via models/load_model.py:
import os
from dotenv import load_dotenv
from huggingface_hub import snapshot_download, login
load_dotenv()
login(token=os.getenv("HF_TOKEN"))
local_dir = snapshot_download(
repo_id="Eddy-Emmanuel/Motor_Sound_Classifier",
allow_patterns="*.pt"
)
3. Launch
streamlit run app.py
πΌοΈ App Features
π Audio Visualization
Three-panel signal analysis for any uploaded WAV:
- Waveform β raw amplitude over time
- STFT Spectrogram β power in dB over linear frequency
- Mel Spectrogram β normalized log-mel energy over 80 mel bins
π¬ Individual Models
- Model selector dropdown with per-model prediction card
- Class probability bar chart
- Full comparison table across all six models
- Grouped bar chart showing per-class confidence for every model side by side
π€ Ensemble
- Select any subset of the six loaded models
- Choose uniform average or weighted average (per-model weight sliders 0.1 β 3.0)
- Ensemble prediction card with aggregated confidence
- Individual model breakdown cards beneath the ensemble result
π¦ Dependencies
torch
torchaudio
streamlit
numpy
matplotlib
soundfile
pandas
huggingface_hub
python-dotenv
π§ Design Notes
Why six models?
This is a comparative study across recurrent and attention-based architectures for audio classification. Training all six on identical features and evaluating them individually and in ensemble isolates the contribution of architecture choice vs. positional encoding strategy.
Why RoPE, Sinusoidal, and Relative PE?
Three fundamentally different approaches to position information: RoPE encodes position in the rotation of Q/K vectors (relative, no added parameters); sinusoidal adds fixed absolute position to the input; relative PE learns a bias over pairwise token distances. Comparing them on the same encoder backbone isolates their effect.
Why log1p + z-score normalisation?log1p compresses the large dynamic range of raw mel energies. Per-clip z-score normalisation makes the model invariant to recording loudness, which varies significantly across motor operating conditions.
Why bidirectional RNNs?
For classification (not streaming), the full temporal context is available at inference time. Bidirectional encoding gives each timestep access to both past and future frames, improving the quality of the final hidden state used for classification.
π€ Author
Jimmy Edifon Emmanuel (Eddy)
AI & Computer Vision Engineer Β· Lagos, Nigeria
π License
MIT License β see LICENSE for details.