В этом примере подробно описывается рабочий процесс сегментации формы сигнала электрокардиограммы (ЭКГ) с использованием кратковременного преобразования Фурье и двунаправленной сети долговременной памяти (BiLSTM). В примере также представлена информация о том, как генерировать и развертывать код и обученную сеть BiLSTM для сегментации на цели Raspberry Pi™ (устройство на базе ARM ®).
Предварительно обученная сеть в данном примере аналогична примеру сегментации сигналов с использованием глубокого обучения (панель инструментов обработки сигналов).
В этом примере приводится подробная информация:
Рабочий процесс на основе процессора в цикле (PIL) для проверки созданного кода, развернутого и запущенного на Raspberry Pi из MATLAB™
Создание автономного исполняемого файла
Процесс проверки PIL является важной частью цикла проектирования, чтобы проверить, соответствует ли поведение сгенерированного кода конструкции перед развертыванием автономного исполняемого файла.
В этом примере используются сигналы ЭКГ из общедоступной базы данных QT [1] [2]. Данные состоят примерно из 15 минут меченых записей ЭКГ с частотой выборки 250 Гц, измеренной от общего числа 105 пациентов.
Сигнал ЭКГ можно разделить на следующие морфологии биений [3]:
P wave - небольшой прогиб перед комплексом QRS, представляющим собой деполяризацию предсердий;
Комплекс QRS - Наибольшая амплитудная часть пульса
T wave - небольшой прогиб после комплекса QRS, представляющий реполяризацию желудочков
Сегментация этих областей сигналов ЭКГ может обеспечить основу для измерений, которые оценивают общее состояние здоровья сердца человека и наличие аномалий.
Процессор ARM, поддерживающий расширение NEON
Вычислительная библиотека ARM (на целевом оборудовании ARM)
MATLAB ® Coder™
Встроенные Coder™
Глубокое обучение Toolbox™
Поддерживаемые версии библиотек и сведения о настройке переменных среды см. в разделе Предварительные условия для глубокого обучения с помощью кодера MATLAB (MATLAB Coder) (кодер MATLAB).
Основная функция в созданном исполняемом файле:
Использует 15 000 образцов данных ЭКГ с одинарной точностью в качестве входных данных.
Вычисляет кратковременное преобразование Фурье сигнала.
Стандартизирует и нормализует выходные данные.
Маркирует области сигнала с помощью предварительно обученной сети BiLSTM.
Создает выходной файл с метками.
waveformSegmentation ФункцияФункция начального уровня, также известная как функция верхнего уровня или первичная функция, является функцией, определяемой для создания кода. Необходимо определить функцию точки входа, которая вызывает функции с поддержкой генерации кода и генерирует код C/C + + из функции точки входа. Все функции в рамках функции начального уровня должны поддерживать генерацию кода.
В этом примере waveformSegmentation является функцией точки входа. Он принимает сигнал ЭКГ в качестве входного сигнала и передает его в обученную сеть BiLSTM для прогнозирования. performPreprocessing функция предварительно обрабатывает необработанный сигнал и применяет кратковременное преобразование Фурье. genClassifiedResults функция передает предварительно обработанный сигнал в сеть для прогнозирования и отображает результаты классификации.
type waveformSegmentationfunction out = waveformSegmentation(in)
%#codegen
persistent net;
if isempty(net)
net = coder.loadDeepLearningNetwork('trained-network-STFTBILSTM.mat', 'net');
end
preprocessedSignal = performPreprocessing(in);
out = cell(3,1);
for indx = 1:3
out{indx,1} = genClassifedResults(net.predict(preprocessedSignal{1,indx}));
end
end
Используйте функцию MATLAB Support Package for Raspberry Pi, raspi, чтобы создать соединение с Raspberry Pi. В следующем коде замените:
'raspiname' с именем вашего Малинового Пи
'pi' с вашим именем пользователя
'password' с вашим паролем
r = raspi('raspiname','pi','password');
В примере показан рабочий поток на основе PIL для проверки кода и конструкции, а затем создается и развертывается автономный исполняемый файл. При необходимости, если требуется непосредственно развернуть автономный исполняемый файл, можно пропустить выполнение PIL и перейти к созданию автономного выполнения.
На первом шаге показан поток операций на основе PIL для создания функции MEX для waveformSegmentation функция.
Создание объекта конфигурации кода для статической библиотеки и установка режима проверки 'PIL'. Задайте для целевого языка значение 'C++'.
cfg = coder.config('lib','ecoder',true); cfg.VerificationMode = 'PIL'; cfg.TargetLang = 'C++';
Создать coder.ARMNEONConfig объект. Укажите версию библиотеки вычислений ARM в качестве версии на Raspberry Pi. Укажите архитектуру Raspberry Pi. (В этом примере требуется вычислительная библиотека ARM версии 19.05).
dlcfg = coder.DeepLearningConfig('arm-compute'); dlcfg.ArmComputeVersion = '19.05'; dlcfg.ArmArchitecture = 'armv7';
Установите DeepLearningConfig свойство объекта конфигурации генерации кода для объекта конфигурации глубокого обучения. Задайте объект конфигурации с исходными комментариями MATLAB, видимыми в кодовом коде.
cfg.DeepLearningConfig = dlcfg; cfg.MATLABSourceComments = 1;
Создать coder.Hardware объект для Raspberry Pi и присоедините его к объекту конфигурации генерации кода.
hw = coder.hardware('Raspberry Pi');
cfg.Hardware = hw;Укажите папку сборки на Raspberry Pi.
cfg.Hardware.BuildDir = '~/waveformSegmentation';codegen ФункцияИспользуйте codegen для генерации кода C++. Когда codegen используется с пакетом поддержки MATLAB для аппаратных средств Raspberry Pi, сгенерированный код загружается на плату и компилируется там. Функция PIL MEX генерируется для обмена данными между MATLAB и генерируемым кодом, выполняемым на Raspberry Pi.
Убедитесь, что установлены переменные среды ARM_COMPUTELIB и LD_LIBRARY_PATH на Малиновом Пи. См. раздел Предпосылки для глубокого обучения с помощью кодера MATLAB (MATLAB Coder).
codegen -config cfg waveformSegmentation -args {coder.typeof(single(ones(1,15000)),[1,15000],[0,0])} -report
### Target device has no native communication support. Checking connectivity configuration registrations... Deploying code. This may take a few minutes. ### Target device has no native communication support. Checking connectivity configuration registrations... ### Connectivity configuration for function 'waveformSegmentation': 'Raspberry Pi' Location of the generated elf : /home/pi/waveformSegmentation/MATLAB_ws/R2020b/C/Users/eshashah/OneDrive_-_MathWorks/Documents/MATLAB/Examples/deeplearning_shared-ex28372959/codegen/lib/waveformSegmentation/pil Code generation successful: View report
Загрузка файла MAT ecgsignal_test. В файле хранится образец сигнала ЭКГ, на котором можно протестировать сгенерированный код.
Выполнить сгенерированное waveformSegmentation_pil Функция MEX в тестовом сигнале.
load ecgsignal_test.mat;
out = waveformSegmentation_pil(test);### Starting application: 'codegen\lib\waveformSegmentation\pil\waveformSegmentation.elf'
To terminate execution: clear waveformSegmentation_pil
### Launching application waveformSegmentation.elf...
Отображение сигналов с прогнозируемыми метками.
labels = categorical(out{1}(1,2000:3000));
msk = signalMask(labels);
plotsigroi(msk,test(1,2000:3000))
title('Predicted Labels')
После проверки выходных данных функции PIL MEX можно создать автономный исполняемый файл для waveformSegmentation функция.
В следующей части показан рабочий процесс создания кода для создания и развертывания автономного исполняемого файла в коде для прогнозирования на Raspberry Pi с помощью приложения MATLAB Coder App.
Приложение MATLAB Coder генерирует код C или C++ из кода MATLAB ®. Пользовательский интерфейс на основе рабочего процесса выполняет процесс создания кода. Следующие шаги описывают краткий рабочий процесс с использованием приложения Кодер MATLAB. Дополнительные сведения см. в разделах Кодер MATLAB (Кодер MATLAB) и Создание кода C с помощью приложения кодера MATLAB (Кодер MATLAB).
На вкладке Приложения щелкните стрелку вниз справа от панели инструментов, чтобы развернуть галерею приложений. В разделе Создание кода (Code Generation) щелкните Кодер MATLAB (MATLAB Coder). Приложение открывает страницу Выбор исходных файлов. Введите или выберите имя функции точки входа, waveformSegmentation.

