Этот пример демонстрирует генерацию кода для Основанного на акустике Распознавания Отказа Машины (Audio Toolbox) с помощью долгой краткосрочной памяти (LSTM) сетевые и спектральные дескрипторы. Этот пример использует MATLAB® Coder™, Интерфейс MATLAB Coder для Библиотек Глубокого обучения, Пакет поддержки MATLAB для Оборудования Raspberry Pi, чтобы сгенерировать независимый исполняемый файл (.elf
) файл на Raspberry Pi™, который усиливает эффективность Руки, Вычисляет Библиотеку. Входные данные состоят из записей timeseries акустики от неисправных или здоровых воздушных компрессоров, и выход является состоянием механической машины, предсказанной сетью LSTM. Этот независимый исполняемый файл на Raspberry Pi запускает классификатор потоковой передачи на входных данных, полученных от MATLAB, и отправляет вычисленную музыку к каждой метке к MATLAB. Взаимодействие между скриптом MATLAB и исполняемым файлом на вашем Raspberry Pi обработано с помощью пользовательского дейтаграммного протокола (UDP). Для получения дополнительной информации о предварительной обработке аудио и сетевом обучении, смотрите Основанное на акустике Распознавание Отказа Машины (Audio Toolbox).
Интерфейс MATLAB Coder для пакета поддержки библиотек глубокого обучения
Процессор ARM, который поддерживает расширение NEON
ARM Вычисляет версию 20.02.1 Библиотеки (на целевом оборудовании ARM)
Переменные окружения для компиляторов и библиотек
Для поддерживаемых версий библиотек и для получения информации о подготовке переменных окружения, смотрите Необходимые условия для Глубокого обучения для MATLAB Coder (MATLAB Coder)
Задайте частоту дискретизации fs
из 16 кГц и windowLength
из 512 выборок, как задано в Основанном на акустике Распознавании Отказа Машины (Audio Toolbox). Установите numFrames
к 100
.
fs = 16000; windowLength = 512; numFrames = 100;
Чтобы запустить Пример на тестовом сигнале, сгенерируйте розовый шумовой сигнал. Чтобы проверить производительность системы на действительном наборе данных, загрузите воздушный набор данных компрессора [1].
downloadDataset = false; if ~downloadDataset pinkNoiseSignal = pinknoise (windowLength*numFrames); else % Download AirCompressorDataset.zip компонент = 'audio'; имя файла = 'AirCompressorDataset/AirCompressorDataset.zip'; localfile = matlab.internal.examples.downloadSupportFile (компонент, имя файла); % Unzip the downloaded zip file to the downloadFolder downloadFolder = fileparts (localfile); if ~exist (fullfile (downloadFolder,'AirCompressorDataset'),'dir') разархивируйте (localfile, downloadFolder) end % Create an audioDatastore object dataStore, to manage, the data. dataStore = audioDatastore (downloadFolder,'IncludeSubfolders'TRUE,'LabelSource','foldernames'); % Use countEachLabel to get the number of samples of each category in the dataset. countEachLabel (dataStore) end
Чтобы запустить классификатор потоковой передачи в MATLAB, загрузите и разархивируйте систему, разработанную в Основанном на акустике Распознавании Отказа Машины (Audio Toolbox).
component = 'audio'; filename = 'AcousticsBasedMachineFaultRecognition/AcousticsBasedMachineFaultRecognition.zip'; localfile = matlab.internal.examples.downloadSupportFile(component,filename); downloadFolder = fullfile(fileparts(localfile),'system'); if ~exist(downloadFolder,'dir') unzip(localfile,downloadFolder) end
Получить доступ к recognizeAirCompressorFault
функция системы, добавляет downloadFolder
к пути поиска файлов.
addpath(downloadFolder)
Создайте dsp.AsyncBuffer
Объект (DSP System Toolbox) считать аудио способом потоковой передачи и dsp.AsyncBuffer
Объект (DSP System Toolbox) накопить баллы.
audioSource = dsp.AsyncBuffer; scoreBuffer = dsp.AsyncBuffer;
Загрузите предварительно обученную сеть и извлеките метки из сети.
airCompNet = coder.loadDeepLearningNetwork('AirCompressorFaultRecognitionModel.mat');
labels = string(airCompNet.Layers(end).Classes);
Инициализируйте signalToBeTested
к pinkNoiseSignal
или выберите сигнал из выпадающего списка, чтобы протестировать файл по вашему выбору от набора данных.
if ~downloadDataset signalToBeTested = pinkNoiseSignal; else [allFiles,~] = splitEachLabel(dataStore,1); allData = readall(allFiles); signalToBeTested = allData(1); signalToBeTested = cell2mat (signalToBeTested); end
Передайте одну аудио систему координат потоком за один раз, чтобы представлять систему, когда это было бы развернуто во встроенной системе реального времени. Используйте recognizeAirCompressorFault
разработанный в Основанном на акустике Распознавании Отказа Машины (Audio Toolbox), чтобы вычислить функции аудио и выполнить классификацию глубокого обучения.
write(audioSource,signalToBeTested); resetNetworkState = true; while audioSource.NumUnreadSamples >= windowLength % Get a frame of audio data x = read(audioSource,windowLength); % Apply streaming classifier function score = recognizeAirCompressorFault(x,resetNetworkState); % Store score for analysis write(scoreBuffer,score); resetNetworkState = false; end
Вычислите распознанный отказ из баллов и отобразите его.
scores = read(scoreBuffer); [~,labelIndex] = max(scores(end,:),[],2); detectedFault = labels(labelIndex)
detectedFault = "Flywheel"
Постройте множество каждой метки для каждой системы координат.
plot(scores) legend("" + labels,'Location','northwest') xlabel("Time Step") ylabel("Score") str = sprintf("Predicted Scores Over Time Steps.\nPredicted Class: %s",detectedFault); title(str)
Сбросьте асинхронный буферный audioSource
.
reset(audioSource)
Этот пример использует dsp.UDPSender
(DSP System Toolbox) Системный объект, чтобы передать аудио кадр к исполняемому файлу, работающему на Raspberry Pi и dsp.UDPReceiver
(DSP System Toolbox) Системный объект, чтобы получить вектор счета от Raspberry Pi. Создайте dsp.UDPSender
(DSP System Toolbox) системный объект, чтобы отправить аудио, записанное в MATLAB к вашему Raspberry Pi. Установите targetIPAddress
к IP-адресу вашего Raspberry Pi. Установите RemoteIPPort
к 25000
. Raspberry Pi принимает входной кадр аудио от того же порта с помощью dsp.UDPReceiver
(DSP System Toolbox) системный объект.
targetIPAddress = '172.31.164.247'; UDPSend = dsp.UDPSender('RemoteIPPort',25000,'RemoteIPAddress',targetIPAddress);
Создайте dsp.UDPReceiver
(DSP System Toolbox) системный объект, чтобы получить предсказанные баллы от вашего Raspberry Pi. Каждый пакет UDP, полученный от Raspberry Pi, является вектором из баллов, и каждым векторным элементом является счет к состоянию воздушного компрессора. Максимальная длина сообщения для dsp.UDPReceiver
Объект (DSP System Toolbox) составляет 65 507 байтов. Вычислите buffer size, чтобы вместить максимальное количество пакетов UDP.
sizeOfDoubleInBytes = 8; numScores = 8; maxUDPMessageLength = floor(65507/sizeOfDoubleInBytes); numPackets = floor(maxUDPMessageLength/numScores); bufferSize = numPackets*numScores*sizeOfDoubleInBytes; UDPReceive = dsp.UDPReceiver("LocalIPPort",21000, ... "MessageDataType","single", ... "MaximumMessageLength",numScores, ... "ReceiveBufferSize",bufferSize);
Создайте функцию поддержки, recognizeAirCompressorFaultRaspi
, это принимает аудио кадр с помощью dsp.UDPReceiver
(DSP System Toolbox) и применяет классификатор потоковой передачи и отправляет предсказанный вектор счета в MATLAB с помощью dsp.UDPSender
(DSP System Toolbox).
type recognizeAirCompressorFaultRaspi
function recognizeAirCompressorFaultRaspi(hostIPAddress) % This function receives acoustic input using dsp.UDPReceiver and runs a % streaming classifier by calling recognizeAirCompressorFault, developed in % the Acoustics-Based Machine Fault Recognition - MATLAB Example. % Computed scores are sent to MATLAB using dsp.UDPSender. %#codegen % Copyright 2021 The MathWorks, Inc. frameLength = 512; % Configure UDP Sender System Object UDPSend = dsp.UDPSender('RemoteIPPort',21000,'RemoteIPAddress',hostIPAddress); % Configure UDP Receiver system object sizeOfDoubleInBytes = 8; maxUDPMessageLength = floor(65507/sizeOfDoubleInBytes); numPackets = floor(maxUDPMessageLength/frameLength); bufferSize = numPackets*frameLength*sizeOfDoubleInBytes; UDPReceiveRaspi = dsp.UDPReceiver('LocalIPPort',25000, ... 'MaximumMessageLength',frameLength, ... 'ReceiveBufferSize',bufferSize, ... 'MessageDataType','double'); % Reset network state for first call resetNetworkState = true; while true % Receive audio frame of size frameLength x 1 x = UDPReceiveRaspi(); if(~isempty(x)) x = x(1:frameLength,1); % Apply streaming classifier function scores = recognizeAirCompressorFault(x,resetNetworkState); %Send output to the host machine UDPSend(scores); resetNetworkState = false; end end
Замените hostIPAddress
с адресом вашей машины. Ваш Raspberry Pi отправляет предсказанные баллы в IP-адрес, который вы задаете.
hostIPAddress = coder.Constant('172.18.230.30');
Создайте объект настройки генерации кода сгенерировать исполняемую программу. Задайте выходной язык как C++.
cfg = coder.config('exe'); cfg.TargetLang = 'C++';
Создайте объект настройки для генерации кода глубокого обучения с ARM, вычисляют библиотеку, которая находится на вашем Raspberry Pi. Задайте архитектуру Raspberry Pi и присоедините объект настройки глубокого обучения к объекту настройки генерации кода.
dlcfg = coder.DeepLearningConfig('arm-compute'); dlcfg.ArmArchitecture = 'armv7'; dlcfg.ArmComputeVersion = '20.02.1'; cfg.DeepLearningConfig = dlcfg;
Используйте функцию Пакета поддержки Raspberry Pi raspi
создать связь с вашим Raspberry Pi. В следующем блоке кода, замене:
raspiname
с именем вашего Raspberry Pi
pi
с вашим именем пользователя
password
с вашим паролем
if (~exist('r','var')) r = raspi('raspiname','pi','password'); end
Создайте coder.hardware
Объект (MATLAB Coder) для Raspberry Pi и присоединения это к объекту настройки генерации кода.
hw = coder.hardware('Raspberry Pi');
cfg.Hardware = hw;
Задайте папку сборки на Raspberry Pi.
buildDir = '~/remoteBuildDir';
cfg.Hardware.BuildDir = buildDir;
Используйте автоматически сгенерированный C++ основной файл, чтобы сгенерировать независимый исполняемый файл.
cfg.GenerateExampleMain = 'GenerateCodeAndCompile';
Вызовите codegen
(MATLAB Coder) функция от MATLAB Coder, чтобы сгенерировать Код С++ и исполняемый файл на вашем Raspberry Pi. По умолчанию исполняемый файл Raspberry Pi имеет то же имя как функция MATLAB. Вы получаете предупреждение в журналах генерации кода that
можно игнорировать потому что recognizeAirCompressorFaultRaspi
имеет бесконечный цикл, который ищет аудио систему координат из MATLAB.
codegen -config cfg recognizeAirCompressorFaultRaspi -args {hostIPAddress} -report
Deploying code. This may take a few minutes. Warning: Function 'recognizeAirCompressorFaultRaspi' does not terminate due to an infinite loop. Warning in ==> recognizeAirCompressorFaultRaspi Line: 1 Column: 1 Code generation successful (with warnings): View report
Создайте команду, чтобы открыть recognizeAirCompressorFaultRaspi
приложение на Raspberry Pi. Использование системы
отправить команду в ваш Raspberry Pi.
applicationName = 'recognizeAirCompressorFaultRaspi'; applicationDirPaths = raspi.utils.getRemoteBuildDirectory('applicationName',applicationName); targetDirPath = applicationDirPaths{1}.directory; exeName = strcat(applicationName,'.elf'); command = ['cd ',targetDirPath,'; ./',exeName,' &> 1 &']; system(r,command);
Инициализируйте signalToBeTested
к pinkNoiseSignal
или выберите сигнал из выпадающего списка, чтобы протестировать файл по вашему выбору от набора данных.
if ~downloadDataset signalToBeTested = pinkNoiseSignal; else [allFiles,~] = splitEachLabel(dataStore,1); allData = readall(allFiles); signalToBeTested = allData(1); signalToBeTested = cell2mat (signalToBeTested); end
Передайте одну аудио систему координат потоком за один раз, чтобы представлять систему, когда она была бы развернута во встроенной системе реального времени. Используйте сгенерированный файл MEX recognizeAirCompressorFault_mex
вычислить функции аудио и выполнить классификацию глубокого обучения.
write(audioSource,signalToBeTested); while audioSource.NumUnreadSamples >= windowLength x = read(audioSource,windowLength); UDPSend(x); score = UDPReceive(); if ~isempty(score) write(scoreBuffer,score'); end end
Вычислите распознанный отказ из баллов и отобразите его.
scores = read(scoreBuffer); [~,labelIndex] = max(scores(end,:),[],2); detectedFault = labels(labelIndex)
detectedFault = "Flywheel"
Постройте множество каждой метки для каждой системы координат.
plot(scores) legend("" + labels,'Location','northwest') xlabel("Time Step") ylabel("Score") str = sprintf("Predicted Scores Over Time Steps.\nPredicted Class: %s",detectedFault); title(str)
Отключите независимый исполняемый файл, работающий на Raspberry Pi.
stopExecutable(codertarget.raspi.raspberrypi,exeName)
Чтобы оценить время выполнения, потраченное независимым исполняемым файлом на Raspberry Pi, используйте PIL (процессор в цикле) рабочий процесс. Чтобы выполнить профилирование PIL, сгенерируйте функцию PIL для функции поддержки recognizeAirCompressorFault
.
Создайте объект настройки генерации кода сгенерировать функцию PIL.
cfg = coder.config('lib','ecoder',true); cfg.VerificationMode = 'PIL';
Установите ARM, вычисляют библиотеку и архитектуру.
dlcfg = coder.DeepLearningConfig('arm-compute'); cfg.DeepLearningConfig = dlcfg ; cfg.DeepLearningConfig.ArmArchitecture = 'armv7'; cfg.DeepLearningConfig.ArmComputeVersion = '20.02.1';
Настройте связь со своим целевым компьютером.
if (~exist('r','var')) r = raspi('raspiname','pi','password'); end hw = coder.hardware('Raspberry Pi'); cfg.Hardware = hw;
Установите каталог сборки и выходной язык.
buildDir = '~/remoteBuildDir'; cfg.Hardware.BuildDir = buildDir; cfg.TargetLang = 'C++';
Позвольте профилировать и сгенерируйте код PIL. Файл MEX под названием recognizeAirCompressorFault_pil
сгенерирован в вашей текущей папке.
cfg.CodeExecutionProfiling = true; audioFrame = ones(windowLength,1); resetNetworkStateFlag = true; codegen -config cfg recognizeAirCompressorFault -args {audioFrame,resetNetworkStateFlag}
Deploying code. This may take a few minutes. ### Connectivity configuration for function 'recognizeAirCompressorFault': 'Raspberry Pi' Location of the generated elf : /home/pi/remoteBuildDir/MATLAB_ws/R2021b/S/MATLAB/Examples/ExampleManager/sporwal.Bdoc21b.j1720794/deeplearning_shared-ex44063374/codegen/lib/recognizeAirCompressorFault/pil Code generation successful.
Вызовите сгенерированную функцию PIL 50 раз, чтобы получить среднее время выполнения.
totalCalls = 50; for k = 1:totalCalls x = pinknoise(windowLength,1); score = recognizeAirCompressorFault_pil(x,resetNetworkStateFlag); resetNetworkStateFlag = false; end
### Starting application: 'codegen\lib\recognizeAirCompressorFault\pil\recognizeAirCompressorFault.elf' To terminate execution: clear recognizeAirCompressorFault_pil ### Launching application recognizeAirCompressorFault.elf... Execution profiling data is available for viewing. Open Simulation Data Inspector. Execution profiling report available after termination.
Отключите выполнение PIL.
clear recognizeAirCompressorFault_pil
### Host application produced the following standard output (stdout) and standard error (stderr) messages: ### Connectivity configuration for function 'recognizeAirCompressorFault': 'Raspberry Pi' Execution profiling report: report(getCoderExecutionProfile('recognizeAirCompressorFault'))
Сгенерируйте профиль выполнения, сообщают, чтобы оценить время выполнения.
executionProfile = getCoderExecutionProfile('recognizeAirCompressorFault'); report(executionProfile, ... 'Units','Seconds', ... 'ScaleFactor','1e-03', ... 'NumericFormat','%0.4f');
Среднее время выполнения recognizeAirCompressorFault_pil
функцией является 0.423
ms
, который является значительно ниже 32
ms
бюджет для эффективности в реальном времени. Первый вызов recognizeAirCompressorFault_pil
использует вокруг 12
времена среднего времени выполнения, когда это включает загрузку сети и сброс состояний. Однако в действительной, развернутой системе, то время инициализации понесено только однажды. Этот пример заканчивается здесь. Для развертывания распознавания отказа машины на рабочих столах смотрите Основанную на акустике Генерацию кода Распознавания Отказа Машины с Intel MKL-DNN (Audio Toolbox).
[1] Verma, Нищел К., и др. "Интеллектуальный основанный на условии Контроль Используя Акустические Сигналы для Воздушных Компрессоров". Транзакции IEEE на Надежности, издании 65, № 1, март 2016, стр 291–309. DOI.org (Crossref), doi:10.1109/TR.2015.2459684.