В этом примере показано, как создать многомодельную систему позднего слияния для распознавания акустических сцен. Пример обучает сверточную нейронную сеть (CNN) с использованием спектрограмм mel и ансамблевого классификатора с использованием вейвлет-рассеяния. В примере используется набор данных TUT для обучения и оценки [1].
Классификация акустических сцен (ASC) - задача классификации сред по производимым ими звукам. ASC - это общая проблема классификации, которая является основой для понимания контекста в устройствах, роботах и многих других приложениях [1]. В ранних попытках ASC использовались кепстральные коэффициенты мел-частоты (mfcc (Audio Toolbox)) и гауссовы модели смесей (GMM) для описания их статистического распределения. Другие популярные особенности, используемые для ASC, включают нулевую скорость пересечения, спектральный центроид (spectralCentroid (Audio Toolbox)), спектральный откат (spectralRolloffPoint (Audio Toolbox)), спектральный поток (spectralFlux (Audio Toolbox)) и коэффициенты линейного прогнозирования (lpc(Панель инструментов обработки сигналов)) [5]. Скрытые модели Маркова (HMM) были обучены описывать временную эволюцию GMM. В последнее время в наиболее эффективных системах используется глубокое обучение, обычно CNN, и слияние нескольких моделей. Самой популярной функцией для топовых систем в конкурсе DCASE 2017 стала спектрограмма mel (melSpectrogram (Панель звуковых инструментов)). Топовые системы в проблеме использовали поздний синтез и увеличение данных, чтобы помочь их системам обобщить.
Чтобы проиллюстрировать простой подход, который дает разумные результаты, этот пример обучает CNN с использованием спектрограмм и ансамблевого классификатора с использованием вейвлет-рассеяния. Классификатор CNN и ансамбля производит примерно эквивалентную общую точность, но лучше работает при различении различных акустических сцен. Для повышения общей точности необходимо объединить результаты классификации CNN и ensemble с помощью позднего слияния.
Для выполнения примера необходимо сначала загрузить набор данных [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 (Audio Toolbox) к акустической сцене. Звонить countEachLabel (Audio Toolbox) для проверки равномерного распределения меток как в поезде, так и в тестовых наборах.
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 (Audio Toolbox), чтобы получить данные и частоту дискретизации файла из набора поездов. Звук в базе данных имеет согласованную частоту дискретизации и длительность. Нормализуйте звук и слушайте его. Отображение соответствующей метки.
[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 (Audio Toolbox), чтобы вернуть хранилище данных в исходное состояние.
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 (Audio Toolbox) для преобразования данных в компактное представление в частотной области. Определите параметры спектрограммы в соответствии с [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);
Преобразование спектрограммы в логарифмическую шкалу.
spec = log10(spec+eps);
Измените форму массива на размеры (Число полос) -by- (Количество транзитных участков) -by- (Количество каналов) -by- (Количество сегментов). При подаче изображения в нейронную сеть первые два измерения - высота и ширина изображения, третье измерение - каналы, а четвертое измерение разделяет отдельные изображения.
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 выполняет описанные выше шаги извлечения признаков.
Для ускорения обработки извлеките спектрограммы всех аудиофайлов в хранилищах данных с помощью tall массивы. В отличие от массивов в памяти, массивы tall остаются невысокими до тех пор, пока вы не запросите выполнение вычислений с помощью gather функция. Этот отложенный анализ позволяет быстро работать с большими наборами данных. При конечном запросе выходных данных с помощью gatherMATLAB объединяет вычисления в очереди, где это возможно, и принимает минимальное количество проходов через данные. При наличии Toolbox™ параллельных вычислений можно использовать массивы tall в локальной сессии MATLAB или в локальном пуле параллельных вычислений. Можно также выполнить вычисления массива высокого уровня в кластере, если установлен MATLAB ® Parallel Server™.
Если у вас нет 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 3 min 45 sec Evaluation completed in 3 min 45 sec Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 1 min 22 sec Evaluation completed in 1 min 22 sec
Реплицируйте метки обучающего набора таким образом, чтобы они соответствовали сегментам один к одному.
numSegmentsPer10seconds = size(dataBuffered,2)/2; yTrain = repmat(adsTrain.Labels,1,numSegmentsPer10seconds)'; yTrain = yTrain(:);
Набор данных DCASE 2017 содержит относительно небольшое количество акустических записей для задачи, а набор разработок и набор оценок были записаны в разных конкретных местах. В результате во время тренировок легко поддаваться данным. Одним из популярных способов уменьшения переоборудования является смешение. В mixup вы дополняете свой набор данных, смешивая особенности двух разных классов. При смешивании элементов метки смешиваются в равной пропорции. То есть:

Смешение было переформулировано [2] как метки, взятые из распределения вероятностей вместо смешанных меток. Реализация миксапа в данном примере является упрощённым вариантом миксапа: каждая спектрограмма смешивается со спектрограммой разной метки с лямбдой, установленной на 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 11749
bus 11870
cafe/restaurant 11860
car 11873
city_center 11789
forest_path 12023
grocery_store 11850
home 11877
library 11756
metro_station 11912
office 11940
park 11895
residential_area 11875
train 11795
tram 11776
Определите архитектуру CNN. Эта архитектура основана на [1] и модифицирована методом проб и ошибок. Дополнительные сведения о слоях глубокого обучения, доступных в 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 globalAveragePooling2dLayer dropoutLayer(0.5) fullyConnectedLayer(15) softmaxLayer classificationLayer];
Определить trainingOptions для 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 для обучения сети.
trainedNet = trainNetwork(xTrain,yTrain,layers,options);

Звонить predict прогнозировать ответы от обученной сети с использованием задержанного тестового набора.
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 для визуализации точности на тестовом наборе. Возврат средней точности в окно команд.
figure('Units','normalized','Position',[0.2 0.2 0.5 0.5]) 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 = 73.33

Вейвлет-рассеяние показано в [4] для обеспечения хорошего представления акустических сцен. Определение waveletScattering (Wavelet Toolbox) объект. Шкала инвариантности и коэффициенты качества определялись методом проб и ошибок.
sf = waveletScattering('SignalLength',size(data,1), ... 'SamplingFrequency',fs, ... 'InvarianceScale',0.75, ... 'QualityFactors',[4 1]);
Преобразуйте звуковой сигнал в моно, а затем вызовите featureMatrix (Vavelet 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 25 min 15 sec Evaluation completed in 25 min 15 sec Evaluating tall expression using the Parallel Pool 'local': - Pass 1 of 1: Completed in 8 min 2 sec Evaluation completed in 8 min 2 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 для визуализации точности на тестовом наборе. Распечатайте среднее значение.
[waveletPredictedLabels,waveletResponses] = predict(classificationEnsemble,xTest); figure('Units','normalized','Position',[0.2 0.2 0.5 0.5]) 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.05

Для каждого 10-секундного клипа вызов предсказания по вейвлет-классификатору и CNN возвращает вектор, указывающий относительную уверенность в их решении. Умножьте значение waveletResponses с cnnResponses для создания системы позднего слияния.
fused = waveletResponses .* cnnResponses; [~,classIdx] = max(fused,[],2); predictedLabels = classes(classIdx);
Звонить confusionchart для визуализации точности конденсированной классификации. Печать средней точности в окне команд.
figure('Units','normalized','Position',[0.2 0.2 0.5 0.5]) 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 = 78.21

Закройте параллельный пул.
delete(pp)
Parallel pool using the 'local' profile is shutting down.
[1] А. Месарош, Т. Хейттола и Т. Виртанен. Классификация акустических сцен: обзор записей вызова DCASE 2017. В proc. Международный семинар по усилению акустического сигнала, 2018 год.
[2] Гусар, Ференц. «Микширование: увеличение данных, зависящее от данных». InFERENCe. 03 ноября 2017 года. Доступ состоялся 15 января 2019 года. https://www.inference.vc/mixup-data-dependent-data-augmentation/.
[3] Хан, Йончан, Чонсу Парк и Кёгу Ли. «Сверточные нейронные сети с бинауральными представлениями и фоновым вычитанием для классификации акустических сцен». Обнаружение и классификация акустических сцен и событий (DCASE) (2017): 1-5.
[4] Лоштанлен, Винсент и Йоаким Анден. Бинауральная классификация сцены с вейвлет-рассеянием. Технический отчет, DCASE2016 Challenge, 2016.
[5] А. Ж. Эронен, В. Т. Пелтонен, Ж. Т. Туоми, А. П. Клапури, С. Фагерлунд, Т. Сорса, Г. Лорхо и Ж. Хуопаниеми, «Распознавание контекста на основе аудио», IEEE Trans. по аудио, речи и языку
[6] Акустические сцены TUT 2017, набор данных разработки
[7] Акустические сцены TUT 2017, оценочный набор данных
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
batchNormalizationLayer | classify | convolution2dLayer | layerGraph | trainingOptions | trainNetwork