오디오 분류(Audio Classification) — MFCC 기반 k-NN에서 AST와 BEATs까지

"개 짖음 vs 사이렌"부터 "이 언어가 무엇인가"까지 모두 오디오 분류(audio classification)입니다. 특징(feature)은 멜(mel)이고, 아키텍처(architecture)는 시대마다 바뀝니다. 평가 지표는 AUC, F1, 클래스별 재현율(per-class recall)로 남습니다.

유형: Build 언어: Python 선수 지식: Phase 6 · 02 (Spectrograms & Mel), Phase 3 · 06 (CNNs), Phase 5 · 08 (CNNs & RNNs for Text) 예상 시간: 약 75분

학습 목표

  • 오디오 분류 문제를 log-mel -> model -> softmax 또는 다중 라벨 헤드(multi-label head) 흐름으로 정리합니다.
  • MFCC(Mel-frequency cepstral coefficient) 기반 k-최근접 이웃(k-NN), 2D CNN, AST(Audio Spectrogram Transformer), BEATs, Whisper 인코더(Whisper encoder) 기준선을 비교합니다.
  • 클래스 불균형(class imbalance), 도메인 이동(domain shift), 라벨 노이즈(label noise)가 실제 난이도라는 점을 이해합니다.
  • 과제 유형에 맞는 평가 지표(metric)를 선택합니다.

문제

10초짜리 클립(clip)이 있습니다. 우리는 "이 소리는 무엇인가?"를 알고 싶습니다. 도시 소리(사이렌, 드릴, 개), 음성 명령(yes/no/stop), 언어 식별(language ID: en/es/ar), 화자 감정(speaker emotion: angry/neutral), 환경음(environmental sound: indoor/outdoor, babble)이 모두 오디오 분류입니다. 2026년 기준 기준선 아키텍처(baseline architecture)는 이미 성숙했습니다. 기본 흐름은 log-mel -> CNN or Transformer -> softmax입니다.

핵심 난이도는 신경망(network)이 아닙니다. 데이터(data)입니다. 오디오 데이터셋(audio dataset)은 클래스 불균형이 심하고, 깨끗한 데이터와 잡음 많은 데이터 사이의 도메인 이동이 강하며, 라벨 노이즈도 큽니다. 누가 "urban babble"과 "restaurant noise"를 구분했다고 믿을 수 있을까요? 문제의 80%는 CNN을 Transformer로 바꾸는 일이 아니라 큐레이션(curation), 증강(augmentation), 평가(evaluation)입니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.오디오 분류(audio classification)의 표준 파이프라인이 원시 파형(raw waveform)을 바로 넣지 않고 로그-멜(log-mel) -> 모델 -> 소프트맥스(softmax) 순서를 따르는 이유는 무엇인가요?

2.50개 클래스에 각 40개 클립(ESC-50)인 데이터셋과, 632개 클래스에 100,000:1 클래스 불균형(AudioSet)인 데이터셋이 있습니다. 불균형 데이터셋이 근본적으로 다른 학습 전략을 요구하는 이유는 무엇인가요?

0/2 답변 완료

개념

three decades of audio classifiers, same log-mel input input: 10-sec log-mel spectrogram — shape [T=998, n_mels=80] same frontend, three generations of backends 1990s — k-NN on MFCCs MFCC-13 + mean/var pool cosine → top-K vote zero training, no GPU strong on ESC-50 fails on AudioSet ESC-50 acc: ~65% your first baseline 2015–2021 — 2D CNN log-mel as image Conv + Pool × 3, softmax 3M params, 10-min train SpecAugment + mixup still the baseline in KWS ESC-50 acc: ~82% edge + speech commands 2024–2026 — BEATs / AST patchify log-mel (16×16) SSL-pretrained transformer fine-tune on 1-10% labels BEATs-iter3 leads AudioSet default for non-speech 2026 ESC-50 acc: 97.0% AudioSet mAP: 0.548 the features stayed the same for 30 years; the backend is the lever

MFCC 기반 k-최근접 이웃(k-NN on MFCCs, 1990년대 기준선). 클립별 MFCC를 평탄화(flatten)하거나 풀링(pooling)하고, 라벨이 붙은 특징 저장소(labeled bank)와 코사인 유사도(cosine similarity)를 계산한 뒤 상위 K개 표본의 다수결(majority vote)을 반환합니다. Speech Commands, ESC-50처럼 깨끗하고 작은 데이터셋에서는 놀라울 정도로 강합니다. GPU 없이 실행됩니다.

