TAI BUI
Back to curriculum
BuildPython

Audio Classification — From k-NN on MFCCs to AST and BEATs

"Dog barking vs siren" and "which language is this" are the same task: audio classification. The features are mels. The architecture moves each decade. The evaluation stays AUC, F1, and per-class recall.

TIME: ~75 minutesPREREQUISITES: Phase 6 · 02 (Spectrograms & Mel), Phase 3 · 06 (CNNs), Phase 5 · 08 (CNNs & RNNs for Text)

Learning Objectives

  • Identify what counts as an audio classification task (urban sound, speech command, language ID, speaker emotion) and what doesn't, like voice cloning or generation.
  • Trace the architecture ladder from k-NN on MFCCs through 2D CNNs, AST, and BEATs to a frozen Whisper-encoder backbone, and explain why 2026 practice defaults to a frozen backbone first.
  • Implement a k-NN audio classifier from scratch: MFCC featurization, a fixed-length mean/variance summary, and cosine-similarity voting.
  • Apply class-imbalance techniques (balanced sampling, Mixup, SpecAugment) and pick the right evaluation metric, accuracy, mAP, AUC, or per-class recall and macro F1, for a task's label distribution.
  • Fine-tune a pretrained AST or BEATs checkpoint with Hugging Face transformers instead of training a CNN from scratch.

The Problem

Audio classification is the task of mapping a clip to a label, and by 2026 the baseline architecture for doing it is mature: log-mel → CNN or Transformer → softmax. Hand a model a 10-second clip and ask "what is it?" and you're doing this task, whatever the domain: urban sound (siren, drill, dog), speech command (yes/no/stop), language ID (en/es/ar), speaker emotion (angry/neutral), environmental sound (indoor/outdoor, babble).

The bottleneck here is data, not model architecture. Audio datasets carry brutal class imbalance, strong domain shift (clean vs noisy), and label noise nobody agrees on (is that "urban babble" or "restaurant noise"?). Curation, augmentation, and evaluation make up 80% of the actual work; swapping a CNN for a Transformer barely touches it.

Warm-up0/3
1. A classifier must pick exactly one of several classes for each input. Which output layer turns the raw class scores into probabilities that sum to 1?Warm-up
Three raw class scores drawn as bars, an arrow into an unnamed output layer marked with a question mark, and an unnamed result whose values must sum to 1.
Scores are illustrative, not from a trained model.
2. In k-nearest-neighbours classification, how is the label for a new example decided?Warm-up
A 2D scatter of labeled points: five circles labelled A on the left, five squares labelled B on the right, and one unlabeled point marked with a question mark between them.
Illustrative points, not audio features.
3. A dataset is 95% negative examples. A model that always predicts 'negative' scores what accuracy?Warm-up
A 10 by 10 grid of 100 dots, 95 grey for negative and 5 orange for positive, next to a model box that always outputs negative and an unknown accuracy.
The 100-example size is illustrative; the 95 percent split is from the question.
Check: The Problem0/3
1. Which of these is NOT an audio classification task?Define
A synthetic waveform goes into a model box, which outputs one of the labels yes, no or stop.
Waveform is synthetic; the yes/no/stop label set is the lesson's speech-command example.
2. Which part of audio classification work does the lesson say takes about 80% of the effort?Define
One horizontal bar split into a dashed slice of about 80 percent with a question mark and a slice of about 20 percent.
Proportions from the question; the slice is unnamed.
3. Which of these is named as a data problem that makes audio classification hard?Define
A quote that the bottleneck is data, not model architecture, above three unnamed boxes marked with question marks.
Quote and count of three from the lesson's Problem section.

The Concept

Audio classification ladder: k-NN on MFCCs to AST to BEATs

k-NN on MFCCs (the 1990s baseline). Flatten the MFCCs for a clip, compute cosine similarity against a labeled bank, and return the majority vote of the top K. It's surprisingly strong on clean, small datasets like Speech Commands and ESC-50, and it runs with no GPU at all.

2D CNN on log-mels (2015-2019). Treat the (T, n_mels) log-mel as an image, run it through a ResNet-18 or VGG-style stack, global-mean-pool the time axis, and softmax over classes. Still the baseline you'll see in most 2026 Kaggle competitions.

Audio Spectrogram Transformer, AST (2021-2024). Patchify the log-mel (16×16 patches are typical), add position embeddings, and feed the result to a ViT. State of the art on AudioSet for supervised learning, at mAP 0.485.

BEATs and WavLM-base (2024-2026). Self-supervised pretraining on millions of hours of audio, then fine-tune on your task with 1-10% of the supervised data you'd otherwise need. This is the default starting point for non-speech audio in 2026: BEATs-iter3 beats AST by 1-2 mAP on AudioSet while using 1/4 the compute.

