В этом примере вы обучаете три сверточных нейронных сети (CNNs) выполнять верификацию динамика и затем сравнивать эффективность архитектур. Архитектуры трех CNNs являются всем эквивалентом за исключением первого сверточного слоя в каждом:
В первой архитектуре первый сверточный слой является "стандартным" сверточным слоем, реализованное использование convolution2dLayer.
Во второй архитектуре первый сверточный слой является постоянным sinc filterbank, реализованное использование пользовательского слоя.
В третьей архитектуре первый сверточный слой является обучаемым sinc filterbank, реализованное использование пользовательского слоя. Эта архитектура упоминается как SincNet [1].
[1] показывает, что заменяющий стандартный сверточный слой на filterbank слой приводит к более быстрой учебной сходимости и более высокой точности. [1] также показывает что, делая параметры набора фильтров learnable выражениями дополнительное увеличение производительности.
Идентификация динамика является видной областью исследования со множеством приложений включая судебную экспертизу и биометрическую аутентификацию. Много идентификационных систем динамика зависят от предварительно вычисленных функций, таких как i-векторы или MFCCs, которые затем поданы в машинное обучение или нейронные сети для глубокого обучения для классификации. Другие речевые системы глубокого обучения обходят этап извлечения признаков и кормят звуковым сигналом непосредственно сеть. В таких комплексных системах сеть непосредственно изучает низкоуровневые характеристики звукового сигнала.
В этом примере вы сначала обучаете традиционный сквозной идентификационный CNN динамика. Изученные фильтры имеют тенденцию иметь случайные формы, которые не соответствуют перцепционному доказательству или знанию того, как человеческое ухо работает, особенно в сценариях, где сумма обучающих данных ограничивается [1]. Вы затем заменяете первый сверточный слой в сети с пользовательским sinc filterbank слой, который вводит структуру и ограничения на основе перцепционного доказательства. Наконец, вы обучаете архитектуру SincNet, которая добавляет обучаемость в sinc filterbank параметры.
Три архитектуры нейронной сети, исследуемые в примере, получены в итоге можно следующим образом:
Стандартная Сверточная нейронная сеть - входная форма волны непосредственно соединяется со случайным образом инициализированным сверточным слоем, который пытается изучить функции и характеристики получения от необработанных аудио систем координат.
ConstantSincLayer - К входной форме волны применяют операцию свертки с набором фиксированной ширины sinc функции (полосовые фильтры), равномерно распределенные по шкале mel.
SincNetLayer - К входной форме волны применяют операцию свертки с набором функций sinc, параметры которых изучены сетью. В архитектуре SincNet сеть настраивает параметры функций sinc в то время как обучение.
Этот пример задает и обучает эти три нейронных сети, предложенные выше, и оценивает их эффективность на Наборе данных LibriSpeech [2].
В этом примере вы используете подмножество Набора данных LibriSpeech [2]. Набор данных LibriSpeech является большим корпусом английской речи чтения, произведенной на уровне 16 кГц. Данные выведены из аудиокниг, считанных из проекта LibriVox.
downloadDatasetFolder = tempdir; filename = "train-clean-100.tar.gz"; url = "http://www.openSLR.org/resources/12/" + filename; datasetFolder = fullfile(downloadDatasetFolder,"LibriSpeech","train-clean-100"); if ~isfolder(datasetFolder) gunzip(url,downloadDatasetFolder); unzippedFile = fullfile(downloadDatasetFolder,filename); untar(unzippedFile{1}(1:end-3),downloadDatasetFolder); end
Создайте audioDatastore возразите, чтобы получить доступ к аудиоданным LibriSpeech.
ADS = audioDatastore(datasetFolder,'IncludeSubfolders',1);Извлеките марку докладчика из пути к файлу.
ADS.Labels = extractBetween(ADS.Files,fullfile(datasetFolder,filesep),filesep);
Полный dev-train-100 набор данных составляет приблизительно 6 Гбайт данных. Чтобы обучить сеть с данными от всего 251 докладчика, установите reduceDataset к false. Чтобы запустить этот пример быстро с данными всего от шести докладчиков, установите reduceDataset к true.
reducedDataSet =false; if reducedDataSet индексы = cellfun ((c) str2double (c) <50, ADS.Labels); %#ok ADS = подмножество (ADS, индексы); end ADS = splitEachLabel (ADS, 0.1);
Разделите звуковые файлы в обучение и тестовые данные. 80% звуковых файлов присвоены набору обучающих данных, и 20% присвоены набору тестов.
[ADSTrain,ADSTest] = splitEachLabel(ADS,0.8);
Постройте один из звуковых файлов и слушайте его.
[audioIn,dsInfo] = read(ADSTrain); Fs = dsInfo.SampleRate; sound(audioIn,Fs) t = (1/Fs)*(0:length(audioIn)-1); plot(t,audioIn) title("Audio Sample") xlabel("Time (s)") ylabel("Amplitude") grid on

