В этом примере показано, как генерировать и развертывать исполняемый файл CUDA ®, который выполняет классификацию модуляции, используя признаки, извлеченные непрерывным вейвлет-преобразованием (CWT), и предварительно обученную сверточную нейронную сеть (CNN).
Классификация модуляции является важной функцией для интеллектуального приемника. Классификация модуляции имеет множество применений, таких как когнитивный радар и программно-определяемое радио. Обычно для идентификации этих сигналов и их классификации по типу модуляции необходимо определить значимые признаки и ввести их в классификатор. Хотя эта процедура эффективна, она может потребовать больших усилий и знаний области для получения точной классификации. В этом примере исследуется структура для автоматического извлечения частотно-временных характеристик из сигналов и выполнения классификации сигналов с использованием сети глубокого обучения.
CWT используется для создания частотно-временных представлений комплексных сигналов. Нет необходимости разделять сигнал на I и Q каналы. Вы используете представления, называемые скалограммами, и используете существующий CNN, переобучая сеть для классификации сигналов. Это использование существующих нейронных сетей называется обучением передаче.
В этом примере мы адаптируем SqueeEcNet, CNN, предварительно подготовленный для распознавания изображения, для классификации типа модуляции каждого кадра на основе скалограммы. Затем создается исполняемый файл CUDA, который генерирует скалограмму входного сигнала. Мы разворачиваем исполняемый и переподготовленный CNN на целевое устройство, позволяя классифицировать сигналы в реальном времени.
По умолчанию в этом примере данные обучения и обученная сеть загружаются в одном ZIP-файле. wavelet_modulation_classification.zip. Размер ZIP-файла составляет примерно 1,2 гигабайта. Имеется возможность создания данных обучения и обучения сети. Однако обе эти операции требуют много времени. В зависимости от оборудования компьютера генерация данных обучения может занять один час или более. Обучение сети может занять 90 минут или больше.
Укажите пять типов цифровой и три аналоговых модуляции:
Двоичная фазовая манипуляция (BPSK)
16-арная квадратурная амплитудная модуляция (16-QAM)
4-мерная амплитудно-импульсная модуляция (PAM4)
Гауссова частотная манипуляция (GFSK)
Непрерывная фазовая частотная манипуляция (CPFSK)
Широковещательное FM (B-FM)
Амплитудная модуляция с двойной боковой полосой (DSB-AM)
Модуляция амплитуды одной боковой полосы (SSB-AM)
modTypesList = ["BPSK", ... "16QAM", "PAM4", "GFSK", "CPFSK", ... "B-FM", "DSB-AM", "SSB-AM"]; modulationTypes = categorical(modTypesList);
Укажите родительский каталог parentDir и имя каталога dataDir который будет внутри parentDir. Необходимо иметь разрешение на запись в parentDir. ZIP-файл загружается в parentDir. Поскольку в примере данные загружаются по умолчанию, dataDir должно быть 'wavelet_modulation_classification'. Справочник dataDirectory содержит данные обучения, используемые в этом примере. ResultDir указывает имя каталога, который будет содержать обученную сеть. ResultDir находится в том же каталоге, что и в этом примере, и будет создан для вас при необходимости.
parentDir = tempdir; dataDir = 'wavelet_modulation_classification'; dataDirectory = fullfile(parentDir,dataDir); ResultDir = 'trainedNetworks';
Укажите параметры данных обучения. Обучающие данные состоят из 5000 кадров для каждого типа модуляции. Каждый кадр имеет длину 1024 выборки и частоту дискретизации 200 кГц. Для типов цифровой модуляции восемь выборок представляют символ. Предположим, центральная частота 902 МГц и 100 МГц для типов цифровой и аналоговой модуляции соответственно.
numFramesPerModType = 5000; frameLength = 1024; fs = 200e3;
Загрузите и распакуйте обучающие данные и обучаемую сеть. dataDirectory содержит папки с именами каждого типа модуляции. Данные обучения находятся в этих папках. Обученная сеть, waveletModClassNet.mat, находится в ResultDir.
Если вы не хотите загружать данные, установите downloadData в значение false. Вспомогательная функция helperGenerateModWaveforms генерирует кадры и сохраняет их в dataDirectory. Для воспроизводимости задайте случайное начальное число.
downloadData =true; if downloadData dataURL = 'https://ssd.mathworks.com/supportfiles/wavelet/waveletModulation/wavelet_modulation_classification.zip'; zipFile = fullfile(parentDir,'wavelet_modulation_classification.zip'); tic websave(zipFile,dataURL); disp(['Download time: ',num2str(toc),' seconds']) tic unzip(zipFile,parentDir); disp(['Unzipping time: ',num2str(toc),' seconds']) trainedNetworkDir = fullfile(parentDir,dataDir,'results'); status = copyfile(trainedNetworkDir,ResultDir); else rng(1235) helperGenerateModWaveforms(dataDirectory,modulationTypes,numFramesPerModType,frameLength,fs); end
Download time: 38.2209 seconds
Unzipping time: 7.9005 seconds
Другой пример, классификация модуляции с глубоким обучением (Communications Toolbox), выполняет классификацию модуляции нескольких различных типов модуляции с использованием Communications Toolbox™. Вспомогательная функция helperGenerateModWaveforms генерирует и расширяет подмножество типов модуляции, используемых в этом примере. Подробное описание рабочего процесса, необходимого для классификации цифровой и аналоговой модуляции, а также методов, используемых для создания этих сигналов, см. в примере ссылки.
Постройте график амплитуды действительной и мнимой частей представителя каждого типа модуляции. Вспомогательная функция helperModClassPlotTimeDomain2 делает это.
helperModClassPlotTimeDomain2(dataDirectory,modulationTypes,fs)

