В этом примере показано, как создать последнюю систему сплава мультимодели для акустического распознавания сцены. Пример обучает сверточную нейронную сеть (CNN) с помощью mel спектрограммы и классификатор ансамбля с помощью рассеивания вейвлета. Пример использует набор данных TUT для обучения и оценки [1].
Акустическая классификация сцен (ASC) является задачей классификации сред от звуков, которые они производят. ASC является типовой проблемой классификации, которая является основополагающей для осведомленности контекста в устройствах, роботах и многих других приложениях [1]. Ранние попытки ASC использовали mel-частоту cepstral коэффициенты (mfcc
) и смешанные гауссовские модели (GMMs), чтобы описать их статистическое распределение. Другие популярные функции, использованные для ASC, включают нулевой уровень пересечения, спектральный центроид (spectralCentroid
), спектральный спад (spectralRolloffPoint
), спектральный поток (spectralFlux
), и коэффициенты линейного предсказания (lpc
) [5]. Скрытые модели Маркова (HMMs) были обучены описать временную эволюцию GMMs. Позже, лучшие системы выполнения использовали глубокое обучение, обычно CNNs и сплав многоуровневых моделей. Самой популярной функцией находящихся на вершине рейтинга систем в конкурсе DCASE 2017 была mel спектрограмма (melSpectrogram
). Находящиеся на вершине рейтинга системы в проблеме использовали последний сплав и увеличение данных, чтобы помочь их системам сделать вывод.
Чтобы проиллюстрировать простой подход, который приводит к разумным результатам, этот пример обучает CNN с помощью mel спектрограммы и классификатор ансамбля с помощью рассеивания вейвлета. CNN и классификатор ансамбля производят примерно эквивалентную общую точность, но выполняют лучше при различении различных акустических сцен. Чтобы увеличить общую точность, вы объединяете CNN и результаты классификатора ансамбля с помощью последнего сплава.
Чтобы запустить пример, необходимо сначала загрузить набор данных [1]. Полный набор данных составляет приблизительно 15,5 Гбайт. В зависимости от вашей машины и интернет-соединения, загружая данные может занять приблизительно 4 часа.
downloadFolder = tempdir; datasetFolder = fullfile(downloadFolder,'TUT-acoustic-scenes-2017'); if ~exist(datasetFolder,'dir') disp('Downloading TUT-acoustic-scenes-2017 (15.5 GB)...') HelperDownload_TUT_acoustic_scenes_2017(datasetFolder); end
Читайте в метаданных набора разработки как таблица. Назовите табличные переменные FileName
, AcousticScene
, и SpecificLocation
.
metadata_train = readtable(fullfile(datasetFolder,'TUT-acoustic-scenes-2017-development','meta.txt'), ... 'Delimiter',{'\t'}, ... 'ReadVariableNames',false); metadata_train.Properties.VariableNames = {'FileName','AcousticScene','SpecificLocation'}; head(metadata_train)
ans = 8×3 table FileName AcousticScene SpecificLocation __________________________ _____________ ________________ {'audio/b020_90_100.wav' } {'beach'} {'b020'} {'audio/b020_110_120.wav'} {'beach'} {'b020'} {'audio/b020_100_110.wav'} {'beach'} {'b020'} {'audio/b020_40_50.wav' } {'beach'} {'b020'} {'audio/b020_50_60.wav' } {'beach'} {'b020'} {'audio/b020_30_40.wav' } {'beach'} {'b020'} {'audio/b020_160_170.wav'} {'beach'} {'b020'} {'audio/b020_170_180.wav'} {'beach'} {'b020'}
metadata_test = readtable(fullfile(datasetFolder,'TUT-acoustic-scenes-2017-evaluation','meta.txt'), ... 'Delimiter',{'\t'}, ... 'ReadVariableNames',false); metadata_test.Properties.VariableNames = {'FileName','AcousticScene','SpecificLocation'}; head(metadata_test)
ans = 8×3 table FileName AcousticScene SpecificLocation __________________ _____________ ________________ {'audio/1245.wav'} {'beach'} {'b174'} {'audio/1456.wav'} {'beach'} {'b174'} {'audio/1318.wav'} {'beach'} {'b174'} {'audio/967.wav' } {'beach'} {'b174'} {'audio/203.wav' } {'beach'} {'b174'} {'audio/777.wav' } {'beach'} {'b174'} {'audio/231.wav' } {'beach'} {'b174'} {'audio/768.wav' } {'beach'} {'b174'}
Обратите внимание на то, что определенные места записи в наборе тестов не пересекаются с определенными местами записи в наборе разработки. Это облегчает подтверждать это, обученные модели могут сделать вывод к реальным сценариям.
sharedRecordingLocations = intersect(metadata_test.SpecificLocation,metadata_train.SpecificLocation);
fprintf('Number of specific recording locations in both train and test sets = %d\n',numel(sharedRecordingLocations))
Number of specific recording locations in both train and test sets = 0
Первая переменная таблиц метаданных содержит имена файлов. Конкатенация имен файлов с путями к файлам.
train_filePaths = fullfile(datasetFolder,'TUT-acoustic-scenes-2017-development',metadata_train.FileName); test_filePaths = fullfile(datasetFolder,'TUT-acoustic-scenes-2017-evaluation',metadata_test.FileName);
Создайте аудио хранилища данных для обучения и наборов тестов. Установите Labels
свойство audioDatastore
к акустической сцене. Вызовите countEachLabel
проверять ровное распределение меток и в обучении и в наборах тестов.
adsTrain = audioDatastore(train_filePaths, ... 'Labels',categorical(metadata_train.AcousticScene), ... 'IncludeSubfolders',true); display(countEachLabel(adsTrain)) adsTest = audioDatastore(test_filePaths, ... 'Labels',categorical(metadata_test.AcousticScene), ... 'IncludeSubfolders',true); display(countEachLabel(adsTest))
15×2 table Label Count ________________ _____ beach 312 bus 312 cafe/restaurant 312 car 312 city_center 312 forest_path 312 grocery_store 312 home 312 library 312 metro_station 312 office 312 park 312 residential_area 312 train 312 tram 312 15×2 table Label Count ________________ _____ beach 108 bus 108 cafe/restaurant 108 car 108 city_center 108 forest_path 108 grocery_store 108 home 108 library 108 metro_station 108 office 108 park 108 residential_area 108 train 108 tram 108
Можно уменьшать набор данных, используемый в этом примере, чтобы ускорить время выполнения за счет эффективности. В общем случае сокращение набора данных является хорошей практикой для разработки и отладки. Установите reduceDataset
к true
уменьшать набор данных.
reduceDataset = false; if reduceDataset adsTrain = splitEachLabel(adsTrain,20); adsTest = splitEachLabel(adsTest,10); end
Вызовите read
получить данные и частоту дискретизации файла от состава. Аудио в базе данных имеет сопоставимую частоту дискретизации и длительность. Нормируйте аудио и слушайте его. Отобразите соответствующую метку.
[data,adsInfo] = read(adsTrain); data = data./max(data,[],'all'); fs = adsInfo.SampleRate; sound(data,fs) fprintf('Acoustic scene = %s\n',adsTrain.Labels(1))
Acoustic scene = beach
Вызовите reset
возвратить datastore в его начальное условие.
reset(adsTrain)
Каждый аудиоклип в наборе данных состоит из 10 секунд (лево-правильного) аудио стерео. Конвейер извлечения признаков и архитектура CNN в этом примере основаны [3]. Гиперпараметры для извлечения признаков, архитектуры CNN и опций обучения были изменены из исходной бумаги с помощью систематического рабочего процесса оптимизации гиперпараметра.
Во-первых, преобразуйте аудио в середину кодирования стороны. [3] предполагает, что середина закодированных данных стороны предоставляет лучшую пространственную информацию, которую CNN может использовать, чтобы идентифицировать движущиеся источники (такие как обучение продвигающегося по акустической сцене).
dataMidSide = [sum(data,2),data(:,1)-data(:,2)];
Разделите сигнал на вторые сегменты с перекрытием. Итоговая система использует взвешенное среднее вероятности на вторых сегментах, чтобы предсказать сцену для каждых 10 вторых аудиоклипов в наборе тестов. Деление аудиоклипов во вторые сегменты делает сеть легче обучаться и помогает предотвратить сверхподбор кривой к определенным акустическим событиям в наборе обучающих данных. Перекрытие помогает гарантировать, что все комбинации функций друг относительно друга получены обучающими данными. Это также предоставляет системе дополнительные данные, которые могут быть смешаны исключительно во время увеличения.
segmentLength = 1; segmentOverlap = 0.5; [dataBufferedMid,~] = buffer(dataMidSide(:,1),round(segmentLength*fs),round(segmentOverlap*fs),'nodelay'); [dataBufferedSide,~] = buffer(dataMidSide(:,2),round(segmentLength*fs),round(segmentOverlap*fs),'nodelay'); dataBuffered = zeros(size(dataBufferedMid,1),size(dataBufferedMid,2)+size(dataBufferedSide,2)); dataBuffered(:,1:2:end) = dataBufferedMid; dataBuffered(:,2:2:end) = dataBufferedSide;
Используйте melSpectrogram
преобразовать данные в компактное представление частотного диапазона. Задайте параметры для mel спектрограммы, как предложено [3].
windowLength = 2048; samplesPerHop = 1024; samplesOverlap = windowLength - samplesPerHop; fftLength = 2*windowLength; numBands = 128;
melSpectrogram
действует вдоль каналов независимо. Чтобы оптимизировать время вычислений, вызовите melSpectrogram
с целым буферизированным сигналом.
spec = melSpectrogram(dataBuffered,fs, ... 'Window',hamming(windowLength,'periodic'), ... 'OverlapLength',samplesOverlap, ... 'FFTLength',fftLength, ... 'NumBands',numBands);
Преобразуйте mel спектрограмму в логарифмический масштаб.
spec = log10(spec+eps);
Измените размерность массива к размерностям (Количество полос) (Количество транзитных участков) (Количество каналов) (Количество сегментов). Когда вы подаете изображение в нейронную сеть, первые две размерности являются высотой и шириной изображения, третья размерность является каналами, и четвертая размерность разделяет отдельные изображения.
X = reshape(spec,size(spec,1),size(spec,2),size(data,2),[]);
Вызовите melSpectrogram
без выходных аргументов, чтобы построить mel спектрограмму середины канала для первых шести из одного второго шага.
for channel = 1:2:11 figure melSpectrogram(dataBuffered(:,channel),fs, ... 'Window',hamming(windowLength,'periodic'), ... 'OverlapLength',samplesOverlap, ... 'FFTLength',fftLength, ... 'NumBands',numBands); title(sprintf('Segment %d',ceil(channel/2))) end
Функция помощника HelperSegmentedMelSpectrograms
выполняет шаги извлечения признаков, обрисованные в общих чертах выше.
Чтобы ускорить обработку, извлеките mel спектрограммы всех звуковых файлов в хранилищах данных с помощью tall
массивы. В отличие от массивов в оперативной памяти, длинные массивы остаются неоцененными, пока вы не запрашиваете, чтобы вычисления были выполнены с помощью gather
функция. Эта отсроченная оценка позволяет вам работать быстро с большими наборами данных. Когда вы в конечном счете запрашиваете выход с помощью gather
, MATLAB комбинирует вычисления в очереди, где возможный и берет минимальное количество проходов через данные. Если у вас есть Parallel Computing Toolbox™, можно использовать длинные массивы в локальном сеансе работы с MATLAB, или на локальном параллельном пуле. Можно также выполнить вычисления длинного массива на кластере, если вам установили MATLAB® Parallel Server™.
Если у вас нет Parallel Computing Toolbox™, код в этом примере все еще запускается.
pp = parpool('IdleTimeout',inf); train_set_tall = tall(adsTrain); xTrain = cellfun(@(x)HelperSegmentedMelSpectrograms(x,fs, ... 'SegmentLength',segmentLength, ... 'SegmentOverlap',segmentOverlap, ... 'WindowLength',windowLength, ... 'HopLength',samplesPerHop, ... 'NumBands',numBands, ... 'FFTLength',fftLength), ... train_set_tall, ... 'UniformOutput',false); xTrain = gather(xTrain); xTrain = cat(4,xTrain{:}); test_set_tall = tall(adsTest); xTest = cellfun(@(x)HelperSegmentedMelSpectrograms(x,fs, ... 'SegmentLength',segmentLength, ... 'SegmentOverlap',segmentOverlap, ... 'WindowLength',windowLength, ... 'HopLength',samplesPerHop, ... 'NumBands',numBands, ... 'FFTLength',fftLength), ... test_set_tall, ... 'UniformOutput',false); xTest = gather(xTest); xTest = cat(4,xTest{:});
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6). Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 4 min 48 sec Evaluation completed in 4 min 48 sec Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 1 min 40 sec Evaluation completed in 1 min 40 sec
Реплицируйте метки набора обучающих данных так, чтобы они были во взаимно-однозначном соответствии с сегментами.
numSegmentsPer10seconds = size(dataBuffered,2)/2; yTrain = repmat(adsTrain.Labels,1,numSegmentsPer10seconds)'; yTrain = yTrain(:);
Набор данных DCASE 2017 содержит относительно небольшое количество акустических записей для задачи, и набор разработки и набор оценки были зарегистрированы в различных определенных местоположениях. В результате легко сверхсоответствовать к данным во время обучения. Один популярный метод, чтобы уменьшать сверхподбор кривой является путаницей. В путанице вы увеличиваете свой набор данных путем смешивания функций двух различных классов. Когда вы смешиваете функции, вы смешиваете метки в равной пропорции. Это:
Путаница была переформулирована [2] как метки, чертившие от вероятностного распределения вместо смешанных меток. Реализация путаницы в этом примере является упрощенной версией путаницы: каждая спектрограмма смешана со спектрограммой различной метки с набором lambda к 0,5. Исходные и смешанные наборы данных объединены для обучения.
xTrainExtra = xTrain; yTrainExtra = yTrain; lambda = 0.5; for i = 1:size(xTrain,4) % Find all available spectrograms with different labels. availableSpectrograms = find(yTrain~=yTrain(i)); % Randomly choose one of the available spectrograms with a different label. numAvailableSpectrograms = numel(availableSpectrograms); idx = randi([1,numAvailableSpectrograms]); % Mix. xTrainExtra(:,:,:,i) = lambda*xTrain(:,:,:,i) + (1-lambda)*xTrain(:,:,:,availableSpectrograms(idx)); % Specify the label as randomly set by lambda. if rand > lambda yTrainExtra(i) = yTrain(availableSpectrograms(idx)); end end xTrain = cat(4,xTrain,xTrainExtra); yTrain = [yTrain;yTrainExtra];
Вызовите summary
отобразить распределение меток для увеличенного набора обучающих данных.
summary(yTrain)
beach 11769 bus 11904 cafe/restaurant 11873 car 11820 city_center 11886 forest_path 11936 grocery_store 11914 home 11923 library 11817 metro_station 11804 office 11922 park 11871 residential_area 11704 train 11773 tram 11924
Задайте архитектуру CNN. Эта архитектура основана [1] и изменена методом проб и ошибок. Смотрите Список слоев глубокого обучения (Deep Learning Toolbox), чтобы узнать больше о слоях глубокого обучения, доступных в MATLAB®.
imgSize = [size(xTrain,1),size(xTrain,2),size(xTrain,3)]; numF = 32; layers = [ ... imageInputLayer(imgSize) batchNormalizationLayer convolution2dLayer(3,numF,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(3,numF,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer(3,'Stride',2,'Padding','same') convolution2dLayer(3,2*numF,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(3,2*numF,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer(3,'Stride',2,'Padding','same') convolution2dLayer(3,4*numF,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(3,4*numF,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer(3,'Stride',2,'Padding','same') convolution2dLayer(3,8*numF,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(3,8*numF,'Padding','same') batchNormalizationLayer reluLayer averagePooling2dLayer(ceil(imgSize(1:2)/8)) dropoutLayer(0.5) fullyConnectedLayer(15) softmaxLayer classificationLayer];
Задайте trainingOptions
(Deep Learning Toolbox) для CNN. Эти опции основаны [3] и изменены через систематический рабочий процесс гипероптимизации параметров управления.
miniBatchSize = 128; tuneme = 128; lr = 0.05*miniBatchSize/tuneme; options = trainingOptions('sgdm', ... 'InitialLearnRate',lr, ... 'MiniBatchSize',miniBatchSize, ... 'Momentum',0.9, ... 'L2Regularization',0.005, ... 'MaxEpochs',8, ... 'Shuffle','every-epoch', ... 'Plots','training-progress', ... 'Verbose',false, ... 'LearnRateSchedule','piecewise', ... 'LearnRateDropPeriod',2, ... 'LearnRateDropFactor',0.2);
Вызовите trainNetwork
(Deep Learning Toolbox), чтобы обучить сеть.
trainedNet = trainNetwork(xTrain,yTrain,layers,options);
Вызовите predict
(Deep Learning Toolbox), чтобы предсказать ответы от обучившего сеть использования протянутого набора тестов.
cnnResponsesPerSegment = predict(trainedNet,xTest);
Насчитайте ответы по каждым 10 вторым аудиоклипам.
classes = trainedNet.Layers(end).Classes; numFiles = numel(adsTest.Files); counter = 1; cnnResponses = zeros(numFiles,numel(classes)); for channel = 1:numFiles cnnResponses(channel,:) = sum(cnnResponsesPerSegment(counter:counter+numSegmentsPer10seconds-1,:),1)/numSegmentsPer10seconds; counter = counter + numSegmentsPer10seconds; end
Для каждых 10 вторых аудиоклипов выберите максимум предсказаний, затем сопоставьте его с соответствующим предсказанным местоположением.
[~,classIdx] = max(cnnResponses,[],2); cnnPredictedLabels = classes(classIdx);
Вызовите confusionchart
(Deep Learning Toolbox), чтобы визуализировать точность на наборе тестов. Возвратите среднюю точность в Командное окно.
figure cm = confusionchart(adsTest.Labels,cnnPredictedLabels,'title','Test Accuracy - CNN'); cm.ColumnSummary = 'column-normalized'; cm.RowSummary = 'row-normalized'; fprintf('Average accuracy of CNN = %0.2f\n',mean(adsTest.Labels==cnnPredictedLabels)*100)
Average accuracy of CNN = 75.12
Рассеивание вейвлета, как показывали, в [4] обеспечило хорошее представление акустических сцен. Задайте waveletScattering
Объект (Wavelet Toolbox). Масштабные коэффициенты инвариантности и добротности были определены методом проб и ошибок.
sf = waveletScattering('SignalLength',size(data,1), ... 'SamplingFrequency',fs, ... 'InvarianceScale',0.75, ... 'QualityFactors',[4 1]);
Преобразуйте звуковой сигнал в моно, и затем вызовите featureMatrix
(Wavelet Toolbox), чтобы возвратить рассеивающиеся коэффициенты для рассеивающейся среды разложения, sf
.
dataMono = mean(data,2); scatteringCoeffients = featureMatrix(sf,dataMono,'Transform','log');
Насчитайте рассеивающиеся коэффициенты по 10 вторым аудиоклипам.
featureVector = mean(scatteringCoeffients,2);
fprintf('Number of wavelet features per 10-second clip = %d\n',numel(featureVector))
Number of wavelet features per 10-second clip = 290
Функция помощника HelperWaveletFeatureVector
выполняет перечисленные выше шаги. Используйте tall
массив с cellfun
и HelperWaveletFeatureVector
параллелизировать извлечение признаков. Извлеките характеристические векторы вейвлета для обучения и наборов тестов.
scatteringTrain = cellfun(@(x)HelperWaveletFeatureVector(x,sf),train_set_tall,'UniformOutput',false); xTrain = gather(scatteringTrain); xTrain = cell2mat(xTrain')'; scatteringTest = cellfun(@(x)HelperWaveletFeatureVector(x,sf),test_set_tall,'UniformOutput',false); xTest = gather(scatteringTest); xTest = cell2mat(xTest')';
Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 30 min 22 sec Evaluation completed in 30 min 22 sec Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 10 min 30 sec Evaluation completed in 10 min 30 sec
Используйте fitcensemble
создать обученную модель ансамбля классификации (ClassificationEnsemble
).
subspaceDimension = min(150,size(xTrain,2) - 1); numLearningCycles = 30; classificationEnsemble = fitcensemble(xTrain,adsTrain.Labels, ... 'Method','Subspace', ... 'NumLearningCycles',numLearningCycles, ... 'Learners','discriminant', ... 'NPredToSample',subspaceDimension, ... 'ClassNames',removecats(unique(adsTrain.Labels)));
Для каждых 10 вторых аудиоклипов вызовите predict
чтобы возвратить метки и веса, затем сопоставьте его с соответствующим предсказанным местоположением. Вызовите confusionchart
(Deep Learning Toolbox), чтобы визуализировать точность на наборе тестов. Распечатайте среднее значение.
[waveletPredictedLabels,waveletResponses] = predict(classificationEnsemble,xTest); figure cm = confusionchart(adsTest.Labels,waveletPredictedLabels,'title','Test Accuracy - Wavelet Scattering'); cm.ColumnSummary = 'column-normalized'; cm.RowSummary = 'row-normalized'; fprintf('Average accuracy of classifier = %0.2f\n',mean(adsTest.Labels==waveletPredictedLabels)*100)
Average accuracy of classifier = 76.23
Для каждых 10 вторых клипов вызов предсказывает на классификаторе вейвлета, и CNN возвращает вектор, указывающий на относительное доверие к их решению. Умножьте waveletResponses
с cnnResponses
создать последнюю систему сплава.
fused = waveletResponses .* cnnResponses; [~,classIdx] = max(fused,[],2); predictedLabels = classes(classIdx);
Вызовите confusionchart
визуализировать сплавленную точность классификации. Распечатайте среднюю точность к Командному окну.
figure cm = confusionchart(adsTest.Labels,predictedLabels,'title','Test Accuracy - Fusion'); cm.ColumnSummary = 'column-normalized'; cm.RowSummary = 'row-normalized'; fprintf('Average accuracy of fused models = %0.2f\n',mean(adsTest.Labels==predictedLabels)*100)
Average accuracy of fused models = 79.57
Закройте параллельный пул.
delete(pp)
Parallel pool using the 'local' profile is shutting down.
[1] А. Мезэрос, Т. Хейттола и Т. Виртэнен. Акустическая Классификация Сцен: Обзор записей DCASE 2017 проблемы. В материалах Международный семинар на Акустическом Улучшении Сигнала, 2018.
[2] Huszar, Ференц. "Путаница: информационно-зависимое Увеличение Данных". InFERENCe. 03 ноября 2017. Полученный доступ 15 января 2019. https://www.inference.vc/mixup-data-dependent-data-augmentation/.
[3] Ханьцы, Yoonchang, парк Jeongsoo и Киогу Ли. "Сверточные нейронные сети с бинауральными представлениями и фоновым вычитанием для акустической классификации сцен". Обнаружение и Классификация Акустических Сцен и Событий (DCASE) (2017): 1-5.
[4] Lostanlen, Винсент и Джоуким Анден. Бинауральная классификация сцен с рассеиванием вейвлета. Технический отчет, проблема DCASE2016, 2016.
[5] А. Дж. Эронен, В. Т. Пелтонен, Дж. Т. Туоми, А. П. Клапури, С. Фэджерланд, Т. Сорса, Г. Лорхо и Дж. Хуопэними, "Основанное на аудио распознавание контекста", Сделка IEEE на Аудио, Речи, и Обработке Языка, vol 14, № 1, стр 321-329, январь 2006.
[6] TUT Акустические сцены 2017, набор данных Development
[7] TUT Акустические сцены 2017, набор данных Evaluation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %HelperSegmentedMelSpectrograms function X = HelperSegmentedMelSpectrograms(x,fs,varargin) p = inputParser; addParameter(p,'WindowLength',1024); addParameter(p,'HopLength',512); addParameter(p,'NumBands',128); addParameter(p,'SegmentLength',1); addParameter(p,'SegmentOverlap',0); addParameter(p,'FFTLength',1024); parse(p,varargin{:}) params = p.Results; x = [sum(x,2),x(:,1)-x(:,2)]; x = x./max(max(x)); [xb_m,~] = buffer(x(:,1),round(params.SegmentLength*fs),round(params.SegmentOverlap*fs),'nodelay'); [xb_s,~] = buffer(x(:,2),round(params.SegmentLength*fs),round(params.SegmentOverlap*fs),'nodelay'); xb = zeros(size(xb_m,1),size(xb_m,2)+size(xb_s,2)); xb(:,1:2:end) = xb_m; xb(:,2:2:end) = xb_s; spec = melSpectrogram(xb,fs, ... 'Window',hamming(params.WindowLength,'periodic'), ... 'OverlapLength',params.WindowLength - params.HopLength, ... 'FFTLength',params.FFTLength, ... 'NumBands',params.NumBands, ... 'FrequencyRange',[0,floor(fs/2)]); spec = log10(spec+eps); X = reshape(spec,size(spec,1),size(spec,2),size(x,2),[]); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %HelperWaveletFeatureVector function features = HelperWaveletFeatureVector(x,sf) x = mean(x,2); features = featureMatrix(sf,x,'Transform','log'); features = mean(features,2); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%