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 del género musical usando dispersión de tiempo wavelet

Este ejemplo muestra cómo clasificar el género de un fragmento musical utilizando la dispersión de tiempo de wavelet y el almacén de datos de audio. En la dispersión de Wavelet, los datos se propagan a través de una serie de transformaciones de Wavelet, no linealidades y promediación para producir representaciones de baja varianza de los datos. Estas representaciones de baja varianza se utilizan entonces como entradas para un clasificador.

GTZAN DataSet

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 tar comprimido que es aproximadamente 1,2 GB. El conjunto de datos sin comprimir requiere aproximadamente 3 GB de espacio en disco. Extraer el archivo tar comprimido del enlace proporcionado anteriormente crea una carpeta con diez subcarpetas. Cada subcarpeta se nombra para el 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 documento original, los autores utilizaron una serie de características de dominio de tiempo y de frecuencia, incluyendo coeficientes de cefstral de frecuencia Mel (MFC) extraídos de cada ejemplo de música y una clasificación de modelo de mezcla gaussiana (GMM) para lograr una precisión de 61 % [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 de MFC como la entrada a la CNN profunda. Estos enfoques han dado como resultado un rendimiento de alrededor del 84% [4]. Un enfoque de LSTM con divisiones de tiempo de espectrograma dio lugar a un 79% de precisión y las características de dominio de tiempo y de dominio de frecuencia junto con un enfoque de aprendizaje conjunto (AdaBoost) resultaron en un 82% de precisión en un conjunto de pruebas [2] [3]. Recientemente, un enfoque de aprendizaje automático de representación dispersa alcanzó aproximadamente 89% de precisión [6].

Marco de dispersión wavelet

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

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

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

[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 

Audio datastore

El almacén de datos de audio le permite administrar colecciones de archivos de audio. Para el aprendizaje en máquina o en profundidad, el almacén de datos de audio no solo gestiona el flujo de audio de archivos y carpetas, el almacén de datos de audio también gestiona la Asociación de etiquetas con los datos y proporciona la capacidad de particionar aleatoriamente sus 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 de música GTZAN. Recuerde que cada subcarpeta de la colección se denomina para el género que representa. Establezca la propiedad para indicar al almacén de datos de audio que utilice subcarpetas y establezca la propiedad en la que se crearán las etiquetas basadas en los nombres de subcarpeta.'IncludeSubFolders'true'LabelSource''foldernames' Este ejemplo asume que el directorio de nivel superior está dentro de su directorio MATLAB y se llama ' géneros '.tempdir Asegúrese de que es la ruta correcta a la carpeta de datos de nivel superior en su equipo.location La carpeta de datos de nivel superior en su máquina debe contener diez subcarpetas cada una con nombre para los diez géneros y sólo 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 indicó anteriormente, hay 10 géneros con 100 archivos cada uno.

Conjuntos de entrenamiento y pruebas

Cree conjuntos de entrenamiento y pruebas para desarrollar y probar nuestro clasificador. Utilizamos el 80% de los datos para entrenar y mantener el 20% restante para las pruebas. La función del almacén de datos de audio se baraja aleatoriamente.shuffle Hágalo antes de dividir los datos por etiqueta para aleatorizar los datos. En este ejemplo, configuramos la semilla del generador de números aleatorios para 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 de alto MATLAB.audioDatastore Cree matrices altas para los conjuntos de entrenamiento y pruebas. Dependiendo de su sistema, el número de trabajadores en el grupo paralelo que MATLAB crea 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 logaritmo natural de las entidades de dispersión para 2 ^ 19 muestras de cada archivo de audio y submuestrea el número de ventanas de dispersión por 8.helperscatfeatures El código fuente para aparece en el apéndice.helperscatfeatures Calcularemos las características de dispersión de wavelet para los datos de entrenamiento y prueba.

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

Calcule las entidades de dispersión en los datos de entrenamiento y agrupe 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 rutas de 341 en la transformación de dispersión de cada señal de audio.TrainFeaturesTestFeatures Para cada muestra de música, tenemos 32 tales ventanas de tiempo. En consecuencia, la matriz de características para los datos de entrenamiento es 25600-by-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). De forma similar, la matriz de características de dispersión para los datos de prueba es 6400-by-341. Hay 200 ejemplos de prueba y 32 ventanas por ejemplo. Cree una etiqueta de género para cada una de las ventanas 32 en la matriz de características de dispersión de wavelet 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 de vectores de soporte (SVM) de varias clases con un kernel polinómico cúbico. Ajuste el SVM 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)); 

Test Set prediction

Utilice el modelo SVM apto para las transformaciones de dispersión de los datos de entrenamiento para predecir los géneros musicales para los datos de prueba. Recuerde que hay 32 ventanas de tiempo para cada señal en la transformación de dispersión. Usa un voto por mayoría simple para predecir el género. La función auxiliar obtiene el modo de las etiquetas de género sobre todas las ventanas de dispersión 32.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 aparece 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 DataSet GTZAN.

Visualice la matriz de confusión para inspeccionar las tasas de precisión de género por género. Recordemos 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 precisiones de clasificación para los géneros individuales son bastante buenas en general. Extraiga estas precisiones 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

Este ejemplo demostró el uso de la dispersión de tiempo de wavelet y el almacén de datos de audio en la clasificación de género musical. En este ejemplo, la dispersión de tiempo de wavelet alcanzó una precisión de clasificación comparable al rendimiento del estado de la técnica para el DataSet GTZAN. A diferencia de otros enfoques que requieren la extracción de un número de características de dominio de tiempo y de dominio de frecuencia, la dispersión de wavelet 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 eficientemente la transferencia de un gran DataSet desde el disco a MATLAB y nos permitió aleatorizar los datos y retener 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 en 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 la clasificación musical. Machine learning, Vol. 65, número 2-3, PP. 473-484.

  3. Irvin, J., Chartock, E., y Hollander, N. 2016. Redes neuronales recurrentes con atención a 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 patrones musicales mediante red neuronal convolucional. Conferencia Internacional de minería de datos y aplicaciones.

  5. MALLAT. S. 2012. Agrupar la dispersión invariable. Comunicaciones en matemática pura y aplicada, Vol. 65, 10, PP. 1331-1398.

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

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

  8. .GTZAN Genre Collectionhttp://marsyas.info/downloads/datasets.html

Apéndice--funciones de apoyo

--Esta función devuelve el modo de las etiquetas de clase pronosticadas en un número de vectores de características.helperMajorityVote En la dispersión de tiempo de Wavelet, 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 wavelet para una señal de entrada dada.helperscatfeatures En este caso, utilizamos el logaritmo natural de los coeficientes de dispersión de wavelet. La matriz de la entidad de dispersión se calcula en 2 ^ 19 muestras 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