Создайте частотно-временные представления форм сигнала. Эти представления называются скалограммами. Скалограмма - это абсолютное значение коэффициентов CWT сигнала. Чтобы создать скалограммы, предварительно вычислите банк фильтров CWT. Предварительное вычисление набора фильтров CWT является предпочтительным способом при получении CWT многих сигналов с использованием одних и тех же параметров.
Перед генерацией всех скалограмм постройте график скалограмм из представления каждого типа модуляции. Создание банка фильтров CWT с помощью cwtfilterbank для сигнала с 1024 выборками и используйте набор фильтров, чтобы взять CWT сигнала. Поскольку сигнал имеет комплексное значение, CWT является 3-D массивом. Первая страница является CWT для положительных шкал (аналитическая часть или компонент против часовой стрелки), а вторая страница является CWT для отрицательных шкал (антианалитическая часть или компонент по часовой стрелке). Чтобы создать скалограммы, возьмите абсолютное значение конкатенации каждой страницы. Вспомогательная функция helperPlotScalogramsMod2 делает это.
helperPlotScalogramsMod2(dataDirectory,modulationTypes,frameLength,fs)

Если были загружены данные обучения и обученная сеть, перейдите к разделу Разделение на данные обучения, тестирования и проверки. В противном случае создайте все скалограммы как изображения RGB и запишите их в соответствующую подкаталогу в dataDirectory. Вспомогательная функция helperGenerateCWTfiles2 делает это. Чтобы быть совместимым с архитектурой SqueezeNet, каждое изображение RGB - множество размера 227 на 227 на 3.
if ~downloadData helperGenerateCWTfiles2(dataDirectory,modulationTypes,frameLength,fs) end
Загрузите изображения скалограммы как хранилище данных изображения. imageDatastore функция автоматически помечает изображения на основе имен папок и сохраняет данные как объект ImageDatastore. Хранилище данных изображения позволяет хранить большие данные изображения, включая данные, которые не помещаются в память, и эффективно считывать пакеты изображений во время обучения CNN.
folders = fullfile(dataDirectory,string(modulationTypes)); imds = imageDatastore(folders,... 'FileExtensions','.jpg','LabelSource','foldernames');
Случайное разделение изображений на три группы, где 80% используются для обучения, 10% используются для проверки, а 10% используются для тестирования. Мы используем кадры обучения и проверки на этапе обучения сети. Для воспроизводимости мы задаем случайное начальное число.
rng(1235) [imdsTrain,imdsTest,imdsValidation] = splitEachLabel(imds,0.8,0.1);
При необходимости создайте каталог, который будет содержать обученную сеть. При загрузке данных каталог, указанный в ResultDir уже существует, и файл waveletModClassNet.mat в этом каталоге содержится обученная сеть.
if ~exist(ResultDir,'dir') mkdir(ResultDir) end MatFile = fullfile(ResultDir,'waveletModClassNet.mat');
Если ZIP-файл загружен, загрузите обученную сеть и перейдите к разделу Оценка сети. В противном случае необходимо переобучить SqueeeNet.
if downloadData disp('Load ML model from the file') load(MatFile,'trainedNet','imdsValidation') end
Load ML model from the file
SqueeeNet - это предварительно обученный CNN, который может классифицировать изображения на 1000 категорий объектов. Необходимо перепрофилировать SqueeEcnet для классификации форм сигналов по типу модуляции. Перед переподготовкой необходимо изменить несколько сетевых уровней и задать различные варианты обучения. После завершения переподготовки вы сохраняете CNN в .mat файл. Исполняемый файл CUDA использует файл .mat.
Загрузите SqueeEnet и извлеките график слоев из сети. Проверьте последние пять слоев графика.
net = squeezenet; lgraph = layerGraph(net); 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
Последний обучаемый уровень в SqueeExNet - сверточный уровень 1 на 1, 'conv10'. Замените слой новым сверточным слоем с числом фильтров, равным числу типов модуляции.
numClasses = numel(modulationTypes); newLearnableLayer = convolution2dLayer(1,numClasses,'Name','new_conv10'); lgraph = replaceLayer(lgraph,lgraph.Layers(end-4).Name,newLearnableLayer);
Замените классификационный слой новым без меток классов. Классы вывода уровня устанавливаются автоматически во время обучения. Просмотрите последние пять слоев для подтверждения изменений.
newClassLayer = classificationLayer('Name','new_classoutput'); lgraph = replaceLayer(lgraph,lgraph.Layers(end).Name,newClassLayer); lgraph.Layers(end-4:end)
ans =
5×1 Layer array with layers:
1 'new_conv10' Convolution 8 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
Обучение нейронной сети - это итеративный процесс, который включает минимизацию функции потерь. Используйте trainingOptions (Deep Learning Toolbox) используется для определения параметров процесса обучения, обеспечивающих хорошую производительность сети. См. раздел trainingOptions для описания каждого варианта.
OptimSolver = 'adam'; MiniBatchSize = 50; MaxEpochs = 20; InitialLearnRate = 1e-4; Shuffle = 'every-epoch'; options = trainingOptions(OptimSolver, ... 'MiniBatchSize',MiniBatchSize, ... 'MaxEpochs',MaxEpochs, ... 'InitialLearnRate',InitialLearnRate, ... 'Shuffle',Shuffle, ... 'Verbose',false, ... 'Plots','training-progress',... 'ValidationData',imdsValidation);
Сохраните все параметры в структуре. Обученная сеть и структура будут сохранены в .mat файл.
TrialParameter.OptimSolver = OptimSolver; TrialParameter.MiniBatchSize = MiniBatchSize; TrialParameter.MaxEpochs = MaxEpochs; TrialParameter.InitialLearnRate = InitialLearnRate;
Установите случайное начальное значение по умолчанию и используйте trainNetwork (Deep Learning Toolbox) используется для обучения CNN. Сохраните обученную сеть, параметры пробной версии, время выполнения обучения и хранилище данных образа, содержащее изображения проверки. Из-за большого размера набора данных процесс займет много минут. По умолчанию обучение выполняется на графическом процессоре, если он доступен. Для использования графического процессора требуется Toolbox™ параллельных вычислений. Сведения о том, какие графические процессоры поддерживаются, см. в разделе Поддержка графических процессоров по выпуску (Панель инструментов параллельных вычислений). В противном случае обучение выполняется на CPU. Графики точности обучения на рисунке показывают ход обучения сети по всем итерациям.
if ~downloadData rng default tic; trainedNet = trainNetwork(imdsTrain,lgraph,options); trainingTime = toc; fprintf('Total training time: %.2e sec\n',trainingTime); save(MatFile,'TrialParameter','trainedNet','trainingTime','imdsValidation'); end
Загрузить .mat файл, содержащий обученную сеть и параметры обучения. Сохранение только обученной сети в отдельной .mat файл. Этот файл будет использоваться исполняемым файлом CUDA.
OutMatFile = 'mdwv_model.mat'; data = load(MatFile,'trainedNet'); trainedNet = data.trainedNet; save(OutMatFile,'trainedNet');
Оценка обученной сети путем получения точности классификации для тестовых кадров.
[YPred,probs] = classify(trainedNet,imdsTest); imdsTestLabels = imdsTest.Labels; modAccuracy = sum(YPred==imdsTestLabels)/numel(imdsTestLabels)*100
modAccuracy = 96.2250
Обобщите производительность обученной сети на тестовых кадрах с помощью таблицы путаницы. Отображение точности и отзыва для каждого класса с помощью сводок столбцов и строк. Сохраните фигуру. В таблице внизу таблицы путаницы показаны значения точности. В таблице справа от таблицы путаницы показаны значения отзыва.
figure('Units','normalized','Position',[0.2 0.2 0.5 0.5]); ccDCNN = confusionchart(imdsTestLabels,YPred); ccDCNN.Title = ['Test Accuracy: ',num2str(modAccuracy)]; ccDCNN.ColumnSummary = 'column-normalized'; ccDCNN.RowSummary = 'row-normalized'; AccFigFile = fullfile(ResultDir,'Network_ValidationAccuracy.fig'); saveas(gcf,AccFigFile);