Сбросьте учебный datastore.
reset(ADSTrain)
CNNs ожидают, что входные параметры будут иметь сопоставимые размерности. Вы предварительно обработаете аудио путем удаления областей тишины и затем повредите остающуюся речь в системы координат на 200 мс с перекрытием на 40 мс.
Установите параметры для предварительной обработки.
frameDuration = 200e-3; overlapDuration = 40e-3; frameLength = floor(Fs*frameDuration); overlapLength = round(Fs*overlapDuration);
Используйте функцию поддержки, preprocessAudioData, чтобы предварительно обработать обучение и тестовые данные. XTrain и XTest содержите обучение и протестируйте речевые системы координат, соответственно. YTrain и YTest содержите обучение и протестируйте метки, соответственно.
[XTrain,YTrain] = preprocessAudioData(ADSTrain,frameLength,overlapLength,Fs);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
[XTest,YTest] = preprocessAudioData(ADSTest,frameLength,overlapLength,Fs);
Стандартный CNN вдохновлен архитектурой нейронной сети в [1].
numFilters = 80;
filterLength = 251;
numSpeakers = numel(unique(ADS.Labels));
layers = [
imageInputLayer([1 frameLength 1])
% First convolutional layer
convolution2dLayer([1 filterLength],numFilters)
batchNormalizationLayer
leakyReluLayer(0.2)
maxPooling2dLayer([1 3])
% This layer is followed by 2 convolutional layers
convolution2dLayer([1 5],60)
batchNormalizationLayer
leakyReluLayer(0.2)
maxPooling2dLayer([1 3])
convolution2dLayer([1 5],60)
batchNormalizationLayer
leakyReluLayer(0.2)
maxPooling2dLayer([1 3])
% This is followed by 3 fully-connected layers
fullyConnectedLayer(256)
batchNormalizationLayer
leakyReluLayer(0.2)
fullyConnectedLayer(256)
batchNormalizationLayer
leakyReluLayer(0.2)
fullyConnectedLayer(256)
batchNormalizationLayer
leakyReluLayer(0.2)
fullyConnectedLayer(numSpeakers)
softmaxLayer
classificationLayer];Анализируйте слои нейронной сети с помощью analyzeNetwork функция
analyzeNetwork(layers)
Обучите нейронную сеть в течение 15 эпох с помощью adam оптимизация. Переставьте обучающие данные перед каждой эпохой. Опции обучения для нейронной сети установлены с помощью trainingOptions. Используйте тестовые данные в качестве данных о валидации, чтобы наблюдать, как производительность сети улучшается, в то время как обучение прогрессирует.
numEpochs = 15; miniBatchSize = 128; validationFrequency = floor(numel(YTrain)/miniBatchSize); options = trainingOptions("adam", ... "Shuffle","every-epoch", ... "MiniBatchSize",miniBatchSize, ... "Plots","training-progress", ... "Verbose",false,"MaxEpochs",numEpochs, ... "ValidationData",{XTest,categorical(YTest)}, ... "ValidationFrequency",validationFrequency);
Чтобы обучить сеть, вызовите trainNetwork.
[convNet,convNetInfo] = trainNetwork(XTrain,YTrain,layers,options);

Постройте частотную характеристику величины девяти фильтров, усвоенных из стандартной сети CNN. Форма этих фильтров не интуитивна и не соответствует перцепционному знанию. Следующий раздел исследует эффект использования ограниченных форм фильтра.
F = squeeze(convNet.Layers(2,1).Weights); H = zeros(size(F)); Freq = zeros(size(F)); for ii = 1:size(F,2) [h,f] = freqz(F(:,ii),1,251,Fs); H(:,ii) = abs(h); Freq(:,ii) = f; end idx = linspace(1,size(F,2),9); idx = round(idx); figure for jj = 1:9 subplot(3,3,jj) plot(Freq(:,idx(jj)),H(:,idx(jj))) sgtitle("Frequency Response of Learned Standard CNN Filters") xlabel("Frequency (Hz)") end

