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 acest task vrem să clasificam un set data cu sunete precum 'Laratul unui câine', 'Valuri', 'Ploaie' și altele. Vom folosi subsetul ESC10 din datasetul [1]. Pentru a realiza clasificarea vom implementa o metoda o metoda de baza, folosită ca baseline pentru dataset.

Î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. Vom încerca să ne construim niște feature-uri care surprind bine spectrul sunetelor.

Primul tip de feature numit zero-crossing rate este media schimbărilor semnalului din pozitiv în negativ. Acesta ar putea fi un indiciu al frecventelor medii din semnal.

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 regiuni, iar fiecărei regiuni 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, adică aplicăm fft(fereastra,256) în matlab
  3. vrem sa vedem cât de puternice sunt frecventele din mai multe (Nr_coeficienti) intervale. De exemplu plânsul unui copil are frecvente mai mari față de sunetul valurilor. Asa că ne vom stabili câteva intervale și vom aproximaun puterea medie a frecvențelor din fiecare interval. Pentru aceasta vom înmulți element cu element fiecare spectrul cu câte un filtru pentru fiecare interval, apoi vom face suma acestor elemente. În totul vom avea o valoare rezultată pentru fiecare interval. Filtru va avea dimensiunea spectrului (256) și valori diferite de zero doar în acel interval, de la 0 crescând liniar până la 1 în centrul intervalului și înapoi la zero. La sfârșit vom aplica logaritm pe rezultat. La final ar trebui să avem Nr_coeficienti valori pentru fiecare frame. Vom folosi intervale de mărimi din ce în ce mai mari, precum în imaginea următoare, unde fiecare filtru are o culoare diferită.

  1. [opțional] aplicat discrete cosine transform (dct) pe răspunsurile din fiecare fereastră
  2. la final featurile MFCC folosite vor fi media și varianță peste toate ferestrele adică un vector de dimensiune 2 * Nr_coeficienti

În total, pentru fiecare semnal vom avea 2*Nr_coeficienti valori reprezentând coeficienții MFCC plus 1 valoare reprezentând zero-crossing. Aceste feature-uri, puse într-un vector cu 2*Nr_coeficienti+1 elemente ne va caracteriza semnalul nostru audio. 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/tema.txt · Last modified: 2018/12/05 10:56 by andrei.nicolicioiu
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