Whisper-encoder as a frozen backbone (2024). Take Whisper's encoder, drop the decoder, attach a linear classifier. That's it. It lands near-SOTA on language ID and simple event classification with zero audio augmentation, which is why it's the "free lunch" baseline.

Class imbalance is the real challenge

ESC-50 keeps things easy: 50 classes, 40 clips each, balanced. UrbanSound8K is already lopsided, 10 classes imbalanced 10:1. AudioSet is the extreme case: 632 classes with a 100,000:1 long tail. A few techniques actually move the needle:

  • Balanced sampling during training (not evaluation).
  • Mixup: linearly interpolate two clips, and their labels, as augmentation.
  • SpecAugment: mask random time and frequency bands. Simple, and critical.

Evaluation

  • Multiclass exclusive (Speech Commands): top-1 accuracy, top-5 accuracy.
  • Multiclass multi-label (AudioSet, UrbanSound-style): mean average precision (mAP), plus AUC (area under the ROC curve) as the companion metric AudioSet leaderboards report alongside it.
  • Heavily imbalanced: per-class recall plus macro F1.

The 2026 numbers worth memorizing:

BenchmarkBaselineSOTA 2026Source
ESC-5082% (AST)97.0% (BEATs-iter3)BEATs paper (2024)
AudioSet mAP0.485 (AST)0.548 (BEATs-iter3)HEAR leaderboard 2026
Speech Commands v298% (CNN)99.0% (Audio-MAE)HEAR v2 results
Check: The Concept0/16
1. What is AudioSet?Define
A quote card reading the ImageNet of audio, above boxes naming ImageNet and AudioSet.
The quote is the nickname given in the lesson's Key Terms table.
2. What is ESC-50?Define
One row of a results table: ESC-50, baseline 82 percent with AST, state of the art 97.0 percent with BEATs-iter3.
Copied from the lesson's benchmark table.
3. What is the Audio Spectrogram Transformer (AST)?Define
A card naming AST, Audio Spectrogram Transformer, with its authors, years, and an AudioSet mAP of 0.485.
Facts from the lesson's Concept, Key Terms and Further Reading.
4. What is BEATs?Define
Two horizontal bars of AudioSet mAP: AST 0.485 and BEATs-iter3 0.548.
Values from the lesson's benchmark table.
5. What does Mixup do as an augmentation?Define
Two synthetic clips, one labelled siren and one labelled dog, feed a box named Mixup whose output is an unknown augmented example.
Waveforms are synthetic for illustration.
6. What does SpecAugment do?Define
A synthetic log-mel spectrogram goes into a box named SpecAugment and comes out as an unknown result.
Spectrogram computed with numpy from a synthetic two-tone clip.
7. What does mAP (mean average precision) measure?Define
A table of model scores for four clips and three classes (siren, dog, drill), with orange dots marking which sounds are really present, and an unknown mAP.
Scores and truth marks are illustrative.
8. Why is k-NN on MFCCs, a 1990s baseline, still worth running today?Explain
A timeline with k-NN on MFCCs in the 1990s on the left and BEATs-iter3 in 2026 on the right.
Dates from the lesson's Concept section.
9. How does AST's handling of a log-mel differ from the 2D CNN's?Explain
A synthetic log-mel spectrogram labelled (T, n_mels) with arrows to a 2D CNN and to AST, each leading to an unknown box.
Spectrogram computed from a synthetic clip.
10. BEATs-iter3 reaches 97.0% on ESC-50 where supervised AST gets 82%. What training approach makes BEATs strong with little labeled data?Explain
Two bars of ESC-50 accuracy, supervised AST at 82 percent and BEATs-iter3 at 97.0 percent, above an unanswered question about how BEATs was trained.
Values from the question and the lesson's benchmark table.
11. Why is the frozen Whisper-encoder classifier called a 'free lunch' baseline?Explain
Audio goes into a frozen Whisper encoder, then a new linear head, then class scores; the Whisper decoder is drawn dashed and crossed out.
Schematic of the lesson's description.
12. AudioSet has 632 classes with a 100,000:1 long tail. What does that imply for training?Explain
A curve on a log scale falling across 632 classes from the most common class to the rarest, a ratio of 100,000 to 1.
Shape is illustrative; only the 632 classes and the 100,000:1 ratio come from the lesson.
13. Why does the lesson give heavily imbalanced tasks per-class recall plus macro F1, instead of top-1 accuracy?Explain
Three horizontal bars of class sizes 900, 90 and 10 clips, followed by two metric choices: top-1 accuracy, or per-class recall plus macro F1.
Class sizes are illustrative.
14. A classifier hits 91% accuracy on a UrbanSound-style set with 10:1 imbalance, yet it never predicts the rarest class. Which evaluation would expose this?Analyze
Ten bars of class sizes falling from 10 to 1 with the smallest in orange, beside a note of 91 percent accuracy and the rarest class never predicted.
Class sizes between the 10:1 ends are illustrative.
15. A k-NN on MFCC means scores well on clean test clips but badly on field recordings. Which problem from the lesson is this?Analyze
A k-NN on MFCC means model scoring well on clean test clips and badly on field recordings.
Restated from the question.
16. You fine-tune a BEATs classifier on a 6-class dataset and reach 99% training accuracy, but validation recall on your two rarest classes is under 20%. What should you check first?Analyze
Three bars: training accuracy 99 percent, and validation recall under 20 percent for each of the two rarest classes.
Values from the question; the 20 percent bars are an upper limit.

