В этом примере показано, как сгенерировать и развернуть исполняемый файл CUDA®, который классифицирует человеческую электрокардиограмму (ECG) сигналы, использующие функции, извлеченные непрерывным вейвлетом преобразовывает (CWT) и предварительно обученной сверточной нейронной сетью (CNN).
SqueezeNet является глубоким CNN, первоначально спроектированным, чтобы классифицировать изображения на 1 000 категорий. Мы снова используем сетевую архитектуру CNN, чтобы классифицировать сигналы ECG на основе их scalograms. scalogram является абсолютным значением CWT сигнала. После учебного SqueezeNet, чтобы классифицировать сигналы ECG, вы создаете исполняемый файл CUDA, который генерирует scalogram сигнала ECG и затем использует CNN, чтобы классифицировать сигнал. Исполняемый файл и CNN оба развертываются на оборудовании NVIDIA.
Этот пример использует те же данные, как используется в, Классифицируют Временные ряды Используя Анализ Вейвлета и Глубокое обучение (Wavelet Toolbox). В том примере передача обучения с GoogLeNet и SqueezeNet используется, чтобы классифицировать формы волны ECG в одну из трех категорий. Описание данных и как получить его, повторяется здесь для удобства.
Данные о ECG получены из трех групп людей: люди с сердечной аритмией (ARR), люди с застойной сердечной недостаточностью (CHF) и люди с нормальными ритмами пазухи (NSR). Всего от трех Физиосетевых баз данных существует 162 записи ECG: База данных Аритмии MIT-BIH [2] [3], MIT-BIH Нормальная База данных Ритма Пазухи [3] и База данных Застойной сердечной недостаточности BIDMC [1] [3]. А именно, 96 записей от людей с аритмией, 30 записей от людей с застойной сердечной недостаточностью и 36 записей от людей с нормальными ритмами пазухи. Цель состоит в том, чтобы обучить модель различать ARR, швейцарский франк и NSR.
Можно получить эти данные из репозитория MathWorks GitHub. Чтобы загрузить данные из веб-сайта, нажмите Code
и выберите Download ZIP
. Сохраните файл physionet_ECG_data-main.zip
в папке, где у вас есть разрешение записи. Инструкции для этого примера принимают, что вы загрузили файл на свою временную директорию, tempdir
, в MATLAB. Измените последующие инструкции для того, чтобы разархивировать и загрузить данные, если вы принимаете решение загрузить данные в папке, отличающейся от tempdir
.
После загрузки данных GitHub разархивируйте файл в своей временной директории.
unzip(fullfile(tempdir,'physionet_ECG_data-main.zip'),tempdir)
Разархивация создает папку physionet-ECG_data-main
в вашей временной директории. Эта папка содержит текстовый файл README.md
и ECGData.zip
. ECGData.zip
файл содержит:
ECGData.mat
Modified_physionet_data.txt
License.txt
ECGData.mat
содержит данные, используемые в этом примере. Текстовый файл Modified_physionet_data.txt
требуется копированием PhysioNet политики и обеспечивает исходные приписывания для данных, а также описание шагов предварительной обработки применилось к каждой записи ECG.
Разархивируйте ECGData.zip
в physionet-ECG_data-main
. Загрузите файл данных в свое рабочее пространство MATLAB.
unzip(fullfile(tempdir,'physionet_ECG_data-main','ECGData.zip'),... fullfile(tempdir,'physionet_ECG_data-main')) load(fullfile(tempdir,'physionet_ECG_data-main','ECGData.mat'))
ECGData является массивом структур с двумя полями: Data
и Labels
. Data
поле 162 65536 матрица, где каждая строка является записью ECG, произведенной на уровне 128 герц. Labels
162 1 массив ячеек диагностических меток, одной метки для каждой строки Data
. Три диагностических категории: 'ARR'
, 'CHF'
, и 'NSR'
.
После загрузки данных необходимо сгенерировать scalograms сигналов. scalograms являются "входными" изображениями к CNN.
Чтобы сохранить scalograms каждой категории, сначала создайте директорию 'data'
данных о ECG в
tempdir
. Затем создайте три подкаталога в 'data'
названный в честь каждой категории ECG. Функция помощника helperCreateECGDirectories
делает это для вас. helperCreateECGDirectories
принимает ECGData
, имя директории данных о ECG и имя родительского каталога как входные параметры. Можно заменить tempdir
с другой директорией, где у вас есть разрешение записи. Можно найти исходный код для этой функции помощника в разделе Supporting Functions в конце этого примера.
parentDir = tempdir;
dataDir = 'data';
helperCreateECGDirectories(ECGData,parentDir,dataDir)
После создания папок создайте scalograms сигналов ECG, когда RGB отображает, и запишите им в соответствующий подкаталог в dataDir
. Чтобы создать scalograms, сначала предварительно вычислите набор фильтров CWT. Предварительное вычисление набора фильтров является предпочтительным методом при получении CWT многих сигналов с помощью тех же параметров. Функция помощника helperCreateRGBfromTF
делает this.The исходный код для этой функции помощника, находится в разделе Supporting Functions в конце этого примера. Чтобы быть совместимым с архитектурой SqueezeNet, каждое изображение RGB является массивом размера 227 227 3.
helperCreateRGBfromTF(ECGData,parentDir,dataDir)
Загрузите изображения scalogram как datastore изображений. imageDatastore
функционируйте автоматически помечает изображения на основе имен папок и хранит данные как ImageDatastore
объект. Datastore изображений позволяет вам сохранить большие данные изображения, включая данные, которые не умещаются в памяти, и эффективно считать пакеты изображений когда обучение CNN.
allImages = imageDatastore(fullfile(tempdir,dataDir),... 'IncludeSubfolders',true,... 'LabelSource','foldernames');
Случайным образом разделите изображения на две группы, один для обучения и другого для валидации. Используйте 80% изображений для обучения и остатка для валидации. В целях воспроизводимости мы устанавливаем случайный seed на значение по умолчанию.
rng default [imgsTrain,imgsValidation] = splitEachLabel(allImages,0.8,'randomized'); disp(['Number of training images: ',num2str(numel(imgsTrain.Files))]);
Number of training images: 130
disp(['Number of validation images: ',num2str(numel(imgsValidation.Files))]);
Number of validation images: 32
SqueezeNet является предварительно обученным CNN, который может классифицировать изображения в 1 000 категорий. Необходимо переобучить SqueezeNet для нашей проблемы классификации ECG. До переобучения вы изменяете несколько слоев сети и устанавливаете различные опции обучения. После того, как переобучение завершено, вы сохраняете CNN в .mat
файл. Исполняемый файл CUDA будет использовать .mat
файл.
Задайте испытательный индекс эксперимента и директорию результатов. При необходимости создайте директорию.
trial = 1; ResultDir = 'results'; if ~exist(ResultDir,'dir') mkdir(ResultDir) end MatFile = fullfile(ResultDir,sprintf('SqueezeNet_Trial%d.mat',trial));
Загрузите SqeezeNet. Извлеките график слоев и смотрите последние пять слоев.
sqz = squeezenet; lgraph = layerGraph(sqz); lgraph.Layers(end-4:end)
ans = 5×1 Layer array with layers: 1 'conv10' Convolution 1000 1×1×512 convolutions with stride [1 1] and padding [0 0 0 0] 2 'relu_conv10' ReLU ReLU 3 'pool10' Global Average Pooling Global average pooling 4 'prob' Softmax softmax 5 'ClassificationLayer_predictions' Classification Output crossentropyex with 'tench' and 999 other classes
Чтобы переобучить SqueezeNet, чтобы классифицировать три класса сигналов ECG, замените 'conv10'
слой с новым сверточным слоем с количеством фильтров равняется количеству классов ECG. Замените слой классификации на новый без меток класса.
numClasses = numel(categories(imgsTrain.Labels)); new_conv10_WeightLearnRateFactor = 1; new_conv10_BiasLearnRateFactor = 1; newConvLayer = convolution2dLayer(1,numClasses,... 'Name','new_conv10',... 'WeightLearnRateFactor',new_conv10_WeightLearnRateFactor,... 'BiasLearnRateFactor',new_conv10_BiasLearnRateFactor); lgraph = replaceLayer(lgraph,'conv10',newConvLayer); newClassLayer = classificationLayer('Name','new_classoutput'); lgraph = replaceLayer(lgraph,'ClassificationLayer_predictions',newClassLayer); lgraph.Layers(end-4:end)
ans = 5×1 Layer array with layers: 1 'new_conv10' Convolution 3 1×1 convolutions with stride [1 1] and padding [0 0 0 0] 2 'relu_conv10' ReLU ReLU 3 'pool10' Global Average Pooling Global average pooling 4 'prob' Softmax softmax 5 'new_classoutput' Classification Output crossentropyex
Создайте набор опций обучения, чтобы использовать с SqueezeNet.
OptimSolver = 'sgdm'; MiniBatchSize = 15; MaxEpochs = 20; InitialLearnRate = 1e-4; Momentum = 0.9; ExecutionEnvironment = 'cpu'; options = trainingOptions(OptimSolver,... 'MiniBatchSize',MiniBatchSize,... 'MaxEpochs',MaxEpochs,... 'InitialLearnRate',InitialLearnRate,... 'ValidationData',imgsValidation,... 'ValidationFrequency',10,... 'ExecutionEnvironment',ExecutionEnvironment,... 'Momentum',Momentum);
Сохраните все параметры в структуре. Обучивший сеть и структура будут позже сохраненный в .mat
файл.
TrialParameter.new_conv10_WeightLearnRateFactor = new_conv10_WeightLearnRateFactor; TrialParameter.new_conv10_BiasLearnRateFactor = new_conv10_BiasLearnRateFactor; TrialParameter.OptimSolver = OptimSolver; TrialParameter.MiniBatchSize = MiniBatchSize; TrialParameter.MaxEpochs = MaxEpochs; TrialParameter.InitialLearnRate = InitialLearnRate; TrialParameter.Momentum = Momentum; TrialParameter.ExecutionEnvironment = ExecutionEnvironment;
Установите случайный seed на значение по умолчанию и обучите сеть. Сохраните обучившие сеть, испытательные параметры, учебное время выполнения, и отобразите datastore, содержащий изображения валидации. Учебный процесс обычно занимает 1-5 минут на настольном центральном процессоре. Если вы хотите использовать обученный CNN от предыдущего испытания, установите trial
к индексу того испытания и LoadModel
к true
.
LoadModel = false; if ~LoadModel rng default tic; trainedModel = trainNetwork(imgsTrain,lgraph,options); trainingTime = toc; fprintf('Total training time: %.2e sec\n',trainingTime); save(MatFile,'TrialParameter','trainedModel','trainingTime','imgsValidation'); else disp('Load ML model from the file') load(MatFile,'trainedModel','imgsValidation'); end
Initializing input data normalization. |======================================================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Validation | Mini-batch | Validation | Base Learning | | | | (hh:mm:ss) | Accuracy | Accuracy | Loss | Loss | Rate | |======================================================================================================================| | 1 | 1 | 00:00:02 | 26.67% | 25.00% | 4.1769 | 2.9883 | 1.0000e-04 | | 2 | 10 | 00:00:12 | 73.33% | 59.38% | 0.9877 | 1.1559 | 1.0000e-04 | | 3 | 20 | 00:00:21 | 60.00% | 56.25% | 0.9164 | 0.9182 | 1.0000e-04 | | 4 | 30 | 00:00:31 | 86.67% | 68.75% | 0.6698 | 0.7883 | 1.0000e-04 | | 5 | 40 | 00:00:40 | 66.67% | 68.75% | 0.9053 | 0.7489 | 1.0000e-04 | | 7 | 50 | 00:00:50 | 80.00% | 78.13% | 0.5422 | 0.6781 | 1.0000e-04 | | 8 | 60 | 00:00:59 | 100.00% | 81.25% | 0.4187 | 0.6124 | 1.0000e-04 | | 9 | 70 | 00:01:08 | 93.33% | 84.38% | 0.3561 | 0.5471 | 1.0000e-04 | | 10 | 80 | 00:01:18 | 73.33% | 84.38% | 0.5141 | 0.4765 | 1.0000e-04 | | 12 | 90 | 00:01:27 | 86.67% | 84.38% | 0.4220 | 0.4038 | 1.0000e-04 | | 13 | 100 | 00:01:36 | 93.33% | 90.63% | 0.1923 | 0.3476 | 1.0000e-04 | | 14 | 110 | 00:01:46 | 100.00% | 90.63% | 0.1472 | 0.3125 | 1.0000e-04 | | 15 | 120 | 00:01:55 | 100.00% | 93.75% | 0.0791 | 0.2777 | 1.0000e-04 | | 17 | 130 | 00:02:04 | 86.67% | 93.75% | 0.2486 | 0.2833 | 1.0000e-04 | | 18 | 140 | 00:02:14 | 100.00% | 93.75% | 0.0386 | 0.2288 | 1.0000e-04 | | 19 | 150 | 00:02:23 | 100.00% | 93.75% | 0.0487 | 0.2397 | 1.0000e-04 | | 20 | 160 | 00:02:32 | 100.00% | 93.75% | 0.0224 | 0.2041 | 1.0000e-04 | |======================================================================================================================|
Total training time: 1.61e+02 sec
Сохраните только обучивший сеть в отдельном .mat
файл. Этот файл будет использоваться исполняемым файлом CUDA.
ModelFile = fullfile(ResultDir,sprintf('SqueezeNet_Trial%d.mat',trial)); OutMatFile = fullfile('ecg_model.mat'); data = load(ModelFile,'trainedModel'); net = data.trainedModel; save(OutMatFile,'net');
Используйте обучивший сеть, чтобы предсказать классы для набора валидации.
[YPred, probs] = classify(trainedModel,imgsValidation); accuracy = mean(YPred==imgsValidation.Labels)
accuracy = 0.9375
Обобщите эффективность обучившего сеть на наборе валидации с графиком беспорядка. Отобразите точность и отзыв для каждого класса при помощи сводных данных строки и столбца. Сохраните фигуру. Таблица в нижней части графика беспорядка показывает значения точности. Таблица справа от графика беспорядка показывает значения отзыва.
figure confusionMat = confusionmat(imgsValidation.Labels,YPred); confusionchart(imgsValidation.Labels,YPred, ... 'Title',sprintf('Confusion Matrix on Validation (overall accuracy: %.4f)',accuracy),... 'ColumnSummary','column-normalized','RowSummary','row-normalized');
AccFigFile = fullfile(ResultDir,sprintf('SqueezeNet_ValidationAccuracy_Trial%d.fig',trial));
saveas(gcf,AccFigFile);
Отобразите размер обучившего сеть.
info = whos('trainedModel'); ModelMemSize = info.bytes/1024; fprintf('Trained network size: %g kB\n',ModelMemSize)
Trained network size: 2981.55 kB
Определите среднее время, оно берет сеть, чтобы классифицировать изображение.
NumTestForPredTime = 20;
TrialParameter.NumTestForPredTime = NumTestForPredTime;
fprintf('Test prediction time (number of tests: %d)... ',NumTestForPredTime)
Test prediction time (number of tests: 20)...
imageSize = trainedModel.Layers(1).InputSize; PredTime = zeros(NumTestForPredTime,1); for i = 1:NumTestForPredTime x = randn(imageSize); tic; [YPred, probs] = classify(trainedModel,x,'ExecutionEnvironment',ExecutionEnvironment); PredTime(i) = toc; end AvgPredTimePerImage = mean(PredTime); fprintf('Average prediction time (execution environment: %s): %.2e sec \n',... ExecutionEnvironment,AvgPredTimePerImage);
Average prediction time (execution environment: cpu): 2.94e-02 sec
Сохраните результаты.
if ~LoadModel save(MatFile,'accuracy','confusionMat','PredTime','ModelMemSize', ... 'AvgPredTimePerImage','-append') end
scalogram сигнала является входом "изображение" к глубокому CNN. Создайте функцию, cwt_ecg_jetson_ex
, это вычисляет scalogram входного сигнала и возвращает изображение в пользовательских заданных измерениях. Изображение использует jet(128)
палитра. %#codegen
директива в функции указывает, что функция предназначается для генерации кода. При использовании coder.gpu.kernelfun
прагма, генерация кода пытается сопоставить расчеты в cwt_ecg_jetson_ex
функционируйте к графическому процессору.
type cwt_ecg_jetson_ex.m
function im = cwt_ecg_jetson_ex(TimeSeriesSignal, ImgSize) %#codegen % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. coder.gpu.kernelfun(); %% Create Scalogram cfs = cwt(TimeSeriesSignal, 'morse', 1, 'VoicesPerOctave', 12); cfs = abs(cfs); %% Image generation cmapj128 = coder.load('cmapj128'); imx = ind2rgb_custom_ecg_jetson_ex(round(255*rescale(cfs))+1,cmapj128.cmapj128); % resize to proper size and convert to uint8 data type im = im2uint8(imresize(imx, ImgSize)); end
Создайте функцию точки входа, model_predict_ecg.m
, для генерации кода. Функция берет сигнал ECG, как введено и вызывает cwt_ecg_jetson_ex
функция, чтобы создать изображение scalogram. model_predict_ecg
функционируйте использует сеть, содержавшуюся в ecg_model.mat
файл, чтобы классифицировать сигнал ECG.
type model_predict_ecg.m
function PredClassProb = model_predict_ecg(TimeSeriesSignal) %#codegen % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. coder.gpu.kernelfun(); % parameters ModFile = 'ecg_model.mat'; % file that saves neural network model ImgSize = [227 227]; % input image size for the ML model % sanity check signal is a row vector of correct length assert(isequal(size(TimeSeriesSignal), [1 65536])) %% cwt transformation for the signal im = cwt_ecg_jetson_ex(TimeSeriesSignal, ImgSize); %% model prediction persistent model; if isempty(model) model = coder.loadDeepLearningNetwork(ModFile, 'mynet'); end PredClassProb = predict(model, im); end
Чтобы сгенерировать исполняемый файл CUDA, который может быть развернут на цели NVIDIA, создайте пользовательский основной файл (main_ecg_jetson_ex.cu
) и заголовочный файл (main_ecg_jetson_ex.h
). Можно сгенерировать пример основной файл и использование что как шаблон, чтобы переписать новые основные и заголовочные файлы. Для получения дополнительной информации смотрите GenerateExampleMain
свойство coder.CodeConfig
. Основной файл вызывает код, сгенерированный для функции точки входа MATLAB. Основной файл сначала читает сигнал ECG из текстового файла, передает данные функции точки входа и пишет результаты предсказания в текстовый файл (predClassProb.txt
). Чтобы максимизировать КПД расчета на графическом процессоре, исполняемый файл обрабатывает данные с одинарной точностью.
type main_ecg_jetson_ex.cu
// // File: main_ecg_jetson_ex.cu // // This file is only intended to support wavelet deep learning examples. // It may change or be removed in a future release. //*********************************************************************** // Include Files #include "rt_nonfinite.h" #include "model_predict_ecg.h" #include "main_ecg_jetson_ex.h" #include "model_predict_ecg_terminate.h" #include "model_predict_ecg_initialize.h" #include <stdio.h> #include <stdlib.h> #include <time.h> // Function Definitions /* Read data from a file*/ int readData_real32_T(const char * const file_in, real32_T data[65536]) { FILE* fp1 = fopen(file_in, "r"); if (fp1 == 0) { printf("ERROR: Unable to read data from %s\n", file_in); exit(0); } for(int i=0; i<65536; i++) { fscanf(fp1, "%f", &data[i]); } fclose(fp1); return 0; } /* Write data to a file*/ int writeData_real32_T(const char * const file_out, real32_T data[3]) { FILE* fp1 = fopen(file_out, "w"); if (fp1 == 0) { printf("ERROR: Unable to write data to %s\n", file_out); exit(0); } for(int i=0; i<3; i++) { fprintf(fp1, "%f\n", data[i]); } fclose(fp1); return 0; } // model predict function static void main_model_predict_ecg(const char * const file_in, const char * const file_out) { real32_T PredClassProb[3]; // real_T b[65536]; real32_T b[65536]; // readData_real_T(file_in, b); readData_real32_T(file_in, b); model_predict_ecg(b, PredClassProb); writeData_real32_T(file_out, PredClassProb); } // main function int32_T main(int32_T argc, const char * const argv[]) { const char * const file_out = "predClassProb.txt"; // Initialize the application. model_predict_ecg_initialize(); // Run prediction function main_model_predict_ecg(argv[1], file_out); // argv[1] = file_in // Terminate the application. model_predict_ecg_terminate(); return 0; }
type main_ecg_jetson_ex.h
// // File: main_ecg_jetson_ex.h // // This file is only intended to support wavelet deep learning examples. // It may change or be removed in a future release. // //*********************************************************************** #ifndef MAIN_H #define MAIN_H // Include Files #include <stddef.h> #include <stdlib.h> #include "rtwtypes.h" #include "model_predict_ecg_types.h" // Function Declarations extern int32_T main(int32_T argc, const char * const argv[]); #endif // // File trailer for main_ecg_jetson_ex.h // // [EOF] //
Чтобы создать исполняемый файл, который может быть развернут на целевом устройстве, устанавливает CodeGenMode
равняйтесь 1. Если вы хотите создать исполняемый файл, который запускается локально и связывает удаленно с целевым устройством, установите CodeGenMode
равняйтесь 2.
main
функция считывает данные из текстового файла, заданного signalFile
и пишет результаты классификации в resultFile
. Установите ExampleIndex
выбрать представительный сигнал ECG. Вы будете использовать этот сигнал протестировать исполняемый файл против classify
функция. Jetson_BuildDir
задает директорию для выполнения удаленного процесса сборки на цели. Если заданный каталог сборки не существует на цели, то программное обеспечение создает директорию с именем.
CodeGenMode = 1; signalFile = 'signalData.txt'; resultFile = 'predClassProb.txt'; % consistent with "main_ecg_jetson_ex.cu" Jetson_BuildDir = '~/projectECG'; ExampleIndex = 1; % 1,4: type ARR; 2,5: type CHF; 3,6: type NSR Function_to_Gen = 'model_predict_ecg'; ModFile = 'ecg_model.mat'; % file that saves neural network model; consistent with "main_ecg_jetson_ex.cu" ImgSize = [227 227]; % input image size for the ML model switch ExampleIndex case 1 % ARR 7 SampleSignalIdx = 7; case 2 % CHF 97 SampleSignalIdx = 97; case 3 % NSR 132 SampleSignalIdx = 132; case 4 % ARR 31 SampleSignalIdx = 31; case 5 % CHF 101 SampleSignalIdx = 101; case 6 % NSR 131 SampleSignalIdx = 131; end signal_data = один (ECGData.Data (SampleSignalIdx, :)); ECGtype = ECGData.Labels {SampleSignalIdx};
Чтобы связаться с оборудованием NVIDIA, вы создаете живой аппаратный объект связи использование jetson
функция. Необходимо знать, что имя хоста или IP-адрес, имя пользователя и пароль требуемой платы создают живой аппаратный объект связи.
Создайте живой аппаратный объект связи для оборудования Джетсона. Во время оборудования выполняются живая проверка создания объекта оборудования, установка сервера IO и сбор периферийной информации о цели. Эта информация отображена в Командном окне.
hwobj = jetson('gpucoder-nano-2','ubuntu','ubuntu');
Checking for CUDA availability on the Target... Checking for 'nvcc' in the target system path... Checking for cuDNN library availability on the Target... Checking for TensorRT library availability on the Target... Checking for prerequisite libraries is complete. Gathering hardware details... Checking for third-party library availability on the Target...
Gathering hardware details is complete. Board name : NVIDIA Jetson TX1 CUDA Version : 10.0 cuDNN Version : 7.3 TensorRT Version : 5.0 GStreamer Version : 1.14.5 V4L2 Version : 1.14.2-1 SDL Version : 1.2 Available Webcams : Available GPUs : NVIDIA Tegra X1
Используйте coder.checkGpuInstall
функционируйте и проверьте, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно на оборудовании.
envCfg = coder.gpuEnvConfig('jetson'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.HardwareObject = hwobj; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg)
ans = struct with fields:
gpu: 1
cuda: 1
cudnn: 1
tensorrt: 0
basiccodegen: 0
basiccodeexec: 0
deepcodegen: 1
deepcodeexec: 0
tensorrtdatatype: 0
profiling: 0
Создайте объект настройки графического процессора кода, необходимый для компиляции. Используйте coder.hardware
функция, чтобы создать настройку возражает для платформы Джетсона и присвоить ее Hardware
свойство объекта cfg
настройки кода. Используйте
'NVIDIA Jetson'
для Jetson TX1 или плат TX2. Пользовательский основной файл является оберткой, которая вызывает функцию точки входа в сгенерированном коде. Пользовательский файл требуется для развернутого исполняемого файла.
Используйте coder.DeepLearningConfig
функция, чтобы создать CuDNN
объект настройки глубокого обучения и присвоение это к DeepLearningConfig
свойство объекта настройки графического процессора кода. Генератор кода использует в своих интересах библиотеку глубокой нейронной сети NVIDIA® CUDA® (cuDNN) для NVIDIA графические процессоры. cuDNN является ускоренной графическим процессором библиотекой примитивов для глубоких нейронных сетей.
if CodeGenMode == 1 cfg = coder.gpuConfig('exe'); cfg.Hardware = coder.hardware('NVIDIA Jetson'); cfg.Hardware.BuildDir = Jetson_BuildDir; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); cfg.CustomSource = fullfile('main_ecg_jetson_ex.cu'); elseif CodeGenMode == 2 cfg = coder.gpuConfig('lib'); cfg.VerificationMode = 'PIL'; cfg.Hardware = coder.hardware('NVIDIA Jetson'); cfg.Hardware.BuildDir = Jetson_BuildDir; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); end
Чтобы сгенерировать код CUDA, используйте codegen
функционируйте и передайте настройку графического процессора кода наряду с размером и типом входа для model_predict_ecg
функция точки входа. После того, как генерация кода на хосте завершена, сгенерированные файлы скопированы и основаны на цели.
codegen('-config ',cfg,Function_to_Gen,'-args',{signal_data},'-report');
Code generation successful: View report
Если вы скомпилировали исполняемый файл, который будет развернут на цели, запишите сигнал ECG в качестве примера в текстовый файл. Используйте putFile()
функция оборудования возражает, чтобы поместить текстовый файл в цель. workspaceDir
свойство содержит путь к codegen
папка на цели.
if CodeGenMode == 1 fid = fopen(signalFile,'w'); for i = 1:length(signal_data) fprintf(fid,'%f\n',signal_data(i)); end fclose(fid); hwobj.putFile(signalFile,hwobj.workspaceDir); end
Запустите исполняемый файл.
При выполнении развернутого исполняемого файла удалите предыдущий файл результата, если это существует. Используйте runApplication()
функционируйте, чтобы запустить исполняемый файл на целевом компьютере, и затем getFile()
функция, чтобы получить результаты. Поскольку результаты не могут сразу существовать после runApplication()
вызов функции возвращается, и допускать коммуникационные задержки, назначить максимальное время для выборки результатов к 90 секундам. Используйте evalc
функция, чтобы подавить командную строку выход.
if CodeGenMode == 1 % run deployed executable maxFetchTime = 90; resultFile_hw = fullfile(hwobj.workspaceDir,resultFile); if ispc resultFile_hw = strrep(resultFile_hw,'\','/'); end ta = tic; hwobj.deleteFile(resultFile_hw) hwobj.runApplication(Function_to_Gen,signalFile); tf = tic; success = false; while toc(tf) < maxFetchTime try evalc('hwobj.getFile(resultFile_hw)'); success = true; catch ME end if success break end end fprintf('Fetch time = %.3e sec\n',toc(tf)); assert(success,'Unable to fetch the prediction') PredClassProb = readmatrix(resultFile); PredTime = toc(ta); elseif CodeGenMode == 2 % run PIL executable ta = tic; eval(sprintf('PredClassProb = %s_pil(signal_data);',Function_to_Gen)); PredTime = toc(ta); eval(sprintf('clear %s_pil;',Function_to_Gen)); % terminate PIL execution end
### Launching the executable on the target... Executable launched successfully with process ID 5672. Displaying the simple runtime log for the executable... Note: For the complete log, run the following command in the MATLAB command window: system(hwobj,'cat /home/ubuntu/projectECG/MATLAB_ws/R2021a/C/Users/pkostele/OneDrive_-_MathWorks/Documents/MATLAB/Examples/deeplearning_shared-ex54874305/model_predict_ecg.log')
Fetch time = 9.743e+00 sec
Используйте classify
функция, чтобы предсказать класс помечает для сигнала в качестве примера.
ModData = load(ModFile,'net');
im = cwt_ecg_jetson_ex(signal_data,ImgSize);
[ModPred, ModPredProb] = classify(ModData.net,im);
PredCat = categories(ModPred)';
Сравнение результатов.
PredTableJetson = array2table(PredClassProb(:)','VariableNames',matlab.lang.makeValidName(PredCat)); fprintf('tPred = %.3e sec\nExample ECG Type: %s\n',PredTime,ECGtype)
tPred = 1.288e+01 sec Example ECG Type: ARR
disp(PredTableJetson)
ARR CHF NSR _______ ________ ________ 0.99872 0.001131 0.000153
PredTableMATLAB = array2table(ModPredProb(:)','VariableNames',matlab.lang.makeValidName(PredCat));
disp(PredTableMATLAB)
ARR CHF NSR _______ _________ __________ 0.99872 0.0011298 0.00015316
Закройте аппаратную связь.
clear hwobj
В этом примере показано, как создать и развернуть исполняемый файл CUDA, который использует CNN, чтобы классифицировать сигналы ECG. У вас также есть опция, чтобы создать исполняемый файл запуски локально и подключения к удаленной цели. Полный рабочий процесс представлен в этом примере. После того, как данные загружаются, CWT используется, чтобы извлечь функции из сигналов ECG. Затем SqueezeNet переобучен, чтобы классифицировать сигналы на основе их scalograms. Две пользовательских функции созданы и скомпилированы на целевом устройстве NVIDIA. Результаты исполняемого файла по сравнению с MATLAB.
Baim, D. S. В. С. Колуччи, Э. С. Монрэд, Х. С. Смит, Р. Ф. Райт, А. Лэноу, Д. Ф. Готье, Б. Дж. Рэнсил, В. Гроссман и Э. Бронвалд. "Выживание пациентов с тяжелой застойной сердечной недостаточностью отнеслось с устным milrinone". Журнал американского Колледжа Кардиологии. Издание 7, Номер 3, 1986, стр 661–670.
Голдбергер А. Л., Л. А. Н. Амарал, L. Стекло, Дж. М. Гаусдорф, P. Ch. Иванов, Р. Г. Марк, Дж. Э. Митус, Г. Б. Муди, C.-K. Пенг и Х. Э. Стэнли. "PhysioBank, PhysioToolkit и PhysioNet: Компоненты Нового Ресурса Исследования для Комплексных Физиологических Сигналов". Циркуляция. Издание 101, Номер 23: e215–e220. [Циркуляция Электронные Страницы; http://circ.ahajournals.org/content/101/23/e215.full
]; 2000 (13 июня). doi: 10.1161/01. CIR.101.23.e215.
Капризный, G. B. и Р. Г. Марк. "Удар Базы данных Аритмии MIT-BIH". Разработка IEEE в Журнале Медицины и Биологии. Издание 20. Номер 3, мочь-июнь 2001, стр 45–50. (PMID: 11446209)
helperCreateECGDirectories
function helperCreateECGDirectories(ECGData,parentFolder,dataFolder) % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. rootFolder = parentFolder; localFolder = dataFolder; mkdir(fullfile(rootFolder,localFolder)) folderLabels = unique(ECGData.Labels); for i = 1:numel(folderLabels) mkdir(fullfile(rootFolder,localFolder,char(folderLabels(i)))); end end
helperPlotReps
function helperPlotReps(ECGData) % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. folderLabels = unique(ECGData.Labels); for k=1:3 ecgType = folderLabels{k}; ind = find(ismember(ECGData.Labels,ecgType)); subplot(3,1,k) plot(ECGData.Data(ind(1),1:1000)); grid on title(ecgType) end end
helperCreateRGBfromTF
function helperCreateRGBfromTF(ECGData,parentFolder, childFolder) % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. imageRoot = fullfile(parentFolder,childFolder); data = ECGData.Data; labels = ECGData.Labels; [~,signalLength] = size(data); fb = cwtfilterbank('SignalLength',signalLength,'VoicesPerOctave',12); r = size(data,1); for ii = 1:r cfs = abs(fb.wt(data(ii,:))); im = ind2rgb(im2uint8(rescale(cfs)),jet(128)); imgLoc = fullfile(imageRoot,char(labels(ii))); imFileName = strcat(char(labels(ii)),'_',num2str(ii),'.jpg'); imwrite(imresize(im,[227 227]),fullfile(imgLoc,imFileName)); end end