Время вейвлета, рассеиваясь с ускорением графического процессора — музыкальная классификация жанров

В этом примере показано, как ускорить расчет вейвлета, рассеивающего функции с помощью gpuArray и параллелизированная версия "в глубину" времени вейвлета, рассеиваясь. У вас должен быть CUDA-поддерживающий NVIDIA, графический процессор с вычисляет возможность 3.0 или выше. Смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox) для деталей.

Этот пример воспроизводит версию ЦП, найденную в Музыкальной Классификации Жанров Используя Время Вейвлета, Рассеиваясь. Пример использует функции рассеивания вейвлета с машиной опорных векторов, чтобы классифицировать жанр музыкальной выборки. Пример использует аудио datastore, чтобы справиться с чтением звуковых файлов от диска, а также создания наборов обучающих данных и наборов тестов.

Набор данных GTZAN

Набор данных, используемый в этом примере, является Набором Жанра 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 выборок для частоты дискретизации 22 050 Гц.

Создайте сеть рассеивания времени вейвлета.

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

Аудио Datastore

Используйте audioDatastore управлять музыкальным набором жанра GTZAN. Каждая подпапка набора названа по имени жанра, который это представляет. Установите 'IncludeSubFolders' свойство к true давать аудио datastore команду использовать подпапки и устанавливать 'LabelSource' свойство к 'foldernames' создать метки данных на основе подымен папок. Установите pathToData к вектору символов, содержащему папку данных верхнего уровня на вашей машине. Папка данных верхнего уровня на вашей машине должна содержать десять подпапок каждый названный по имени одного из этих десяти жанров и должна только содержать звуковые файлы, соответствующие тем жанрам. Этот пример принимает, что директория верхнего уровня в вашем tempdir MATLAB™ директория и называется 'genres'. Извлечение сжатого файла tar должно обеспечить папку, содержащую подпапки жанра.

pathToData = fullfile(tempdir,'genres');
location = pathToData;
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)
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  

countEachLabel(adsTest)
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 примеров каждого жанра в наборе тестов.

Чтобы получить рассеивающиеся функции, задайте функцию помощника, helperbatchscatfeatures, это получает натуральный логарифм рассеивающихся функций 2^19 выборки каждого звукового файла и подпроизводит количество рассеивающихся окон 8. Исходный код для helperscatfeatures перечислен в приложении. Функции рассеивания вейвлета вычисляются с помощью пакетного размера 64 сигналов. Использование gpuArray с CUDA-поддерживающим NVIDIA графический процессор обеспечивает значительное ускорение для этого пакетного расчета. С этой средой рассеивания, пакетным размером и графическим процессором (XP Титана NVIDIA), реализация графического процессора уменьшает время, должен был вычислить рассеивающиеся функции приблизительно фактором 7.

N = 2^19;
batchsize = 64;
scTrain = [];
while hasdata(adsTrain)
    sc = helperbatchscatfeatures(adsTrain,sf,N,batchsize);
    scTrain = cat(3,scTrain,sc);
end

Запишите количество окон времени в рассеивающемся преобразовании для создания метки.

numTimeWindows = size(sc,2);

Повторите процесс извлечения признаков для тестовых данных.

scTest = [];
while hasdata(adsTest)
   sc = helperbatchscatfeatures(adsTest,sf,N,batchsize);
   scTest = cat(3,scTest,sc); 
end

Определите количество путей в рассеивающейся сети и измените обучение и протестируйте функции в 2D матрицы.

[~,npaths] = sf.dfspaths();
Npaths = sum(npaths);
TrainFeatures = permute(scTrain,[2 3 1]);
TrainFeatures = reshape(TrainFeatures,[],Npaths,1);
TestFeatures = permute(scTest,[2 3 1]);
TestFeatures = reshape(TestFeatures,[],Npaths,1);

Каждая строка TrainFeatures и TestFeatures одно окно времени рассеивания через Npaths (341) пути в рассеивающемся преобразовании каждого звукового сигнала. Для каждой музыкальной выборки существует numTimeWindows такие окна времени. Соответственно, матрица функции для обучающих данных 25600 341. Количество строк равно количеству учебных примеров (800) умноженный на количество рассеивающихся окон на пример (32). Точно так же рассеивающаяся матрица функции для тестовых данных 6400 341. Существует 200 тестовых примеров и 32 окна на пример. Создайте метку жанра для каждого из этих 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'};
trainingOptions = struct('UseParallel',true);
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 = 87.5000

