Compressor sound diagnosis

Can an existing model hear which fault a compressor has?

An exploratory baseline on 1,800 one-second recordings of one air compressor in 8 states (healthy + 7 faults).

Yes, on this dataset, when you show it a few examples. With 5 labelled clips per fault, the best existing model (FISHER, a model pre-trained on industrial sounds) names the right fault % of the time, and % with 10 clips. Simple hand-built sound features are close behind at %.

Without examples it does not work: naming the fault "zero-shot" scored % (Gemini 3.1 Pro) and % (CLAP), against 12.5% for a random guess.

It works as "learn from a few examples of each fault", not as "recognise faults it has never been shown". Every clip here comes from one compressor in one lab, so the next test is a second machine.

Best model, 5 examples per fault
%
FISHER, mean of 10 random draws
1 example per fault
%
same model
Zero-shot, best
%
random guess = 12.5%
Answer time
Healthy vs any fault
Never confused
by any supervised model

2 · The setup in one glance

One compressor, eight states, 1-second clips

The data is the public IIT Kanpur air-compressor dataset: a single-stage reciprocating compressor recorded with one microphone in one lab, 225 clips per state, each 1 second long. Seven faults were deliberately introduced one at a time.

Models compared

"Frozen" means no model was re-trained. Each model turns a clip into a numeric fingerprint, and a small standard classifier (logistic regression or SVM) learns the faults from the labelled examples.

3 · Listen

What each state sounds like

One clip per state, picked automatically as the most typical-sounding recording of its class (closest to the class's average spectrum). Each clip is 1 second; under the spectrogram, brighter means louder at that frequency. Headphones help: the differences are subtle.

5 · What it gets wrong

Where the best model slips

Rows: the actual state. Columns: what the model said. Diagonal = correct. Shading = share of that row.

Why these mix-ups make sense. The confusions come in two families: valve faults with each other (LIV, LOV, NRV) and mechanical faults with each other (Bearing, Flywheel, Piston). The most-confused classes sound almost identical on average: Bearing and Flywheel's average spectra are only dB apart, about the same as the spread between clips of a single state. Healthy is – dB away from every fault, which is why it is never confused.

Listen to the mistakes

All clips this model got wrong in the draw above. Every one of them is still closer to its own class's average sound than to the class it was mistaken for, so they look like borderline recordings, not mislabelled files.

6 · Can it identify useful problems on its own?

Naming the fault without examples

No. Without examples, both approaches are at chance: % (Gemini) and % (CLAP) vs 12.5% for guessing.

Telling which fault it is works well, but only after the model has been shown labelled examples of each fault (section 4). The question here is whether a model can name a fault it has never been shown. Two attempts:

Gemini's full confusion matrix (50 kHz, 160 clips)

Rows: actual state. Columns: Gemini's answer. Bottom row: how often each answer was given.

7 · Caveats

Why "~100%" is less impressive than it sounds

  1. One compressor, one lab, one microphone. Every result is "telling apart recordings from the same machine". Nothing here shows that a model trained on this data works on another compressor, room or microphone. Whether it does is the most important open question, and it is untested.
  2. Near-100% is expected on this dataset. The original paper reports ~99.8% with classic features; our hand-built features also reach 100% under 5-fold CV. Because the task is this easy, the dataset can only show what pre-trained models add when labels are scarce (1–3 examples per fault).
  3. Each fault was probably recorded in its own session. The label is therefore tangled up with everything else about that session (background noise, microphone placement, tank pressure). The block split rules out drift within a session, but this data can't separate "the fault" from "the day it was recorded".
  4. Sample rate. The files don't state it. We concluded 50 kHz (each file = 1 s): the original recordings are documented at 50 kHz, and the compressor's piston rhythm then works out to ~440 rpm, a normal speed (16 kHz would imply an implausible ~140 rpm). We ran every pre-trained model under both 50 kHz and 16 kHz. The conclusions didn't change, only the ranking: the general audio models score a few points higher when the clip is read as 16 kHz (played slower), while FISHER is best at 50 kHz. Use the toggle in section 4 to compare.
  5. A recording artefact. of the 1,800 files contain a click at exactly the same sample (the midpoint), where two segments seem to have been joined (none in Healthy). It makes those clips slightly harder to classify, not easier, so it doesn't inflate the scores.
  6. What failed or was skipped. FISHER initially failed to load with the current version of the transformers library. It ran after pinning an older version, with no change to the model. EAT was not run (the brief allowed either Dasheng or EAT; Dasheng was used). I compared the misclassified clips by their spectra rather than by ear.

8 · Next steps

Promising, with one test to run first

Cost assumptions: one 1-second clip per compressor per minute; servers planned at 50% of their measured speed; AWS on-demand list prices (c7i.xlarge CPU server, g4dn.xlarge T4 GPU server) and Google's Gemini list price, checked 2026-10-29. Speeds were measured on a Kaggle 4-vCPU machine and T4 GPU (handcrafted features: on a laptop core). Every row is in cost_at_scale.csv.

9 · Method & reproducibility

How to re-run it

All code, results and the full technical write-up are in the repository: github.com/Jivraj-18/machine-sound-diagnosis (REPORT.md).

python features_handcrafted.py --sr 50000        # handcrafted features (CPU)
python embed_pretrained.py --raw cache/raw.npz    # pre-trained embeddings (GPU; ran on a Kaggle T4)
python zeroshot_clap.py
python zeroshot_gemini.py --sr 50k                # needs a Gemini API key
python evaluate.py                                # results.csv, confusion matrices, misclassified clips
python analyze_misses.py && python cost_estimate.py && python build_site.py