Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Clasificación de género musical mediante la dispersión de tiempo de wavelet

En este ejemplo se muestra cómo clasificar el género de un extracto musical mediante la dispersión de tiempo de las ondas y el almacén de datos de audio. En la dispersión de ondas, los datos se propagan a través de una serie de transformaciones de wavelet, no linealidades y promedio para producir representaciones de baja varianza de los datos. Estas representaciones de baja varianza se utilizan como entradas para un clasificador.

Conjunto de datos GTZAN

El conjunto de datos utilizado en este ejemplo es la colección de géneros GTZAN [7][8]. Los datos se proporcionan como un archivo de alquitrán comprimido que es de aproximadamente 1,2 GB. El conjunto de datos sin comprimir requiere aproximadamente 3 GB de espacio en disco. Extraer el archivo tar comprimido del vínculo proporcionado en las referencias crea una carpeta con diez subcarpetas. Cada subcarpeta recibe el nombre del género de muestras de música que contiene. Los géneros son: blues, clásico, country, disco, hiphop, jazz, metal, pop, reggae y rock. Hay 100 ejemplos de cada género y cada archivo de audio consta de unos 30 segundos de datos muestreados a 22050 Hz. En el artículo original, los autores utilizaron una serie de características de dominio de tiempo y dominio de frecuencia, incluidos los coeficientes cepstrales de frecuencia mel (MFC) extraídos de cada ejemplo musical y una clasificación de modelo de mezcla gaussiana (GMM) para lograr una precisión de 61 por ciento [7]. Posteriormente, se han aplicado redes de aprendizaje profundo a estos datos. En la mayoría de los casos, estos enfoques de aprendizaje profundo consisten en redes neuronales convolucionales (CNN) con los coeficientes o espectrogramas MFC como la entrada a la CNN profunda. Estos enfoques han dado lugar a un rendimiento de alrededor del 84% [4]. Un enfoque LSTM con segmentos de tiempo de espectrograma dio como resultado una precisión del 79% y características de dominio de tiempo y dominio de frecuencia junto con un enfoque de aprendizaje en conjunto (AdaBoost) resultó en una precisión del 82% en un conjunto de pruebas [2][3]. Recientemente, un enfoque de aprendizaje automático de representación dispersa logró aproximadamente un 89% de precisión [6].

Wavelet Scattering Framework

Los únicos parámetros que se especifican en un marco de dispersión de tiempo de onda son la duración de la invariancia de tiempo, el número de bancos de filtros de wavelet y el número de wavelets por octava. Para la mayoría de las aplicaciones, es suficiente conectar los datos a través de dos bancos de filtros de ondas. En este ejemplo, usamos el marco de dispersión predeterminado que utiliza dos bancos de filtro de wavelet. El primer banco de filtros tiene 8 wavelets por octava y el segundo banco de filtros tiene 1 wavelet por octava. En este ejemplo, establezca la escala invariable en 0,5 segundos, que corresponde a algo más de 11.000 muestras para la frecuencia de muestreo dada. Cree el marco de descomposición de dispersión de tiempo de ola.

sf = waveletScattering('SignalLength',2^19,'SamplingFrequency',22050,...     'InvarianceScale',0.5); 

Para comprender el papel de la escala de invariancia, obtenga y trace el filtro de escala en el tiempo junto con las partes reales e imaginarias de la onda de escala más gruesa del primer banco de filtros. Tenga en cuenta que el soporte de tiempo del filtro de escalado es esencialmente 0,5 segundos según lo diseñado. Además, el soporte de tiempo de la wavelet de escala más gruesa no supera la escala invariable de la descomposición de dispersión de la letlet.

[fb,f,filterparams] = filterbank(sf); phi = ifftshift(ifft(fb{1}.phift)); psiL1 = ifftshift(ifft(fb{2}.psift(:,end))); dt = 1/22050; time = -2^18*dt:dt:2^18*dt-dt; scalplt = plot(time,phi,'linewidth',1.5); hold on grid on ylimits = [-3e-4 3e-4]; ylim(ylimits); plot([-0.25 -0.25],ylimits,'k--'); plot([0.25 0.25],ylimits,'k--'); xlim([-0.6 0.6]); xlabel('Seconds'); ylabel('Amplitude'); wavplt = plot(time,[real(psiL1) imag(psiL1)]); legend([scalplt wavplt(1) wavplt(2)],{'Scaling Function','Wavelet-Real Part','Wavelet-Imaginary Part'}); title({'Scaling Function';'Coarsest-Scale Wavelet First Filter Bank'}) hold off 