Тестовая точность, testAccuracy, приблизительно 87,5 процентов. Эта точность сопоставима с состоянием набора данных 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('GPU Example: Percent Correct by Genre (Test Set)');

Сводные данные

Этот пример продемонстрировал использование времени вейвлета, рассеявшись и аудио datastore в музыкальной классификации жанров. В этом примере рассеивание времени вейвлета достигло точности классификации, сопоставимой с современной производительностью для набора данных GTZAN. В противоположность другим подходам, требующим экстракции многого временного интервала и функций частотного диапазона, вейвлет, рассеивающийся только, потребовал спецификации одного параметра, шкалы независимого от времени. Аудио datastore позволил нам эффективно справиться с передачей большого набора данных от диска в MATLAB и разрешил нам рандомизировать данные и точно сохранять членство в жанре рандомизированных данных через рабочий процесс классификации.

Ссылки

  1. Anden, J. и Mallat, S. 2014. Глубоко рассеивание спектра. Транзакции IEEE на Обработке сигналов, Издании 62, 16, стр 4114-4128.

  2. Bergstra, J., Casagrande, N., Erhan, D., Eck, D. и Kegl, B. Совокупные функции и AdaBoost для музыкальной классификации. Машинное обучение, Издание 65, Выпуск 2-3, стр 473-484.

  3. Ирвин, J., Chartock, E. и Hollander, N. 2016. Рекуррентные нейронные сети с вниманием для классификации жанров. https://www.semanticscholar.org/paper/Recurrent-Neural-Networks-with-Attention-for-Genre-Irvin-Chartock/bff3eaf5d8ebb6e613ae0146158b2b5346ee7323

  4. Литий, T., Канал, A.B., и Чун, A. 2010. Автоматическая музыкальная сверточная нейронная сеть использования извлечения признаков шаблона. Анализ данных Международной конференции и Приложения.

  5. Mallat. S. 2012. Рассеивание инварианта группы. Коммуникации на Чистой и Прикладной математике, Издании 65, 10, стр 1331-1398.

  6. Panagakis, Y., Котропулос, C.L., и Арке, G.R. 2014. Музыкальная классификация жанров через объединенное разреженное представление низкого ранга функций аудио. Транзакции IEEE на Аудио, Речи и Обработке Языка, 22, 12, стр 1905-1917.

  7. Tzanetakis, G. и Повар, P. 2002. Музыкальная классификация жанров звуковых сигналов. Транзакции IEEE о Речи и Обработке аудиоданных, Издании 10, № 5, стр 293-302.

  8. Набор жанра 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

helperbatchscatfeatures — Эта функция возвращает время вейвлета, рассеивая матрицу функции для данного входного сигнала. В этом случае мы используем натуральный логарифм коэффициентов рассеивания вейвлета. Рассеивающаяся матрица функции вычисляется на 2^19 выборки сигнала. Рассеивающиеся функции подпроизводятся фактором 8.

function sc = helperbatchscatfeatures(ds,sf,N,batchsize)
% This function is only intended to support examples in the Wavelet
% Toolbox. It may be changed or removed in a future release.

% Read batch of data from audio datastore
batch = helperReadBatch(ds,N,batchsize);
% Obtain scattering features
S = sf.featureMatrix(batch,'transform','log');
% Subsample the features
sc = S(:,1:8:end,:);
end

helperReadBatch — Эта функция читает пакеты заданного размера от datastore. Каждый столбец выхода является отдельным сигналом от datastore. Выход может иметь меньше столбцов, чем batchsize, если datastore не имеет достаточного количества записей.

function batchout = helperReadBatch(ds,N,batchsize)
% This function is only in support of Wavelet Toolbox examples. It may
% change or be removed in a future release.
%
% batchout = readBatch(ds,batchsize) where ds is the Datastore and
%   ds is the Datastore
%   batchsize is the batchsize

kk = 1;

while(hasdata(ds)) && kk <= batchsize
    tmpRead = read(ds);
    batchout(:,kk) = tmpRead(1:N); %#ok<AGROW>
    kk = kk+1;
end

end

Смотрите также

Похожие темы