Engine Sound Classifier (PANNs CNN14 fine-tune)

A fine-tuned PANNs CNN14 (pretrained on AudioSet) that classifies short audio clips of running engines into one of 34 configurations β€” cylinder count, layout, and stroke type (e.g. i4, v8_cross, single_two_stroke, 2_rotor).

Status: early, ambitious, not yet accurate. This is a first published checkpoint, shared to show the approach and current state, warts included. Recording-level balanced accuracy is ~0.33 on held-out test data (random guessing over 34 classes is ~0.03).

An informational demo Space (sample clips, performance breakdown) is at joakes90/engine-sound-classifier. The training code, notebook, and full diagnostic write-up live at github.com/joakes90/auto_sound_train.

Files

  • best_model_run_d_soft_weights.pth β€” fine-tuned state dict (~325 MB), Run D checkpoint (best balanced accuracy so far).
  • class_names.json β€” ordered list of the 34 class labels the output layer corresponds to.

Model details

  • Architecture: CNN14 from PANNs, pretrained on AudioSet, with the final fc_audioset layer replaced by a 34-way linear head and fine-tuned.
  • Input: mono audio, resampled to 32 kHz, in 2-second windows (matching the training manifest's window length).
  • Output: softmax over 34 engine configurations. For clips longer than 2s, run overlapping windows (e.g. 1s hop) and average per-window probabilities before taking the top class β€” this "recording-level" pooling is consistently more accurate than scoring a single window.

Classes

2_rotor, h12, h2, h4, h6, i2_180, i2_180_two_stroke, i2_270, i2_360, i2_360_two_stroke, i3, i4, i4_crossplane, i4_diesel, i5, i5_diesel, i6, i6_diesel, single_four_stroke, single_two_stroke, v10_72, v12, v2_45, v2_90, v4, v4_two_stroke, v6_120, v6_60, v6_90_even, v8_cross, v8_diesel, v8_flat, v8_voodoo, vr6

Performance

Run Change Balanced acc Micro acc
A baseline (no regularization) β€” 0.38 (overfit)
B + SpecAugment/noise/mixup 0.297 0.311 (underfit)
C fixed SpecAugment time-mask scale 0.323 0.343
D + softened class weights (counts^-0.5) 0.330 0.376

This checkpoint is Run D. Cylinder-family accuracy (does it at least get the cylinder count right) is meaningfully higher than exact-class accuracy β€” most confusion is between siblings within the same engine family, not wild misfires. Known weak spots: engines with many cylinders (8/12) are confused with close siblings far more than 1–2 cylinder engines, and a couple of classes (v12, 2_rotor) remain poorly calibrated. Full diagnosis in FINDINGS.md in the training repo.

Usage

import json
import torch
from huggingface_hub import hf_hub_download
from panns_inference import AudioTagging

REPO_ID = "joakes90/engine_sound_cassifier"
CHECKPOINT = "best_model_run_d_soft_weights.pth"

class_names = json.load(
    open(hf_hub_download(REPO_ID, "class_names.json"))
)["class_names"]

# Loads PANNs' pretrained AudioSet CNN14, then swaps in our fine-tuned head.
at = AudioTagging(checkpoint_path=None, device="cpu")
backbone = at.model.module if isinstance(at.model, torch.nn.DataParallel) else at.model
backbone.fc_audioset = torch.nn.Linear(backbone.fc_audioset.in_features, len(class_names))

state_dict = torch.load(hf_hub_download(REPO_ID, CHECKPOINT), map_location="cpu")
backbone.load_state_dict(state_dict)
backbone.eval()

# waveform: mono float tensor at 32kHz, shape (num_windows, window_samples)
with torch.inference_mode():
    logits = backbone.fc_audioset(backbone(waveform)["embedding"])
    probs = torch.softmax(logits, dim=1).mean(dim=0)
    top_class = class_names[probs.argmax()]

License

CC BY-SA 4.0.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Space using joakes90/engine_sound_classifier 1