В этом примере демонстрируется создание кода для определения ключевых слов с использованием сети двунаправленной долговременной памяти (BiLSTM) и извлечения функции частотного кепстрального коэффициента (MFCC). MATLAB ® Coder™ с поддержкой глубокого обучения позволяет создавать автономные исполняемые файлы (.exe). Связь между файлом MATLAB ® (.mlx) и созданным исполняемым файлом осуществляется по асинхронному протоколу пользовательских дейтаграмм (UDP). Входящий речевой сигнал отображается с помощью timescope. Маска отображается синим прямоугольником вокруг пятнистых экземпляров ключевого слова YES. Для получения более подробной информации об извлечении функций MFCC и обучении работе с сетью глубокого обучения посетите раздел Ключевые слова - определение шума с использованием сетей MFCC и LSTM.
Интерфейс кодера MATLAB ® для пакета поддержки глубокого обучения
Процессор Intel Xeon с поддержкой Intel Advanced Vector Extensions 2 (Intel AVX2)
Библиотека Intel Math Kernel Library для глубоких нейронных сетей (MKL-DNN)
Переменные среды для Intel MKL-DNN
Поддерживаемые версии библиотек и сведения о настройке переменных среды см. в разделе Предварительные условия для глубокого обучения с помощью кодера MATLAB (MATLAB Coder).
Частота выборки предварительно обученной сети составляет 16 кГц. Задайте длину окна как 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);
Создайте временную область для визуализации речевых сигналов и оценочной маски.
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) (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вспомогательная функция, которая инкапсулирует процессы захвата звука, извлечения признаков и предсказания сети.
codegen helperKeywordSpotting -config cfg -report
Warning: C++ Compiler produced warnings. See the build log for further details. 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) для производства .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 байт. Вычислите размер буфера для размещения максимального количества пакетов 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);
Чтобы запустить ключевое слово spotting бесконечно, установите 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 22904 (child process of PID 4956) has been terminated. SUCCESS: The process with PID 11260 (child process of PID 4956) has been terminated. SUCCESS: The process with PID 4956 (child process of PID 12964) has been terminated.
Подобный рабочий процесс включает использование файла MEX вместо автономного исполняемого файла. Выполните профилирование MEX для измерения времени вычислений для рабочего процесса.
Создайте объект конфигурации генерации кода для создания функции MEX. Укажите целевой язык как C++.
cfg = coder.config('mex'); cfg.TargetLang = 'C++';
Создайте объект конфигурации для создания кода глубокого обучения с помощью библиотеки MKL-DNN. Присоедините объект конфигурации глубокого обучения к объекту конфигурации генерации кода.
dlcfg = coder.DeepLearningConfig('mkldnn');
cfg.DeepLearningConfig = dlcfg;Вызов кодегена для генерации функции 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 = 22.4670 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 = 6.3982 ms
Сравните общее время выполнения автономного исполняемого подхода с подходом функции MEX. Этот тест производительности выполняется на компьютере с использованием графического процессора NVIDIA Quadro P620 (версия 26) и процессора Intel (R) Xeon (R) W-2133 с тактовой частотой 3,60 ГГц.
PerformanceGain = exeTime/exeTimeMex
PerformanceGain = 3.5115