Almacén de datos de audio

El almacén de datos de audio le permite administrar colecciones de archivos de datos de audio. Para el aprendizaje automático o profundo, el almacén de datos de audio no solo administra el flujo de datos de audio de archivos y carpetas, sino que también gestiona la asociación de etiquetas con los datos y proporciona la capacidad de particionar aleatoriamente los datos en diferentes conjuntos para capacitación, validación y pruebas. En este ejemplo, utilice el almacén de datos de audio para administrar la colección de géneros musicales GTZAN. Recuerde que cada subcarpeta de la colección recibe el nombre del género que representa. Establezca la propiedad en para indicar al almacén de datos de audio que use subcarpetas y establezca la propiedad en crear etiquetas de datos basadas en los nombres de subcarpeta.'IncludeSubFolders'true'LabelSource''foldernames' En este ejemplo se supone que el directorio de nivel superior está dentro del directorio MATLAB y se denomina 'géneros'.tempdir Asegúrese de que esla ruta correcta a la carpeta de datos de nivel superior del equipo.location La carpeta de datos de nivel superior del equipo debe contener diez subcarpetas cada una con el nombre de los diez géneros y solo debe contener archivos de audio correspondientes a esos géneros.

location = fullfile(tempdir,'genres'); ads = audioDatastore(location,'IncludeSubFolders',true,...     'LabelSource','foldernames'); 

Ejecute lo siguiente para obtener un recuento de los géneros musicales en el conjunto de datos.

countEachLabel(ads) 
 ans =    10×2 table        Label      Count     _________    _____      blues         100      classical     100      country       100      disco         100      hiphop        100      jazz          100      metal         100      pop           100      reggae        100      rock          100   

Como se ha indicado anteriormente, hay 10 géneros con 100 archivos cada uno.

Conjuntos de Entrenamiento y Pruebas

Crear entrenamiento y conjuntos de pruebas para desarrollar y probar nuestro clasificador. Utilizamos el 80% de los datos para la formación y mantenemos el 20% restante para las pruebas. La función del almacén de datos de audio baraja aleatoriamente los datos.shuffle Haga esto antes de dividir los datos por etiqueta para aleatorizar los datos. En este ejemplo, establecemos la semilla del generador de números aleatorios para la reproducibilidad. Utilice la función de almacén de datos de audio para realizar la división 80-20. garantiza que todas las clases estén igualmente representadas.splitEachLabelsplitEachLabel

rng(100); ads = shuffle(ads); [adsTrain,adsTest] = splitEachLabel(ads,0.8); countEachLabel(adsTrain) countEachLabel(adsTest) 
 ans =    10×2 table        Label      Count     _________    _____      blues         80       classical     80       country       80       disco         80       hiphop        80       jazz          80       metal         80       pop           80       reggae        80       rock          80     ans =    10×2 table        Label      Count     _________    _____      blues         20       classical     20       country       20       disco         20       hiphop        20       jazz          20       metal         20       pop           20       reggae        20       rock          20    

Verá que hay 800 registros en los datos de entrenamiento según lo esperado y 200 registros en los datos de prueba. Además, hay 80 ejemplos de cada género en el conjunto de entrenamiento y 20 ejemplos de cada género en el conjunto de pruebas.

funciona con matrices altas de MATLAB.audioDatastore Cree matrices altas para los conjuntos de entrenamiento y de prueba. Dependiendo del sistema, el número de trabajadores en el grupo paralelo que crea MATLAB puede ser diferente.

Ttrain = tall(adsTrain); Ttest = tall(adsTest); 
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6). 

Para obtener las características de dispersión, defina una función auxiliar, , que obtiene el laritmo natural de las entidades de dispersión para muestras de 2 a 19 de cada archivo de audio y submuestrea el número de ventanas de dispersión por 8.helperscatfeatures El código fuente para se muestra en el apéndice.helperscatfeatures Calcularemos las características de dispersión de wavelet para los datos de entrenamiento y de prueba.

scatteringTrain = cellfun(@(x)helperscatfeatures(x,sf),Ttrain,'UniformOutput',false); scatteringTest = cellfun(@(x)helperscatfeatures(x,sf),Ttest,'UniformOutput',false); 

Calcular las entidades de dispersión en los datos de entrenamiento y agrupar todas las entidades en una matriz. Este proceso tarda varios minutos.

