Этот пример демонстрирует генерацию кода для определения ключевого слова с помощью сети Bidirectional Long Short-Term Memory (BiLSTM) и извлечения признаков частоты mel cepstral коэффициента (MFCC). MATLAB® Coder™ с Поддержкой Глубокого обучения включает генерацию независимого исполняемого файла (.exe
) файл. Связь между MATLAB® (.mlx) файл и сгенерированным исполняемым файлом происходит по асинхронному Пользовательскому дейтаграммному протоколу (UDP). Входящий речевой сигнал отображен с помощью timescope
. Маска показывается синим прямоугольником, окружающим определенные экземпляры ключевого слова, YES. Для получения дополнительной информации об извлечении признаков MFCC и обучении нейронной сети для глубокого обучения, посетите Определение Ключевого слова в Шуме Используя MFCC и Сети LSTM.
MATLAB® Coder Interface для пакета поддержки глубокого обучения
Процессор Intel® Xeon® с поддержкой Intel Усовершенствованные Векторные Расширения 2 (Intel AVX2)
Intel Math Kernel Library для глубоких нейронных сетей (MKL-DNN)
Переменные окружения для Intel MKL-DNN
Для поддерживаемых версий библиотек и для получения информации о подготовке переменных окружения, смотрите Необходимые условия для Глубокого обучения для MATLAB Coder (MATLAB Coder).
Частотой дискретизации предварительно обученной сети является 16
kHz. Установите длину окна на 512
выборки, с длиной перекрытия 384
выборки и длина транзитного участка, заданная как различие между окном и длинами перекрытия. Задайте уровень, на котором оценивается маска. Маска сгенерирована однажды для каждого numHopsPerUpdate
аудио системы координат.
fs = 16e3; windowLength = 512; overlapLength = 384; hopLength = windowLength - overlapLength; numHopsPerUpdate = 16; maskLength = hopLength*numHopsPerUpdate;
Создайте audioFeatureExtractor
объект выполнить извлечение признаков MFCC.
afe = audioFeatureExtractor('SampleRate',fs, ... 'Window',hann(windowLength,'periodic'), ... 'OverlapLength',overlapLength, ... 'mfcc',true, ... 'mfccDelta',true, ... 'mfccDeltaDelta',true);
Загрузите и загрузите предварительно обученную сеть, а также среднее значение (M
) и стандартное отклонение (S
) векторы используются для Стандартизации Функции.
url = 'http://ssd.mathworks.com/supportfiles/audio/KeywordSpotting.zip'; downloadNetFolder = './'; netFolder = fullfile(downloadNetFolder,'KeywordSpotting'); if ~exist(netFolder,'dir') disp('Downloading pretrained network and audio files (4 files - 7 MB) ...') unzip(url,downloadNetFolder) end load(fullfile(netFolder,'KWSNet.mat'),"KWSNet","M","S");
Вызовите generateMATLABFunction
на audioFeatureExtractor
объект создать функцию извлечения признаков. Вы будете использовать эту функцию в цикле обработки.
generateMATLABFunction(afe,'generateKeywordFeatures','IsStreaming',true);
Задайте Читателя Аудио устройства, который может считать аудио из вашего микрофона. Установите длину системы координат, равную длине транзитного участка. Это позволяет вам вычислить новый набор функций каждой новой аудио системы координат от микрофона.
frameLength = hopLength; adr = audioDeviceReader('SampleRate',fs, ... 'SamplesPerFrame',frameLength);
Создайте Time Scope, чтобы визуализировать речевые сигналы и оцененную маску.
scope = timescope('SampleRate',fs, ... 'TimeSpanSource','property', ... 'TimeSpan',5, ... 'TimeSpanOverrunAction','Scroll', ... 'BufferLength',fs*5*2, ... 'ShowLegend',true, ... 'ChannelNames',{'Speech','Keyword Mask'}, ... 'YLimits',[-1.2 1.2], ... 'Title','Keyword Spotting');
Инициализируйте буфер для аудиоданных, буфер для вычисленных функций и буфер, чтобы построить входное аудио и выходную речевую маску.
dataBuff = dsp.AsyncBuffer(windowLength); featureBuff = dsp.AsyncBuffer(numHopsPerUpdate); plotBuff = dsp.AsyncBuffer(numHopsPerUpdate*windowLength);
Выполните определение ключевого слова о речи, полученной от вашего микрофона. Чтобы запустить цикл неопределенно, установите timeLimit
к Inf
. Чтобы остановить симуляцию, закройте scope
.
timeLimit = 20; show(scope); tic while toc < timeLimit && isVisible(scope) data = adr(); write(dataBuff,data); write(plotBuff,data); frame = read(dataBuff,windowLength,overlapLength); features = generateKeywordFeatures(frame,fs); write(featureBuff,features.'); if featureBuff.NumUnreadSamples == numHopsPerUpdate featureMatrix = read(featureBuff); featureMatrix(~isfinite(featureMatrix)) = 0; featureMatrix = (featureMatrix - M)./S; [keywordNet, v] = classifyAndUpdateState(KWSNet,featureMatrix.'); v = double(v) - 1; v = repmat(v,hopLength,1); v = v(:); v = mode(v); predictedMask = repmat(v,numHopsPerUpdate*hopLength,1); data = read(plotBuff); scope([data,predictedMask]); drawnow limitrate; end end release(adr) hide(scope)
helperKeywordSpotting
поддерживающая функция инкапсулирует записывание аудио, извлечения признаков и сетевого процесса предсказания, продемонстрированного ранее. Чтобы сделать извлечение признаков совместимым с генерацией кода, извлечение признаков обработано сгенерированным generateKeywordFeatures
функция. Чтобы сделать сеть совместимой с генерацией кода, функция поддержки использует coder.loadDeepLearningNetwork
(MATLAB Coder) (MATLAB Coder) функционирует, чтобы загрузить сеть.
Функция поддержки использует dsp.UDPSender
Системный объект, чтобы отправить входные данные наряду с выходной маской, предсказанной сетью к MATLAB. Скрипт MATLAB использует dsp.UDPReceiver
Системный объект, чтобы получить входные данные наряду с выходной маской, предсказанной сетью, запускающейся в функции поддержки.
Создайте объект настройки генерации кода сгенерировать исполняемый файл. Задайте выходной язык как C++.
cfg = coder.config('exe'); cfg.TargetLang = 'C++';
Создайте объект настройки для генерации кода глубокого обучения с библиотекой MKL-DNN. Присоедините объект настройки глубокого обучения к объекту настройки генерации кода.
dlcfg = coder.DeepLearningConfig('mkldnn');
cfg.DeepLearningConfig = dlcfg;
Сгенерируйте C++ основной файл, требуемый произвести независимый исполняемый файл.
cfg.GenerateExampleMain = 'GenerateCodeAndCompile';
Сгенерируйте helperKeywordSpotting
, функция поддержки, которая инкапсулирует аудио получение, извлечение признаков и сетевые процессы предсказания. Вы получаете предупреждение в журналах генерации кода, что можно игнорировать потому что helperKeywordSpotting
имеет бесконечный цикл, который постоянно ищет аудио систему координат из MATLAB.
codegen helperKeywordSpotting -config cfg -report
Warning: Function 'helperKeywordSpotting' does not terminate due to an infinite loop. Warning in ==> helperKeywordSpotting Line: 73 Column: 1 Code generation successful (with warnings): View report
В этом разделе вы генерируете все необходимые файлы зависимости и помещаете их в одну папку. Во время процесса сборки MATLAB Coder генерирует buildInfo.mat
, файл, который содержит компиляцию и информацию о зависимостях во время выполнения для независимого исполняемого файла.
Установите название проекта на helperKeywordSpotting
.
projName = 'helperKeywordSpotting'; packageName = [projName,'Package']; if ispc exeName = [projName,'.exe']; else exeName = projName; end
Загрузите buildinfo.mat
и используйте packNGo
(MATLAB Coder), чтобы произвести .zip
пакет.
load(['codegen',filesep,'exe',filesep,projName,filesep,'buildInfo.mat']); packNGo(buildInfo,'fileName',[packageName,'.zip'],'minimalHeaders',false);
Разархивируйте пакет и поместите исполняемый файл в разархивированную директорию.
unzip([packageName,'.zip'],packageName); copyfile(exeName, packageName,'f');
Чтобы вызвать независимый исполняемый файл, который зависит от Динамически подключаемой библиотеки MKL-DNN, добавьте путь к местоположению библиотеки MKL-DNN к переменной окружения PATH
.
setenv('PATH',[getenv('INTEL_MKLDNN'),filesep,'lib',pathsep,getenv('PATH')]);
Запустите сгенерированный исполняемый файл.
if ispc system(['start cmd /k "title ',packageName,' && cd ',packageName,' && ',exeName]); else cd(packageName); system(['./',exeName,' &']); cd ..; end
Создайте dsp.UDPReceiver
Системный объект, чтобы получить речевые данные и предсказанную речевую маску от независимого исполняемого файла. Каждый пакет UDP, полученный от исполняемого файла, состоит из maskLength
выборки маски и речевые выборки. Максимальная длина сообщения для dsp.UDPReceiver
объектом является 65507
байты. Вычислите buffer size, чтобы вместить максимальное количество пакетов UDP.
sizeOfFloatInBytes = 4; speechDataLength = maskLength; numElementsPerUDPPacket = maskLength + speechDataLength; maxUDPMessageLength = floor(65507/sizeOfFloatInBytes); samplesPerPacket = 1 + numElementsPerUDPPacket; numPackets = floor(maxUDPMessageLength/samplesPerPacket); bufferSize = numPackets*samplesPerPacket*sizeOfFloatInBytes; UDPReceive = dsp.UDPReceiver('LocalIPPort',20000, ... 'MessageDataType','single', ... 'MaximumMessageLength',samplesPerPacket, ... 'ReceiveBufferSize',bufferSize);
Чтобы запустить ключевое слово, определяющее неопределенно, установите timelimit
к Inf
. Чтобы остановить симуляцию, закройте scope
.
tic; timelimit = 20; show(scope); while toc < timelimit && isVisible(scope) data = UDPReceive(); if ~isempty(data) plotMask = data(1:maskLength); plotAudio = data(maskLength+1 : maskLength+speechDataLength); scope([plotAudio,plotMask]); end drawnow limitrate; end hide(scope);
Выпустите системные объекты и отключите независимый исполняемый файл.
release(UDPReceive); release(scope); if ispc system(['taskkill /F /FI "WindowTitle eq ',projName,'* " /T']); else system(['killall ',exeName]); end
SUCCESS: The process with PID 4644 (child process of PID 21188) has been terminated. SUCCESS: The process with PID 20052 (child process of PID 21188) has been terminated. SUCCESS: The process with PID 21188 (child process of PID 22940) has been terminated.
Подобный рабочий процесс включает использование файла MEX вместо независимого исполняемого файла. Выполните профилирование MEX, чтобы измерить время вычисления для рабочего процесса.
Создайте объект настройки генерации кода сгенерировать MEX-функцию. Задайте выходной язык как C++.
cfg = coder.config('mex'); cfg.TargetLang = 'C++';
Создайте объект настройки для генерации кода глубокого обучения с библиотекой MKL-DNN. Присоедините объект настройки глубокого обучения к объекту настройки генерации кода.
dlcfg = coder.DeepLearningConfig('mkldnn');
cfg.DeepLearningConfig = dlcfg;
Вызовите codegen, чтобы сгенерировать MEX-функцию для profileKeywordSpotting
.
inputAudioFrame = ones(hopLength,1,'single'); codegen profileKeywordSpotting -config cfg -args {inputAudioFrame} -report
Code generation successful: View report
Измерьте время выполнения кода MATLAB.
x = pinknoise(hopLength,1,'single'); numPredictCalls = 100; totalNumCalls = numPredictCalls*numHopsPerUpdate; exeTimeStart = tic; for call = 1:totalNumCalls [outputMask,inputData,plotFlag] = profileKeywordSpotting(x); end exeTime = toc(exeTimeStart); fprintf('MATLAB execution time per %d ms of audio = %0.4f ms\n',int32(1000*numHopsPerUpdate*hopLength/fs),(exeTime/numPredictCalls)*1000);
MATLAB execution time per 128 ms of audio = 24.9238 ms
Измерьте время выполнения MEX-функции.
exeTimeMexStart = tic; for call = 1:totalNumCalls [outputMask,inputData,plotFlag] = profileKeywordSpotting_mex(x); end exeTimeMex = toc(exeTimeMexStart); fprintf('MEX execution time per %d ms of audio = %0.4f ms\n',int32(1000*numHopsPerUpdate*hopLength/fs),(exeTimeMex/numPredictCalls)*1000);
MEX execution time per 128 ms of audio = 5.2710 ms
Сравните общее время выполнения подхода независимого исполняемого файла с подходом MEX-функции. Этот тест производительности сделан на машине с помощью NVIDIA Quadro® P620 (Версия 26) графический процессор и Xeon W-2133 CPU Intel, достигающий 3,60 ГГц.
PerformanceGain = exeTime/exeTimeMex
PerformanceGain = 4.7285