Отображение размера обучаемой сети.
info = whos('trainedNet'); ModelMemSize = info.bytes/1024; fprintf('Trained network size: %g kB\n',ModelMemSize)
Trained network size: 2992.95 kB
Определите среднее время, необходимое сети для классификации изображения.
NumTestForPredTime = 20;
TrialParameter.NumTestForPredTime = NumTestForPredTime;
fprintf('Test prediction time (number of tests: %d)... ',NumTestForPredTime)Test prediction time (number of tests: 20)...
imageSize = trainedNet.Layers(1).InputSize; PredTime = zeros(NumTestForPredTime,1); for i = 1:NumTestForPredTime x = randn(imageSize); tic; [YPred, probs] = classify(trainedNet,x); PredTime(i) = toc; end AvgPredTimePerImage = mean(PredTime); fprintf('Average prediction time: %.2e sec \n',AvgPredTimePerImage);
Average prediction time: 8.41e-02 sec
Сохраните результаты.
if ~downloadData save(MatFile,'modAccuracy','ccDCNN','PredTime','ModelMemSize', ... 'AvgPredTimePerImage','-append') end
Скалограмма сигнала является входным «изображением» для глубокого CNN. Создайте функцию, cwtModType, которая вычисляет скалограмму сигнала со сложными значениями и возвращает изображение с заданными пользователем размерами. Изображение использует jet(128) colormap. В целях генерации кода, рассматривайте входной сигнал как матрицу 1024 на 2, где первый столбец содержит реальные части выборок формы сигнала, а второй столбец содержит воображаемые части. %#codegen директива в функции указывает, что функция предназначена для генерации кода. При использовании coder.gpu.kernelfun pragma, генерация кода пытается отобразить вычисления в cwtModType функции графическому процессору.
type cwtModTypefunction im = cwtModType(inputSig, 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.kernel; % Input is a 1024x2 matrix, convert it into complex form (a + 1*ib) cinputSig = convertToComplex(inputSig); % Wavelet time-frequency representations [wt, ~, ~] = cwt(cinputSig, 'morse', 1, 'VoicesPerOctave', 48); % Generate Wavelet Time-Frequency Coefficients from Signal cfs = abs([wt(:,:,1); wt(:,:,2)]); % Concatenate the clockwise and counterclockwise representation % Image generation im = generateImagefromCWTCoeff(cfs, imgSize); end
Создайте функцию точки входа, modelPredictModType, для генерации кода. Функция принимает комплексный сигнал, заданный как матрица 1024 на 2, в качестве входного сигнала и вызывает cwtModType для создания изображения скалограммы. modelPredictModType использует сеть, содержащуюся в mdwv_model файл для классификации формы сигнала.
type modelPredictModTypefunction predClassProb = modelPredictModType(inputSig) %#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();
% input signal size is 1024-by-2
% parameters
ModelFile = 'mdwv_model.mat'; % file that saves the neural network model
imSize = [227 227]; % Size of the input image for the deep learning network
%Function to converts signal to wavelet time-frequency image
im = cwtModType(inputSig, imSize);
%Load the trained deep learning network
persistent model;
if isempty(model)
model = coder.loadDeepLearningNetwork(ModelFile, 'mynet');
end
% Predict the Signal Modulation
predClassProb = model.predict(im);
end
Чтобы создать исполняемый файл CUDA, который можно развернуть на целевом объекте NVIDIA, создайте пользовательский основной файл (main_mod_jetson.cu) и файл заголовка (main_mod_jetson.h). Можно создать пример основного файла и использовать его в качестве шаблона для перезаписи нового основного файла и файла заголовка. Дополнительные сведения см. в разделе GenerateExampleMain имущество coder.CodeConfig (Кодер MATLAB). Основной файл вызывает код, созданный для функции точки входа MATLAB. Основной файл сначала считывает сигнал формы сигнала из текстового файла, передает данные в функцию точки входа и записывает результаты прогнозирования в текстовый файл (predClassProb.txt). Чтобы максимизировать эффективность вычислений на GPU, исполняемый файл обрабатывает данные с одной точностью.
Если требуется просмотреть содержимое основного и верхнего колонтитулов, установите viewFiles к true.
viewFiles =false; if viewFiles type main_mod_jetson.cu end if viewFiles type main_mod_jetson.h end
Для взаимодействия с аппаратным обеспечением NVIDIA необходимо создать объект подключения аппаратного обеспечения в реальном времени с помощью jetson функция. Для создания объекта аппаратного подключения в реальном времени необходимо знать имя хоста или IP-адрес, имя пользователя и пароль целевой платы.
Создайте объект аппаратного подключения для оборудования Jetson. При проверке создания аппаратных объектов в режиме реального времени выполняется установка сервера ввода-вывода и сбор периферийной информации о цели. Эта информация отображается в окне команд.
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, NVIDIA Jetson Nano 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 (GPU Coder) и убедитесь, что компиляторы и библиотеки, необходимые для выполнения этого примера, правильно настроены на оборудовании.
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
Чтобы создать исполняемый файл, который можно развернуть на целевом устройстве, установите CodeGenMode равно 1. Если требуется создать исполняемый файл, который выполняется локально и удаленно подключается к целевому устройству, установите CodeGenMode равно 2. Jetson_BuildDir указывает каталог для выполнения удаленного процесса построения на конечном объекте. Если указанный каталог построения не существует на конечном объекте, то программное обеспечение создает каталог с заданным именем.
CodeGenMode =1; Function_to_Gen = 'modelPredictModType'; ModFile = 'mdwv_model.mat'; % file that saves neural network model; consistent with "main_mod_jetson.cu" ImgSize = [227 227]; % input image size for the ML model Jetson_BuildDir = '~/projectMDWV';
Создайте объект конфигурации кода графического процессора, необходимый для компиляции. Используйте coder.hardware чтобы создать объект конфигурации для платформы Jetson и назначить его Hardware свойство объекта конфигурации кода cfg. Использовать 'NVIDIA Jetson' для TX1 Jetson или TX2 плат. Пользовательский основной файл - это оболочка, вызывающая функцию точки входа в сгенерированном коде. Пользовательский файл необходим для развернутого исполняемого файла.
Используйте coder.DeepLearningConfig (Кодер графического процессора) для создания CuDNN глубокий объект конфигурации обучения и назначить его DeepLearningConfig свойства объекта конфигурации кода графического процессора. Генератор кода использует преимущества библиотеки глубоких нейронных сетей (cuDNN) NVIDIA ® CUDA ® для графических процессоров NVIDIA. cuDNN - GPU-ускоренная библиотека примитивов для глубоких нейронных сетей.
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 = 'main_mod_jetson.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 и передать конфигурацию кода GPU вместе с размером и типом входа для modelPredictModType функция точки входа. После завершения создания кода на хосте созданные файлы копируются и создаются на целевом компьютере.
codegen('-config ',cfg,Function_to_Gen,'-args',{single(ones(1024,2))},'-report');
Code generation successful: View report
Исполняемый CUDA выполняет классификацию модуляции путем генерации скалограммы комплексного сигнала и применения к скалограмме переученного CNN. Выберите форму сигнала, сформированную в начале этого примера. Из 5000 кадров каждого типа модуляции выберите один из первых 50 кадров, сгенерированных путем установки waveNumber. Постройте график реальной и мнимой частей кадра, а также созданной из него скалограммы. Использовать функцию помощника helperPlotWaveFormAndScalogram. Исходный код для этой вспомогательной функции можно найти в разделе «Вспомогательные функции» в конце этого примера.
waveForm =modTypesList(6); waveNumber =
1; signal_data = helperPlotWaveFormAndScalogram(dataDirectory,waveForm,waveNumber);

При компиляции исполняемого файла, подлежащего развертыванию, запишите выбранный сигнал в текстовый файл signalFile. Используйте putFile() функция аппаратного объекта для размещения текстового файла на целевом объекте. workspaceDir содержит путь к codegen папка на целевом объекте. main функция в исполняемом файле считывает данные из текстового файла, указанного signalFile и записывает результаты классификации в resultFile.
signalFile = 'signalData.txt'; resultFile = 'predClassProb.txt'; % consistent with "main_mod_jetson.cu" if CodeGenMode == 1 fid = fopen(signalFile,'w'); for i = 1:length(signal_data) fprintf(fid,'%f\n',real(signal_data(i))); end for i = 1:length(signal_data) fprintf(fid,'%f\n',imag(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) evalc('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 sigData = [real(signal_data)';imag(signal_data)']'; ta = tic; eval(sprintf('PredClassProb = %s_pil(single(sigData));',Function_to_Gen)); PredTime = toc(ta); eval(sprintf('clear %s_pil;',Function_to_Gen)); % terminate PIL execution end
Fetch time = 4.852e+00 sec
resultFile содержит результаты классификации. Для каждого возможного типа модуляции сеть назначила вероятность того, что сигнал был такого типа. Отображение выбранного типа модуляции. Использовать функцию помощника helperPredViz для отображения результатов классификации.
if CodeGenMode == 1 helperPredViz % read fetched prediction results file elseif CodeGenMode == 2 helperPredVizPil(PredClassProb) % read workspace variable end

fprintf('Expected Waveform: %s\n',waveForm);Expected Waveform: B-FM
В этом примере показано, как создать и развернуть исполняемый файл CUDA, использующий CNN для выполнения классификации модуляции. Также можно создать исполняемый файл, выполняемый локально и подключенный к удаленному целевому объекту. В этом примере представлен полный рабочий процесс. После загрузки данных CWT используется для извлечения признаков из форм сигнала. Затем SqueeExNet перестраивается для классификации сигналов на основе их скалограмм. На целевом устройстве NVIDIA создаются и компилируются две определяемые пользователем функции. Результаты исполняемого файла сравниваются с MATLAB.
helperPlotWaveFormAndScalogram
function sig = helperPlotWaveFormAndScalogram(dataDirectory,wvType,wvNum) % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. waveFileName = sprintf('frame%s%05d.mat',wvType,wvNum); load(fullfile(dataDirectory,wvType,waveFileName),'frame'); sig = frame; cfs = cwt(sig,'morse',1,'VoicesPerOctave',48); cfs = abs([cfs(:,:,1);cfs(:,:,2)]); subplot(211) plot(real(frame)) hold on plot(imag(frame)) hold off axis tight legend('Real','Imag') str = sprintf('Waveform: %s / Frame: %d\n Signal',wvType,wvNum); title(str) subplot(212) imagesc(cfs) title('Time-Frequency Representation') %set(gca,'xtick',[]); set(gca,'ytick',[]); end
helperPredVizPil
function helperPredVizPil(PredClassProb) % This function is only intended to support wavelet deep learning examples. % It may change or be removed in a future release. classNames = {'16QAM';'B-FM';'BPSK';'CPFSK';'DSB-AM';'GFSK';'PAM4';'SSB-AM'}; figure bar(PredClassProb) set(gca, 'XTickLabel' , classNames) xlabel('Class Labels') ylabel('Probability') title('Modulation Classification Output') axis tight grid on end