로그 Mel 기반 2D CNN(2D CNN on log-mels, 2015-2019). (T, n_mels) 형태의 로그 Mel(log-mel)을 이미지(image)처럼 다룹니다. ResNet-18 또는 VGG 스타일 2D CNN을 적용하고, 시간축(time axis)에 전역 평균 풀링(global mean pool)을 적용한 뒤 클래스별 소프트맥스(softmax)를 붙입니다. 2026년에도 많은 Kaggle 경진대회에서 기준선으로 쓰입니다.

오디오 스펙트로그램 트랜스포머(Audio Spectrogram Transformer, AST, 2021-2024). 로그 Mel을 예를 들어 16x16 패치(patch)로 자르고, 위치 임베딩(position embedding)을 더한 뒤 ViT(Vision Transformer)에 넣습니다. 지도 학습(supervised learning) 기준 AudioSet에서 mAP 0.485를 기록한 강한 구조입니다.

BEATs와 WavLM-base(2024-2026). 수백만 시간의 오디오로 자기지도 사전학습(self-supervised pretraining)을 수행한 모델입니다. 원래 필요했을 지도 학습 데이터의 1-10%만으로도 과제에 맞게 미세조정(fine-tune)할 수 있습니다. 2026년 기준 비음성 오디오(non-speech audio)의 기본 출발점입니다. BEATs-iter3는 AudioSet에서 AST보다 1-2 mAP 높으면서도 약 1/4의 연산 자원(compute)만 사용합니다.

동결 백본으로 쓰는 Whisper 인코더(Whisper-encoder as a frozen backbone, 2024). Whisper의 인코더만 가져오고 디코더(decoder)는 버린 뒤 선형 분류기(linear classifier)를 붙입니다. 오디오 증강 없이도 언어 식별과 단순 이벤트 분류에서 거의 SOTA에 가까운 기준선이 됩니다. 일종의 "공짜 점심" 기준선입니다.

클래스 불균형이 진짜 문제입니다

ESC-50은 50개 클래스에 각 40개 클립이 있어 균형적이고 쉽습니다. UrbanSound8K는 10개 클래스지만 10:1 불균형이 있습니다. AudioSet은 632개 클래스와 100,000:1에 이르는 긴 꼬리(long tail)를 가집니다. 잘 작동하는 기법은 다음과 같습니다.

  • 학습 중 균형 샘플링(balanced sampling)을 사용합니다. 평가는 균형 샘플링으로 하지 않습니다.
  • 믹스업(Mixup): 두 클립과 두 라벨을 선형 보간하여 증강합니다.
  • 스펙어그먼트(SpecAugment): 임의의 시간(time) 대역과 주파수(frequency) 대역을 마스킹(masking)합니다. 단순하지만 중요합니다.

평가

  • 배타적 다중 클래스(multiclass exclusive, 예: Speech Commands): top-1 정확도, top-5 정확도를 봅니다.
  • 다중 클래스 다중 라벨(multiclass multi-label, 예: AudioSet, UrbanSound 스타일): 평균 정밀도 평균(mean average precision, mAP)을 봅니다.
  • 불균형이 심한 경우: 클래스별 재현율(per-class recall)과 매크로 F1(macro F1)을 함께 봅니다.

2026년에 알아두어야 할 수치는 다음과 같습니다.

벤치마크기준선2026년 SOTA출처
ESC-5082% (AST)97.0% (BEATs-iter3)BEATs 논문(2024)
AudioSet mAP0.485 (AST)0.548 (BEATs-iter3)HEAR 리더보드 2026
Speech Commands v298% (CNN)99.0% (Audio-MAE)HEAR v2 결과

직접 만들기

Step 1: 특징 추출(featurize)

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)

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

단순하지만 강합니다. 시간축에 대한 평균(mean)과 분산(variance)을 이어 붙이면 13개 계수(coefficient)를 가진 MFCC에서 26차원 고정 임베딩(fixed embedding)을 만들 수 있습니다. 즉시 실행되며, ESC-50에서는 2017년 무렵까지도 최신 신경망 기준선을 이긴 사례가 있었습니다.

Step 3: k-NN

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: 로그 Mel CNN으로 업그레이드