В этом разделе вы заменяете первый сверточный слой в стандартном CNN с постоянным sinc filterbank слой. Постоянный sinc filterbank слой применяет операцию свертки к входным кадрам с банком фиксированных полосовых фильтров. Полосовые фильтры являются линейной комбинацией двух sinc, просачивается временной интервал. Частоты полосовых фильтров расположены с интервалами линейно по шкале mel.
Реализация для постоянного sinc filterbank слой может быть найдена в constantSincLayer.m файл (присоединенный к этому примеру). Задайте параметры для ConstantSincLayer. Используйте 80 фильтров и длину фильтра 251.
numFilters = 80;
filterLength = 251;
numChannels = 1;
name = 'constant_sinc';Измените первый сверточный слой от стандартного CNN до ConstantSincLayer и сохраните другие слои неизменными.
cSL = constantSincLayer(numFilters,filterLength,Fs,numChannels,name)
cSL =
constantSincLayer with properties:
Name: 'constant_sinc'
NumFilters: 80
SampleRate: 16000
FilterLength: 251
NumChannels: []
Filters: [1×251×1×80 single]
MinimumFrequency: 50
MinimumBandwidth: 50
StartFrequencies: [1×80 double]
Bandwidths: [1×80 double]
Show all properties
layers(2) = cSL;
Обучите сеть с помощью trainNetwork функция. Используйте те же опции обучения, заданные ранее.
[constSincNet,constSincInfo] = trainNetwork(XTrain,YTrain,layers,options);

plotNFilters метод строит частотную характеристику величины n фильтры с равномерно распределенными индексами фильтра. Постройте частотную характеристику величины девять, просачивается ConstantSincLayer.
figure n = 9; plotNFilters(constSincNet.Layers(2),n)

В этом разделе вы используете обучаемый слой SincNet в качестве первого сверточного слоя в вашей сети. Слой SincNet применяет операцию свертки к входным кадрам с банком полосовых фильтров. Полоса пропускания и начальные частоты фильтров SincNet инициализируются как равномерно распределенные в шкале mel. Слой SincNet пытается изучить лучшие параметры для этих полосовых фильтров в среде нейронной сети.
Реализация для слоя SincNet filterbank слой может быть найдена в sincNetLayer.m файл (присоединенный к этому примеру). Задайте параметры для SincNetLayer. Используйте 80 фильтров и длину фильтра 251.
numFilters = 80;
filterLength = 251;
numChannels = 1;
name = 'sinc';Замените ConstantSincLayer от предыдущей сети с SincNetLayer. Этот новый слой имеет два настраиваемых параметра: FilterFrequencies и FilterBandwidths.
sNL = sincNetLayer(numFilters,filterLength,Fs,numChannels,name)
sNL =
sincNetLayer with properties:
Name: 'sinc'
NumFilters: 80
SampleRate: 16000
FilterLength: 251
NumChannels: []
Window: [1×251 double]
TimeStamps: [1×251 double]
MinimumFrequency: 50
MinimumBandwidth: 50
Learnable Parameters
FilterFrequencies: [1×80 double]
FilterBandwidths: [1×80 double]
Show all properties
layers(2) = sNL;
Обучите сеть с помощью trainNetwork функция. Используйте те же опции обучения, заданные ранее.
[sincNet,sincNetInfo] = trainNetwork(XTrain,YTrain,layers,options);

Используйте plotNFilters метод SincNetLayer визуализировать частотную характеристику величины девяти фильтров с равномерно распределенными индексами, изученными SincNet.
figure plotNFilters(sincNet.Layers(2),9)

