Temă

Această temă are timp de lucru 2 săptămâni, începând de pe 18 noiembrie, va fi încărcată pe cs.curs.pub.ro și va fi prezentată la laborator în săptămâna 3-7 decembrie. Tema este un bonus care valorează 2 laboratoare urmând să completeze punctajul lipsă pe laborator sau proiect.

Clasificare de sunete

Autor: Andrei Nicolicioiu

Clasificarea de sunete, adică prezicerea tipului unui sunet este foarte utilă în diferite domenii. În această temă vom implementa o metodă care va clasifica sunete din mai multe categorii ('Laratul unui câine', 'Valuri', 'Ploaie' și altele), folosindu-ne de datale din subsetul ESC10 din datasetul [1]. Aceasta metoda este folosită în [1] ca o primă metodă de bază cu care se pot compara oricare alte metode mai noi.

Extragere de feature-uri

În orice metoda de clasificare avem nevoie de un set de trăsături (feature-uri) care caracterizează într-un mod bun obiectul dorit, sunt utile în diferențierea a doua obiecte de tip diferit. De exemplu pentru diferențierea imaginilor cu căpșuni de imagini cu banane, culoarea ca fi o buna trăsătură. Pentru distingerea sunetelor este foarte important spectrul lor de frecvențe asa că vom încerca să ne construim niște feature-uri care surprind bine spectrul sunetelor. De exemplu plânsul unui copil are frecvențe mai mari față de sunetul valurilor.

Primul tip de feature este numit zero-crossing rate. Sunetul este un semnal centrat in zero, iar zero-crossing rate număra de câte ori semnalul trece din valori pozitive în valori negative, raportat la numărul total de esantioane. Acesta feature ne indică frecvențele din semnal (de exemplu un semnal care conține frecvențe înalte ar trebui să aiba multe treceri prin zero).

Al doilea tip de feature se numeste “mel-frequency cepstral coefficients” (MFCC). Acesta este o reprezentare succintă a spectrului unui sunet. Ideea generala e să împărțim sunetul în segmente, iar fiecărui segment să îi aflăm spectrul. Pentru a calcula MMFCC urmăm următorii pasi:

  1. Împărțim semnalului în ferestre care se suprapun. Vom alege ferestre de dimensiune 25ms eșantionate la fiecare 10ms.
  2. Calcularea fft pe fiecare fereastră, folosind un numar K = 256 de coeficienți, adică aplicăm fft(fereastra,256) în Matlab, apoi analizăm fiecare fereastră.
  3. Vrem sa vedem cât de puternice sunt frecventele din mai multe intervale. Asa că ne vom stabili $N_{coeficienti} = 12$ intervale și vom aproximaun puterea medie a frecvențelor din fiecare interval, pentru fiecare fereastra. Pentru a vedea cât de puternice sunt frecvențele dintr-un interval, vom calcula o medie a coeficienților din spectru corespunzător acestui interval.
    1. Pentru fiecare interval, vom crea un filtru pe care îl vom folosi pentru a calcula o medie ponderată a spectrului. Fiecare filtru va avea dimensiunea spectrului (256) și valori diferite de zero doar în intervalul corespunzător, de la 0 crescând liniar până la 1 în centrul intervalului și înapoi la zero. Vom folosi intervale de mărimi din ce în ce mai mari, precum în imaginea următoare, unde fiecare filtru are o culoare diferită. Mai precis, vom folosi intervale egale pe scara Mel. TODO: de vazut daca dam codul sau nu…
    2. Vom calcula media coeficienților spectrului ponderați de acest filtru (înmulțim element cu element filtrul și spectrul și calculam media rezultatului). Apoi vom aplica logaritm peste rezultat, obținând un scalar pentru fiecare filtru, în total $N_{coeficienti}$ valori.
  4. Din fiecare fereastră obținem astfel un vector de dimensiune $N_{coeficienti}$ și calculăm media și varianță peste toate ferestrele, obținând 2 vectori de dimensiune $N_{coeficienti}$. Concatenarea lor formeaza un vector de dimensiune $2 * N_{coeficienti}$ care reprezintă feature-urile MFCC.