PyTorch에서는 다음처럼 시작할 수 있습니다.

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 파라미터(parameter) 규모입니다. 단일 RTX 4090에서 ESC-50 기준 약 10분 안에 학습할 수 있고, 80% 이상의 정확도(accuracy)를 기대할 수 있습니다.

Step 5: 2026년 기본값, BEATs 미세조정

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

BEATs는 beats 라이브러리에서 microsoft/BEATs-base를 사용합니다. Transformers API와 형태가 비슷합니다.

사용하기

2026년 기준 스택은 다음처럼 고릅니다.

상황시작점
매우 작은 데이터셋(<1000 clips)MFCC 평균 기반 k-NN(기준선) + 오디오 증강(audio augmentation)
중간 데이터셋(1K-100K)BEATs 또는 AST 미세조정
큰 데이터셋(>100K)처음부터 학습하거나 Whisper 인코더 미세조정
실시간, 엣지(edge)int8로 양자화(quantization)한 40-MFCC CNN, KWS(keyword spotting) 스타일
다중 라벨(AudioSet)BEATs-iter3 + BCE 손실(binary cross-entropy loss) + mixup + SpecAugment
언어 식별(language ID)MMS-LID, SpeechBrain VoxLingua107 기준선

결정 규칙은 새 모델(fresh model)이 아니라 동결 백본(frozen backbone)에서 시작한다입니다. BEATs 헤드(head)를 미세조정하면 몇 주가 아니라 몇 시간 안에 SOTA의 95%에 가까운 결과를 얻을 수 있습니다.

산출물 만들기

outputs/skill-classifier-designer.md로 저장합니다. 주어진 오디오 분류 과제에 대해 아키텍처, 증강 방식, 클래스 균형 전략, 평가 지표를 선택하는 skill입니다.

연습문제

  1. 쉬움. code/main.py를 실행합니다. 이 코드는 서로 다른 높이의 순음(pure tone)을 사용하는 4-class 합성 데이터셋에서 k-NN MFCC 기준선을 학습합니다. 혼동 행렬(confusion matrix)을 보고합니다.
  2. 중간. summarize[mean, var, skew, kurtosis]로 바꿉니다. 같은 합성 데이터셋에서 4-moment pooling이 mean+var보다 나은지 확인합니다.
  3. 어려움. torchaudio를 사용하여 ESC-50 fold 1에 2D CNN을 학습합니다. 5-fold 교차 검증 정확도(cross-validation accuracy)를 보고합니다. SpecAugment(time mask = 20, freq mask = 10)를 추가하고 변화량(delta)을 보고합니다.

핵심 용어

용어흔한 설명실제 의미
AudioSet오디오의 ImageNetGoogle의 2M 클립, 632 클래스 약한 라벨(weakly-labeled) YouTube 데이터셋입니다.
ESC-50작은 분류 벤치마크환경음(environmental sound) 50개 클래스 x 40개 클립 데이터셋입니다.
ASTAudio Spectrogram Transformer로그 Mel 패치에 ViT를 적용한 구조입니다. 2021년 SOTA 계열입니다.
BEATs자기지도 오디오(self-supervised audio)Microsoft 모델이며, 2026년 기준 iter3가 AudioSet에서 강한 성능을 냅니다.
Mixup쌍 기반 증강(pair augmentation)x = lambda*x1 + (1-lambda)*x2; y = lambda*y1 + (1-lambda)*y2처럼 입력과 라벨을 함께 섞습니다.
SpecAugment마스크 기반 증강(mask-based augmentation)스펙트로그램의 임의 시간/주파수 대역을 0으로 만듭니다.
mAP주요 다중 라벨 지표클래스와 임계값(threshold) 전반의 평균 정밀도 평균(mean average precision)입니다.

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

classifier-designer

Pick architecture, augmentation, class-balance strategy, and eval metric for an audio classification task.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.라벨이 붙은 오디오 클립이 500개 미만이고 GPU가 없습니다. 가장 좋은 출발점은 무엇이며 그 이유는 무엇인가요?

2.BEATs-iter3가 AST보다 AudioSet에서 더 높은 성능을 내면서도 연산 자원(compute)의 약 1/4만 사용하는 이유는 무엇인가요?

3.다중 라벨 어노테이션(multi-label annotation)이 있는 AudioSet(하나의 클립에 '개 짖음'과 '자동차 경적'이 동시에 존재할 수 있음)에서 오디오 분류기를 평가할 때, top-1 정확도 대신 mAP가 적절한 지표인 이유는 무엇인가요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다