Таблица суммирует точность системы координат для всех трех нейронных сетей.
NetworkType = {'Standard CNN','Constant Sinc Layer','SincNet Layer'}';
Accuracy = [convNetInfo.FinalValidationAccuracy;constSincInfo.FinalValidationAccuracy;sincNetInfo.FinalValidationAccuracy];
resultsSummary = table(NetworkType,Accuracy)resultsSummary=3×2 table
NetworkType Accuracy
_______________________ ________
{'Standard CNN' } 72.97
{'Constant Sinc Layer'} 74.902
{'SincNet Layer' } 78.062
Постройте точность на наборе тестов против номера эпохи, чтобы видеть, как хорошо сети учатся как количество увеличения эпох. SincNet превосходит по характеристикам ConstantSincLayer сеть, особенно во время ранних стадий обучения. Это показывает, что обновление параметров полосовых фильтров в среде нейронной сети приводит к более быстрой сходимости. Это поведение только наблюдается, когда набор данных достаточно большой, таким образом, это не может быть замечено когда reduceDataSet установлен в true.
epoch = linspace(0,numEpochs,numel(sincNetInfo.ValidationAccuracy(~isnan(sincNetInfo.ValidationAccuracy)))); epoch = [epoch,numEpochs]; sinc_valAcc = [sincNetInfo.ValidationAccuracy(~isnan(sincNetInfo.ValidationAccuracy)),... sincNetInfo.FinalValidationAccuracy]; const_sinc_valAcc = [constSincInfo.ValidationAccuracy(~isnan(constSincInfo.ValidationAccuracy)),... constSincInfo.FinalValidationAccuracy]; conv_valAcc = [convNetInfo.ValidationAccuracy(~isnan(convNetInfo.ValidationAccuracy)),... convNetInfo.FinalValidationAccuracy]; figure plot(epoch,sinc_valAcc,'-*','MarkerSize',4) hold on plot(epoch,const_sinc_valAcc,'-*','MarkerSize',4) plot(epoch,conv_valAcc,'-*','MarkerSize',4) ylabel('Frame-Level Accuracy (Test Set)') xlabel('Epoch') xlim([0 numEpochs+0.3]) title('Frame-Level Accuracy Versus Epoch') legend("sincNet","constantSincLayer","conv2dLayer","Location","southeast") grid on

На рисунке выше, точность последнего кадра несколько отличается от точности системы координат, которая вычисляется в последней итерации. В то время как обучение, слои нормализации партии. выполняют нормализацию по мини-пакетам. Однако в конце обучения, слои нормализации партии. нормируют по целым обучающим данным, который приводит к небольшому изменению в эффективности.
function [X,Y] = preprocessAudioData(ADS,SL,OL,Fs) if ~isempty(ver('parallel')) pool = gcp; numPar = numpartitions(ADS,pool); else numPar = 1; end parfor ii = 1:numPar X = zeros(1,SL,1,0); Y = zeros(0); subADS = partition(ADS,numPar,ii); while hasdata(subADS) [audioIn,dsInfo] = read(subADS); speechIdx = detectSpeech(audioIn,Fs); numChunks = size(speechIdx,1); audioData = zeros(1,SL,1,0); for chunk = 1:numChunks % Remove trail end audio audio_chunk = audioIn(speechIdx(chunk,1):speechIdx(chunk,2)); audio_chunk = buffer(audio_chunk,SL,OL); q = size(audio_chunk,2); % Split audio into 200 ms chunks audio_chunk = reshape(audio_chunk,1,SL,1,q); % Concatenate with existing audio audioData = cat(4,audioData,audio_chunk); end audioLabel = str2double(dsInfo.Label{1}); % Generate labels for training and testing by replecating matrix audioLabelsTrain = repmat(audioLabel,1,size(audioData,4)); % Add data points for current speaker to existing data X = cat(4,X,audioData); Y = cat(2,Y,audioLabelsTrain); end XC{ii} = X; YC{ii} = Y; end X = cat(4,XC{:}); Y = cat(2,YC{:}); Y = categorical(Y); end
[1] М. Раванелли и И. Бенхио, "Распознавание динамика от Необработанной Формы волны с SincNet", 2 018 Семинаров по Технологии Разговорного языка IEEE (SLT), Афины, Греция, 2018, стр 1021-1028, doi: 10.1109/SLT.2018.8639585.
[2] В. Панаетов, Г. Чен, Д. Пови и С. Худэнпур, "Librispeech: корпус ASR на основе аудиокниг общественного достояния", 2 015 Международных конференций IEEE по вопросам Акустики, Речи и Обработки сигналов (ICASSP), Брисбена, QLD, 2015, стр 5206-5210, doi: 10.1109/ICASSP.2015.7178964