Этот пример показывает, как классифицировать жанр музыкальной выборки с помощью времени вейвлета, рассеявшись и аудио datastore. В рассеивании вейвлета данные распространены через серию вейвлета, преобразовывает, нелинейность и усреднение, чтобы произвести представления низкого отклонения данных. Эти представления низкого отклонения затем используются в качестве входных параметров к классификатору.
Набор данных, используемый в этом примере, является Набором Жанра GTZAN [7] [8]. Данные обеспечиваются как заархивированный архив tar, который составляет приблизительно 1,2 Гбайт. Несжатый набор данных требует приблизительно 3 Гбайт дискового пространства. Извлечение сжатого файла tar от ссылки, обеспеченной выше, создает папку с десятью подпапками. Каждая подпапка названа по имени жанра музыкальных выборок, которые это содержит. Жанры: блюз, классический, страна, дискотека, хип-хоп, джаз, металл, поп, регги и скала. Существует 100 примеров каждого жанра, и каждый звуковой файл состоит приблизительно из 30 секунд данных, выбранных на уровне 22 050 Гц. В исходной газете авторы использовали много временных интервалов и функций частотного диапазона включая коэффициенты mel-частоты cepstral (MFC), извлеченные от каждого музыкального примера и классификации Гауссовых моделей смеси (GMM), чтобы достигнуть точности 61 процента [7]. Впоследствии, нейронные сети для глубокого обучения были применены к этим данным. В большинстве случаев эти подходы глубокого обучения состоят из сверточных нейронных сетей (CNN) с коэффициентами MFC или спектрограммами как вход к глубокому CNN. Эти подходы привели к производительности приблизительно 84% [4]. Подход LSTM с интервалами времени спектрограммы привел к 79%-й точности и временному интервалу и функциям частотного диапазона вместе с ансамблем, узнающим, что подход (AdaBoost) привел к 82%-й точности на наборе тестов [2] [3]. Недавно, разреженный подход машинного обучения представления достиг приблизительно 89%-й точности [6].
Единственные параметры, чтобы задать в среде рассеивания времени вейвлета являются длительностью инвариантности времени, количеством наборов фильтров вейвлета и количеством вейвлетов на октаву. Для большинства приложений, располагая каскадом данные через два набора фильтров вейвлета достаточно. В этом примере мы используем среду рассеивания значения по умолчанию, которая использует два набора фильтров вейвлета. Первый набор фильтров имеет 8 вейвлетов на октаву, и второй набор фильтров имеет 1 вейвлет на октаву. В данном примере установите инвариантную шкалу составлять 0,5 секунды, который соответствует немного больше чем 11 000 выборок для данной выборки уровня. Создайте время вейвлета, рассеивая среду разложения.
sf = waveletScattering('SignalLength',2^19,'SamplingFrequency',22050,... 'InvarianceScale',0.5);
Чтобы понять роль шкалы инвариантности, получите и постройте масштабирующийся фильтр вовремя наряду с действительными и мнимыми частями вейвлета самой грубой шкалы от первого набора фильтров. Обратите внимание на то, что поддержка времени масштабирующегося фильтра является по существу 0,5 секундами, как разработано. Далее, поддержка времени вейвлета самой грубой шкалы не превышает инвариантную шкалу разложения рассеивания вейвлета.
[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
Аудио datastore позволяет вам управлять наборами файлов аудиоданных. Для машины или глубокого обучения, аудио datastore не только управляет потоком аудиоданных из файлов и папок, аудио datastore также управляет ассоциацией меток с данными и обеспечивает способность случайным образом разделить ваши данные в различные наборы для обучения, валидации и тестирования. В этом примере используйте аудио datastore, чтобы управлять музыкальным набором жанра GTZAN. Вспомните, что каждая подпапка набора названа по имени жанра, который это представляет. Установите свойство 'IncludeSubFolders'
на true
давать аудио datastore команду использовать подпапки и устанавливать свойство 'LabelSource'
на 'foldernames'
создавать метки данных на основе подымен папок. Этот пример принимает, что директория верхнего уровня в вашей директории MATLAB tempdir
и называется 'жанрами'. Гарантируйте, что location
является правильным путем к папке данных верхнего уровня на вашей машине. Папка данных верхнего уровня на вашей машине должна содержать десять подпапок каждый названный по имени этих десяти жанров и должна только содержать звуковые файлы, соответствующие тем жанрам.
location = fullfile(tempdir,'genres'); ads = audioDatastore(location,'IncludeSubFolders',true,... 'LabelSource','foldernames');
Запустите следующее, чтобы получить количество музыкальных жанров в наборе данных.
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
Как ранее утверждено, существует 10 жанров с 100 файлами каждый.
Создайте наборы обучающих данных и наборы тестов, чтобы разработать и протестировать наш классификатор. Мы используем 80% данных для обучения и протягиваем остающиеся 20% для тестирования. Функция shuffle
аудио datastore случайным образом переставляет данные. Сделайте это до разделения данных меткой, чтобы рандомизировать данные. В этом примере мы устанавливаем seed генератора случайных чисел для воспроизводимости. Используйте аудио datastore функция splitEachLabel
, чтобы выполнить разделение 80-20. splitEachLabel
гарантирует, что все классы одинаково представлены.
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
Вы видите, что существует 800 записей в данных тренировки как ожидалось и 200 записей в тестовых данных. Кроме того, существует 80 примеров каждого жанра в наборе обучающих данных и 20 примеров каждого жанра в наборе тестов.
audioDatastore
работает с длинными массивами MATLAB. Создайте длинные массивы и для наборов обучающих данных и для наборов тестов. В зависимости от вашей системы количество рабочих в параллельном пуле, который создает MATLAB, может отличаться.
Ttrain = tall(adsTrain); Ttest = tall(adsTest);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Чтобы получить рассеивающиеся функции, задайте функцию помощника, helperscatfeatures
, который получает натуральный логарифм рассеивающихся функций 2^19 выборки каждого звукового файла и подвыбирает количество рассеивающихся окон 8. Исходный код для helperscatfeatures
перечислен в приложении. Мы вычислим функции рассеивания вейвлета и обучения и тестовых данных.
scatteringTrain = cellfun(@(x)helperscatfeatures(x,sf),Ttrain,'UniformOutput',false); scatteringTest = cellfun(@(x)helperscatfeatures(x,sf),Ttest,'UniformOutput',false);
Вычислите рассеивающиеся функции на данных тренировки и свяжите все функции вместе в матрице. Этот процесс занимает несколько минут.
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
Повторите этот процесс для тестовых данных.
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
Каждая строка TrainFeatures
и TestFeatures
является одним окном времени рассеивания через этот 341 путь в рассеивающемся преобразовании каждого звукового сигнала. Для каждой музыкальной выборки у нас есть 32 таких окна времени. Соответственно, матрица функции для данных тренировки 25600 341. Количество строк равно количеству учебных примеров (800) умноженный на количество рассеивающихся окон на пример (32). Точно так же рассеивающаяся матрица функции для тестовых данных 6400 341. Существует 200 тестовых примеров и 32 окна на пример. Создайте метку жанра для каждого из этих 32 окон в вейвлете, рассеивающем матрицу функции для данных тренировки.
numTimeWindows = 32; trainLabels = adsTrain.Labels; numTrainSignals = numel(trainLabels); trainLabels = repmat(trainLabels,1,numTimeWindows); trainLabels = reshape(trainLabels',numTrainSignals*numTimeWindows,1);
Повторите процесс для тестовых данных.
testLabels = adsTest.Labels; numTestSignals = numel(testLabels); testLabels = repmat(testLabels,1,numTimeWindows); testLabels = reshape(testLabels',numTestSignals*numTimeWindows,1);
В этом примере используйте классификатор машины вектора поддержки (SVM) мультикласса с ядром кубического полинома. Соответствуйте SVM к данным тренировки.
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));
Используйте подгонку модели SVM к рассеивающимся преобразованиям данных тренировки, чтобы предсказать музыкальные жанры для тестовых данных. Отзыв там является 32 разами окна для каждого сигнала в рассеивающемся преобразовании. Используйте голосование простого большинства, чтобы предсказать жанр. Функция помощника helperMajorityVote
получает режим меток жанра по всем 32 рассеивающимся окнам. Если нет никакого уникального режима, helperMajorityVote
возвращает ошибку классификации, обозначенную 'NoUniqueMode'
. Это приводит к дополнительному столбцу в матрице беспорядка. Исходный код для helperMajorityVote
перечислен в приложении.
predLabels = predict(classificationSVM,TestFeatures); [TestVotes,TestCounts] = helperMajorityVote(predLabels,adsTest.Labels,categorical(Classes)); testAccuracy = sum(eq(TestVotes,adsTest.Labels))/numTestSignals*100;
Тестовая точность, testAccuracy
, составляет 88 процентов. Эта точность сопоставима с состоянием набора данных GTZAN.
Отобразите матрицу беспорядка, чтобы осмотреть степени точности жанра жанром. Отзыв там является 20 примерами в каждом классе.
confusionchart(TestVotes,adsTest.Labels);
Диагональ матричного графика беспорядка показывает, что точность классификации для отдельных жанров довольно хороша в целом. Извлеките эту точность жанра и постройте отдельно.
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');
Этот пример продемонстрировал использование времени вейвлета, рассеявшись и аудио datastore в музыкальной классификации жанров. В этом примере рассеивание времени вейвлета достигло точности классификации, сопоставимой с современной производительностью для набора данных GTZAN. В противоположность другим подходам, требующим экстракции многого временного интервала и функций частотного диапазона, вейвлет, рассеивающийся только, потребовал спецификации одного параметра, шкалы независимого от времени. Аудио datastore позволил нам эффективно справиться с передачей большого набора данных от диска в MATLAB и разрешил нам рандомизировать данные и точно сохранять членство в жанре рандомизированных данных через рабочий процесс классификации.
Anden, J. и Mallat, S. 2014. Глубоко рассеивание спектра. Транзакции IEEE на Обработке сигналов, Издании 62, 16, стр 4114-4128.
Bergstra, J., Casagrande, N., Erhan, D., Eck, D. и Kegl, B. Совокупные функции и AdaBoost для музыкальной классификации. Машинное обучение, Издание 65, Выпуск 2-3, стр 473-484.
Ирвин, J., Chartock, E. и Hollander, N. 2016. Рекуррентные нейронные сети с вниманием для классификации жанров. https://www.semanticscholar.org/paper/Recurrent-Neural-Networks-with-Attention-for-Genre-Irvin-Chartock/bff3eaf5d8ebb6e613ae0146158b2b5346ee7323
Литий, T., Канал, A.B., и Чун, A. 2010. Автоматическое музыкальное выделение признаков шаблона с помощью сверточной нейронной сети. Анализ данных Международной конференции и Приложения.
Mallat. S. 2012. Рассеивание инварианта группы. Коммуникации на Чистой и Прикладной математике, Издании 65, 10, стр 1331-1398.
Panagakis, Y., Котропулос, C.L., и Арке, G.R. 2014. Музыкальная классификация жанров через объединенное разреженное представление низкого ранга функций аудио. Транзакции IEEE на Аудио, Речи и Обработке Языка, 22, 12, стр 1905-1917.
Tzanetakis, G. и Повар, P. 2002. Музыкальная классификация жанров звуковых сигналов. Транзакции IEEE о Речи и Обработке аудиоданных, Издании 10, № 5, стр 293-302.
Набор жанра GTZAN. http://marsyas.info/downloads/datasets.html
helperMajorityVote - Эта функция возвращает режим меток класса, предсказанных по многим характеристическим векторам. Во время вейвлета, рассеиваясь, мы получаем метку класса в течение каждого раза окно. Если никакой уникальный режим не найден, что марка 'NoUniqueMode' возвращена, чтобы обозначить ошибку классификации.
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
helperscatfeatures - Эта функция возвращает время вейвлета, рассеивая матрицу функции для данного входного сигнала. В этом случае мы используем натуральный логарифм коэффициентов рассеивания вейвлета. Рассеивающаяся матрица функции вычисляется на 2^19 выборки сигнала. Рассеивающиеся функции подвыбираются фактором 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