TrainFeatures = gather(scatteringTrain); TrainFeatures = cell2mat(TrainFeatures); 
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 8 min 9 sec Evaluation completed in 8 min 9 sec 

Repita este proceso para los datos de prueba.

TestFeatures = gather(scatteringTest); TestFeatures = cell2mat(TestFeatures); 
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 2 min 6 sec Evaluation completed in 2 min 6 sec 

Cada fila de y es una ventana de tiempo de dispersión a través de las 341 rutas en la transformación de dispersión de cada señal de audio.TrainFeaturesTestFeatures Para cada muestra de música, tenemos 32 ventanas de tiempo de este tipo. En consecuencia, la matriz de características para los datos de entrenamiento es 25600-por-341. El número de filas es igual al número de ejemplos de entrenamiento (800) multiplicado por el número de ventanas de dispersión por ejemplo (32). Del mismo modo, la matriz de entidades de dispersión para los datos de prueba es 6400 por 341. Hay 200 ejemplos de prueba y 32 ventanas por ejemplo. Cree una etiqueta de género para cada una de las 32 ventanas de la matriz de entidades de dispersión de ondas para los datos de entrenamiento.

numTimeWindows = 32; trainLabels = adsTrain.Labels; numTrainSignals = numel(trainLabels); trainLabels = repmat(trainLabels,1,numTimeWindows); trainLabels = reshape(trainLabels',numTrainSignals*numTimeWindows,1); 

Repita el proceso para los datos de prueba.

testLabels = adsTest.Labels; numTestSignals = numel(testLabels); testLabels = repmat(testLabels,1,numTimeWindows); testLabels = reshape(testLabels',numTestSignals*numTimeWindows,1); 

En este ejemplo, utilice un clasificador de máquina vectorial de soporte multiclase (SVM) con un kernel polinómio cúbico. Ajuste la smnes a los datos de entrenamiento.

template = templateSVM(...     'KernelFunction', 'polynomial', ...     'PolynomialOrder', 3, ...     'KernelScale', 'auto', ...     'BoxConstraint', 1, ...     'Standardize', true); Classes = {'blues','classical','country','disco','hiphop','jazz',...     'metal','pop','reggae','rock'}; classificationSVM = fitcecoc(...     TrainFeatures, ...     trainLabels, ...     'Learners', template, ...     'Coding', 'onevsone','ClassNames',categorical(Classes)); 

Predicción del conjunto de pruebas

Utilice el modelo SVM adecuado a las transformaciones de dispersión de los datos de entrenamiento para predecir los géneros musicales de los datos de prueba. Recuerde que hay 32 ventanas de tiempo para cada señal en la transformación de dispersión. Utilice un voto de mayoría simple para predecir el género. La función auxiliar obtiene el modo de las etiquetas de género en las 32 ventanas de dispersión.helperMajorityVote Si no hay ningún modo único, devuelve un error de clasificación indicado por .helperMajorityVote'NoUniqueMode' Esto da como resultado una columna adicional en la matriz de confusión. El código fuente para se muestra en el apéndice.helperMajorityVote

predLabels = predict(classificationSVM,TestFeatures); [TestVotes,TestCounts] = helperMajorityVote(predLabels,adsTest.Labels,categorical(Classes)); testAccuracy = sum(eq(TestVotes,adsTest.Labels))/numTestSignals*100; 

La precisión de la prueba, , es del 88 por ciento.testAccuracy Esta precisión es comparable con el estado de la técnica del conjunto de datos GTZAN.

Muestre la matriz de confusión para inspeccionar las tasas de precisión género por género. Recuerde que hay 20 ejemplos en cada clase.

confusionchart(TestVotes,adsTest.Labels); 

La diagonal de la gráfica de matriz de confusión muestra que las precisiónes de clasificación para los géneros individuales es bastante buena en general. Extraiga estas precisiónes de género y trace por separado.

cm = confusionmat(TestVotes,adsTest.Labels); cm(:,end) = []; genreAccuracy = diag(cm)./20*100; figure; bar(genreAccuracy) set(gca,'XTickLabels',Classes); xtickangle(gca,30); title('Percentage Correct by Genre - Test Set'); 

Resumen

En este ejemplo se muestra el uso de la dispersión de tiempo de wavelet y el almacén de datos de audio en la clasificación de géneros musicales. En este ejemplo, la dispersión de tiempo de las ondas logró una precisión de clasificación comparable al rendimiento de última generación para el conjunto de datos GTZAN. A diferencia de otros enfoques que requieren la extracción de una serie de características de dominio de tiempo y dominio de frecuencia, la dispersión de ondas solo requería la especificación de un único parámetro, la escala del tiempo invariable. El almacén de datos de audio nos permitió gestionar de forma eficiente la transferencia de un gran conjunto de datos desde el disco a MATLAB y nos permitió aleatorizar los datos y conservar con precisión la pertenencia al género de los datos aleatorios a través del flujo de trabajo de clasificación.

Referencias

  1. Anden, J. y Mallat, S. 2014. Espectro de dispersión profunda. Transacciones IEEE sobre el procesamiento de señales, Vol. 62, 16, pp. 4114-4128.

  2. Bergstra, J., Casagrande, N., Erhan, D., Eck, D., y Kegl, B. Características agregadas y AdaBoost para clasificación musical. Machine Learning, Vol. 65, Número 2-3, págs. 473-484.

  3. Irvin, J., Chartock, E., and Hollander, N. 2016. Redes neuronales recurrentes con atención para la clasificación de géneros. https://www.semanticscholar.org/paper/Recurrent-Neural-Networks-with-Attention-for-Genre-Irvin-Chartock/bff3eaf5d8ebb6e613ae0146158b2b5346ee7323

  4. Li, T., Chan, A.B., y Chun, A. 2010. Extracción automática de características de patrón musical mediante red neuronal convolucional. Minería y Aplicaciones de Datos de Conferencia Internacional.

  5. Mallat. S. 2012. Agrupar dispersión invariable. Comunicaciones sobre Matemáticas Puras y Aplicadas, Vol. 65, 10, pp. 1331-1398.

  6. Panagakis, Y., Kotropoulos, C.L., y Arce, G.R. 2014. Clasificación de género musical a través de una representación conjunta de bajo rango de características de audio. Transacciones IEEE sobre audio, voz y procesamiento de lenguaje, 22, 12, págs. 1905-1917.

  7. Tzanetakis, G. and Cook, P. 2002. Clasificación de género musical de señales de audio. Transacciones IEEE sobre procesamiento de voz y audio, Vol. 10, No. 5, págs. 293 a 302.

  8. .Colección de género GTZANhttp://marsyas.info/downloads/datasets.html

Apéndice -- Funciones de apoyo

-- Esta función devuelve el modo de las etiquetas de clase predichas en un número de vectores de entidades.helperMajorityVote En la dispersión de tiempo de olas, obtenemos una etiqueta de clase para cada ventana de tiempo. Si no se encuentra ningún modo único, se devuelve una etiqueta de 'NoUniqueMode' para denotar un error de clasificación.

 function [ClassVotes,ClassCounts] = helperMajorityVote(predLabels,origLabels,classes) % This function is in support of wavelet scattering examples only. It may % change or be removed in a future release.  % Make categorical arrays if the labels are not already categorical predLabels = categorical(predLabels); origLabels = categorical(origLabels); % Expects both predLabels and origLabels to be categorical vectors Npred = numel(predLabels); Norig = numel(origLabels); Nwin = Npred/Norig; predLabels = reshape(predLabels,Nwin,Norig); ClassCounts = countcats(predLabels); [mxcount,idx] = max(ClassCounts); ClassVotes = classes(idx); % Check for any ties in the maximum values and ensure they are marked as % error if the mode occurs more than once modecnt = modecount(ClassCounts,mxcount); ClassVotes(modecnt>1) = categorical({'NoUniqueMode'}); ClassVotes = ClassVotes(:);  %-------------------------------------------------------------------------     function modecnt = modecount(ClassCounts,mxcount)         modecnt = Inf(size(ClassCounts,2),1);         for nc = 1:size(ClassCounts,2)             modecnt(nc) = histc(ClassCounts(:,nc),mxcount(nc));         end     end end  

- Esta función devuelve la matriz de características de dispersión de tiempo de onda para una señal de entrada determinada.helperscatfeatures En este caso, utilizamos el logarithm natural de los coeficientes de dispersión de ondas. La matriz de entidades de dispersión se calcula en muestras de 2 a 19 de una señal. Las entidades de dispersión se submuestrean por un factor de 8.

 function features = helperscatfeatures(x,sf) % This function is in support of wavelet scattering examples only. It may % change or be removed in a future release.  features = featureMatrix(sf,x(1:2^19),'Transform','log'); features = features(:,1:8:end)'; end