În total, pentru fiecare semnal vom avea $2 * N_{coeficienti}$ valori reprezentând coeficienții MFCC plus 1 valoare reprezentând zero-crossing. Aceste feature-uri, puse într-un vector cu $2 * N_{coeficienti} + 1$ elemente ne va caracteriza semnalul nostru audio.

Antrenarea unui clasificator

Ar trebui ca având date vectorii de feature-uri pentru toate tipurile de sunete pe care vrem să le analizăm, să putem învăța un clasificator care le poate diferenția. În machine learning, în general avem 2 seturi distincte de date. Primul este setul de învățare (antrenare) pe care îl folosim ca să analizăm datele, și pe care ne optimizăm / învățăm un clasificator care să diferențieze cât mai bine datele. Dar vrem să avem un clasificator care sa poate da predicții despre exemple de sunete pe care nu a fost antrenat, de aceea vom analiza performanța clasificatorului pe un set de date separate (dar care au aceleași clase ca cele din setul de antrenare, doar ca sunt exemple diferite) numit set de validate / testare.

Obiectivul acestui task este să învățăm un clasificator pe setul de antrenare și să îl validam apoi pe setul de test. Vom folosi Linear discriminant analysis (LDA) implementat in Matlab de funcția 'fitcdiscr'.

În fișierul dat aveți dat codul care antrenează clasificatorul, calculează acuratețea și afișează predicția pentru un exemplu din setul de test. În audio_train aveți toate sunetele din setul de date, 300 de semnale audio de 3s, eșantionate la 44109 Hz. Funcția 'get_features' va trebui să primească o mulțime de sunete și să returneze un vector de feature-uri pentru fiecare semnal.

O implementare corectă ar trebui să dea o acuratețe (număr de exemple corect clasificate din numărul total încercat) de aproximativ 70% pe setul de test.

[1]: Piczak, Karol J. “ESC: Dataset for environmental sound classification.” In Proceedings of the 23rd ACM international conference on Multimedia, pp. 1015-1018. ACM, 2015.

Date : Date

tema.m
% Tema PS 2018
% Autor: Andrei Nicolicioiu
 
clear all 
close all
 
% [audio_train,labels_train, audio_test,labels_test] = load_data();
load('data.mat')
 
% calculam featureurile pentru datasetul de train / test
% get_features primeste toate sunetele din set date intr-o matrice
% de dimensiune Numar_sunete x Numar_esantioane si returnează toate
% featurile acestor sunete intr-o matrice de dimensiune Numar_sunete x (2 * N + 1)
% TODO: calculati featurile MFCC si zero-crossing
feat_train = get_features(audio_train);
feat_test = get_features(audio_test);
 
% antrenam un clasificator
lda=fitcdiscr(feat_train,labels_train,'discrimType','pseudoLinear' );
 
% prezicem clasele pentru datasetul de train si de test
pred_train = predict(lda,feat_train);
pred_test = predict(lda,feat_test);
 
 
% calculam acuratetea pe train si test
acc_test  = mean(pred_test(:) == labels_test(:));
acc_train = mean(pred_train(:) == labels_train(:));
 
sprintf('Accuracy on train: %0.2f', acc_train);
sprintf('Accuracy on test: %0.2f', acc_test);
 
 
% TODO: verificati calitativ cateva exemple din setul de test. 
% comparati clasa corecta si clasa presiza cu sunetul auzit
 
% alegem random un fisier audio si verificam daca am clasificat corect
labels_name = ["Dog","Rooster", "Rain" , "Waves","Fire","Baby",...
    "Sneezing","Clock","Helicopter","Chainsow"]
 
r = round(rand() * 100);
sound(audio_test(:,r),fs);
sprintf('Clasa corecta: %s', labels_name(labels_test(r)))
sprintf('Clasa prezisa: %s', labels_name(pred_test(r)))

ps/todo_tema.txt · Last modified: 2019/10/28 14:50 by ionut.gorgos
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0