Build It

Step 1: featurize

python
def featurize_mfcc(signal, sr, n_mfcc=13, n_mels=40, frame_len=400, hop=160):
    mag = stft_magnitude(signal, frame_len, hop)
    fb = mel_filterbank(n_mels, frame_len, sr)
    mels = apply_filterbank(mag, fb)
    log = log_transform(mels)
    return [dct_ii(frame, n_mfcc) for frame in log]

Step 2: fixed-length summary

python
def summarize(mfcc_frames):
    n = len(mfcc_frames[0])
    mean = [sum(f[i] for f in mfcc_frames) / len(mfcc_frames) for i in range(n)]
    var = [
        sum((f[i] - mean[i]) ** 2 for f in mfcc_frames) / len(mfcc_frames) for i in range(n)
    ]
    return mean + var

Simple but strong: mean + variance across time turns a 13-coef MFCC into a fixed 26-dim embedding. It runs instantly, and this exact trick beat state-of-the-art NN baselines on ESC-50 as recently as 2017.

Step 3: k-NN

python
def cosine(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    na = math.sqrt(sum(x * x for x in a)) or 1e-12
    nb = math.sqrt(sum(x * x for x in b)) or 1e-12
    return dot / (na * nb)
 
def knn_classify(q, bank, labels, k=5):
    sims = sorted(range(len(bank)), key=lambda i: -cosine(q, bank[i]))[:k]
    votes = Counter(labels[i] for i in sims)
    return votes.most_common(1)[0][0]

Step 4: upgrade to CNN on log-mels

In PyTorch:

python
import torch.nn as nn
 
class AudioCNN(nn.Module):
    def __init__(self, n_mels=80, n_classes=50):
        super().__init__()
        self.body = nn.Sequential(
            nn.Conv2d(1, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(),
            nn.AdaptiveAvgPool2d(1),
        )
        self.head = nn.Linear(128, n_classes)
 
    def forward(self, x):  # x: (B, 1, T, n_mels)
        return self.head(self.body(x).flatten(1))

3M parameters, trains in ~10 min on ESC-50 with a single RTX 4090, and clears 80%+ accuracy.

Step 5: fine-tune BEATs (the 2026 default)

python
from transformers import ASTFeatureExtractor, ASTForAudioClassification
 
ext = ASTFeatureExtractor.from_pretrained("MIT/ast-finetuned-audioset-10-10-0.4593")
model = ASTForAudioClassification.from_pretrained(
    "MIT/ast-finetuned-audioset-10-10-0.4593",
    num_labels=50,
    ignore_mismatched_sizes=True,
)
 
inputs = ext(audio, sampling_rate=16000, return_tensors="pt")
logits = model(**inputs).logits

For BEATs, swap in microsoft/BEATs-base via the beats library. The transformers API keeps the same shape.

Check: Build It0/8
1. Why does the k-NN step first reduce MFCC frames to a mean-and-variance vector?Explain
A five-step pipeline: audio clip, featurize_mfcc giving T frames by 13, a mean and variance step, cosine similarity against a labeled bank, and a top-k vote.
Step names from the lesson's Build It section.
2. What does summarize() compute from a list of MFCC frames?Apply
A table of five MFCC frames showing coefficients c0 to c3 and c12, followed by a call to summarize with an unknown result.
Frames captured by running the lesson's code/main.py on a noisy 400 Hz tone.
3. featurize_mfcc is called with n_mfcc=20 on a clip with 300 frames, and its output goes to summarize(). How long is the result?Apply
A block of 300 frames by 20 MFCC coefficients feeding summarize, whose output length is unknown.
Sizes from the question.
4. cosine([1, 2], [2, 4]) is evaluated with the lesson's function. What is returned?Apply
The lesson's cosine function source followed by the call cosine([1, 2], [2, 4]) with an unknown result.
Function copied from the lesson's Step 3.
5. knn_classify uses k=3. The query's similarities to the bank are 0.9 (siren), 0.2 (dog), 0.8 (dog), 0.7 (siren), 0.1 (drill). What does it return?Apply
A table of five bank entries with similarities 0.9, 0.2, 0.8, 0.7, 0.1 and labels siren, dog, dog, siren, drill, next to an unknown function result.
Values from the question.
6. In the lesson's AudioCNN, a batch of 8 clips of shape (8, 1, T, 80) goes through self.body and flatten(1). What shape reaches the linear head?Apply
The Sequential body of the lesson's AudioCNN: three conv layers, two max pools and an adaptive average pool, with the input shape (8, 1, T, 80) and an unknown output shape.
Layers copied from the lesson's Step 4.
7. In AudioCNN, the input has T time frames and 80 mel bins. How do the two MaxPool2d(2) layers change those sizes before AdaptiveAvgPool2d(1)?Apply
The AudioCNN body source, with an input of T by 80 and an unknown size after the two MaxPool2d(2) layers.
Layers copied from the lesson's Step 4.
8. You load the AudioSet-finetuned AST checkpoint to classify 50 ESC-50 classes. Which change in the lesson's Step 5 code adapts it?Apply
A pretrained AST checkpoint fine-tuned on AudioSet, an unknown change, and an AST classifier for 50 ESC-50 classes.
Schematic of the question.

Use It

The 2026 stack:

SituationStart with
Tiny dataset (<1000 clips)k-NN on MFCC means (your baseline) + audio augmentation
Medium dataset (1K–100K)BEATs or AST fine-tune
Large dataset (>100K)Train from scratch or fine-tune Whisper-encoder
Real-time, edge40-MFCC CNN, quantized to int8 (KWS-style)
Multi-label (AudioSet)BEATs-iter3 with BCE loss + mixup + SpecAugment
Language IDMMS-LID, SpeechBrain VoxLingua107 baseline

Decision rule: start with a frozen backbone, not a fresh model. Fine-tuning a BEATs head gets you 95% of SOTA in hours, not weeks.

Check: Use It0/4
1. What reason does the lesson give for starting with a frozen backbone rather than a fresh model?Explain
Two rows, a fresh model and a frozen backbone, each pointing to an unknown time to a strong result.
Schematic.
2. A teammate spent a week tuning CNN depth and kernel sizes, then a frozen-backbone fine-tune beat it in an afternoon. What assumption was wrong?Analyze
Two bars: a long bar for a week of CNN tuning and a short bar for an afternoon of frozen-backbone fine-tuning, which scored higher.
Bar lengths are schematic.
3. You must ship a wake-word style keyword spotter on a battery-powered device with real-time latency limits. Which starting point fits the lesson's stack?Design
A requirements card: a wake-word style keyword spotter on a battery-powered device with real-time latency limits.
Restated from the question.
4. You are tagging AudioSet-style clips where several sounds can occur at once, with 632 labels. Which recipe fits?Design
A clip timeline with a siren bar and a dog bar overlapping in time, and a note that there are 632 possible labels.
Illustrative layout; bar positions are typed.

Ship It

This lesson ships outputs/skill-classifier-designer.md, a skill for picking architecture, augmentations, class-balance strategy, and eval metric for a given audio classification task.

Author's Note

The line here I'd tattoo on a wall somewhere is the decision rule in Use It: start with a frozen backbone, not a fresh model. I've watched people spend a week arguing over CNN depth and kernel sizes on a dataset that a BEATs fine-tune would have beaten before lunch. Architecture search is fun, and for most audio classification tasks in 2026 it's also a distraction from what's actually deciding whether your classifier works, which is your data. Fix the class imbalance first. Audit a sample of your labels by hand before you trust the rest. Only reach for a custom architecture once a frozen backbone has genuinely run out of room to improve.

Exercises

  1. Easy. Run code/main.py. It trains the k-NN MFCC baseline on a 4-class synthetic dataset (pure tones at different pitches). Report confusion matrix.
  2. Medium. Replace summarize with [mean, var, skew, kurtosis]. Does 4-moment pooling beat mean+var on the same synthetic dataset?
  3. Hard. Using torchaudio, train a 2D CNN on ESC-50 fold 1. Report 5-fold cross-validation accuracy. Add SpecAugment (time mask = 20, freq mask = 10) and report the delta.

Key Terms

TermWhat people sayWhat it actually means
AudioSetThe ImageNet of audioGoogle's 2M-clip, 632-class weakly-labeled YouTube dataset.
ESC-50Small classification benchmark50 classes × 40 clips of environmental sounds.
ASTAudio Spectrogram TransformerViT on log-mel patches; 2021 SOTA.
BEATsSelf-supervised audioMicrosoft model, iter3 leads AudioSet as of 2026.
MixupPair augmentationx = λ·x1 + (1-λ)·x2; y = λ·y1 + (1-λ)·y2.
SpecAugmentMask-based augmentationZero-out random time and frequency bands of the spectrogram.
mAPMain multi-label metricMean average precision across classes and thresholds.

Further Reading

Code

Ships With