Щелкните Далее (Next), чтобы перейти на страницу Определение типов ввода (Define Input Types).
1. Выберите Разрешить ввод входных или глобальных типов непосредственно и задайте значение входных данных. in как одиночный (1x15000).
2. Нажмите кнопку Далее, чтобы перейти к шагу Создать код. Пропустите шаг Проверка ошибок времени выполнения, поскольку генерация MEX не поддерживается для генерации кода с помощью библиотеки вычислений ARM.
1. Задайте значения в диалоговом окне создания кода:
Задать для типа построения значение Executable (.exe)
Задать язык как C++
Установка платы аппаратных средств как Raspberry Pi
2. Нажмите кнопку «Дополнительные параметры»:
На панели «Пользовательский код» в дополнительных исходных файлах найдите и выберите ecgsegmentation_main.cpp. Дополнительные сведения о записи основной функции C/C + + см. в разделе Структура сгенерированной основной функции C/C + + (кодер MATLAB).
На панели «Оборудование» задайте имя пользователя и пароль для платы Raspberry Pi.
В области «Глубокое обучение» задайте для параметра «Целевая библиотека» значение ARM Compute. Укажите версию библиотеки вычислений ARM и архитектуру вычислений ARM.

3. Закройте окно Настройки и создайте код.
4. Нажмите кнопку Далее, чтобы перейти на страницу Завершить рабочий процесс.
Как только формирование кода завершено, следующие строки кода для тестирования сгенерированного кода на Raspberry Pi копируют входной сигнал ЭКГ в каталог сгенерированного кода. Этот каталог можно найти вручную или с помощью raspi.utils.getRemoteBuildDirectory API. Эта функция перечисляет каталоги двоичных файлов, которые создаются с помощью codegen функция. Если двоичный файл найден только в одном каталоге, введите:
applicationDirPaths =...
raspi.utils.getRemoteBuildDirectory('applicationName','waveformSegmentation');
targetDirPath = applicationDirPaths{1}.directory;
Для копирования файлов, необходимых для запуска исполняемой программы, используйте putFile, который поставляется с пакетом поддержки MATLAB для оборудования Raspberry Pi. input.csv файл содержит образец сигнала ЭКГ, который используется для тестирования развернутого кода.
r.putFile('input.csv', targetDirPath);
input = dlmread('input.csv');
Запустите исполняемую программу на Raspberry Pi из MATLAB и получите выходной файл в MATLAB. Имя входного файла должно передаваться в качестве аргумента командной строки для исполняемого файла.
exeName = 'waveformSegmentation.elf'; % Executable name
command = ['cd ' targetDirPath ';./' exeName];
system(r,command)
outputPath = strcat(targetDirPath,'/*.txt');
getFile(r,outputPath)
Отображение сигналов с прогнозируемыми метками. Выходные данные изображены на рисунке.
load ecgsignal_test.mat;
labels = categorical(textread('out.txt','%s')');
msk = signalMask(labels(1,2000:3000));
plotsigroi(msk,test(1,2000:3000))
title('Predicted Labels')

[1] Макшарри, Патрик Э., и др. «Динамическая модель для генерации синтетических сигналов электрокардиограммы». Транзакции IEEE ® по биомедицинской инженерии. т. 50, № 3, 2003, стр. 289-294.
[2] Лагуна, Пабло, Раймон Джане и Пер Каминал. «Автоматическое обнаружение границ волн в многолучевых сигналах ЭКГ: валидация с базой данных CSE». Компьютеры и биомедицинские исследования. Том 27, № 1, 1994, стр. 45-60.
[3] Голдбергер, Ари Л., Луис А. Н. Амарал, Леон Гласс, Джеффери М. Хаусдорфф, Пламен Ч. Иванов, Роджер Г. Марк, Джозеф Э. Миет, Джордж Б. Муди, Чон-Кан Пэн и Х. Эугал «PhysioBank, PhysioToolkit и PhysioNet: компоненты нового исследовательского ресурса для сложных физиологических сигналов». Циркуляция. Том 101, № 23, 2000, стр. e215-e220. [Электронные страницы тиража; http://circ.ahajournals.org/content/101/23/e215.full].
codegen (Кодер MATLAB) | fsst(Панель инструментов обработки сигналов) | signalMask(Панель инструментов обработки сигналов)