Классификация модуляций Используя анализ вейвлета NVIDIA Джетсон

В этом примере показано, как сгенерировать и развернуть исполняемый файл CUDA®, который выполняет функции использующего классификации модуляций, извлеченные непрерывным вейвлетом преобразовывает (CWT) и предварительно обученной сверточной нейронной сетью (CNN).

Классификация модуляций является важной функцией для интеллектуального приемника. Классификация модуляций имеет многочисленные приложения, такие как познавательный радар и программно определяемое радио. Как правило, чтобы идентифицировать эти формы волны и классифицировать их типом модуляции необходимо задать значимые функции и ввести их в классификатор. В то время как эффективный, эта процедура может потребовать, чтобы обширное усилие и знания проблемной области дали к точной классификации. Этот пример исследует среду, чтобы автоматически извлечь функции частоты времени из сигналов и выполнить классификацию сигнала с помощью нейронной сети для глубокого обучения.

Вы используете CWT, чтобы создать представления частоты времени сигналов с комплексным знаком. Вы не должны разделять сигнал в меня и каналы Q. Вы используете представления, названные scalograms, и усиливаете существующий CNN путем переобучения сети, чтобы классифицировать сигналы. Это усиление существующих нейронных сетей называется передачей обучения.

В этом примере мы адаптируем SqueezeNet, CNN, предварительно обученный распознаванию изображений, чтобы классифицировать тип модуляции каждой системы координат на основе scalogram. Мы затем создаем исполняемый файл CUDA, который генерирует scalogram входного сигнала. Мы развертываем исполняемый файл и переобученный CNN на целевое устройство, позволяя классифицировать сигналы в режиме реального времени.

По умолчанию этот пример загружает обучающие данные и обучил сеть в одном zip-файле wavelet_modulation_classification.zip. Размер zip-файла составляет приблизительно 1,2 гигабайта. У вас есть опция генерации обучающих данных и обучения сети. Однако оба - длительные операции. В зависимости от вашего компьютерного оборудования, генерируя обучающие данные может занять один час или дольше. Обучение сети может занять 90 минут или дольше.

Типы модуляции

Задайте пять цифровых и три аналоговых типа модуляции:

  • Бинарное манипулирование сдвига фазы (BPSK)

  • 16-ary квадратурная амплитудная (16-QAM) модуляция

  • 4-ary импульсная амплитудная модуляция (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. У вас должна быть запись permssion к parentDir. Zip-файл загружается на parentDir. Поскольку пример загружает данные по умолчанию, dataDir должен быть 'wavelet_modulation_classification'. Директория dataDirectory будет содержать обучающие данные, используемые в этом примере. ResultDir задает имя директории, которая будет содержать обучивший сеть. ResultDir находится в той же директории как этот пример и будет создан для вас при необходимости.

parentDir = tempdir;
dataDir = 'wavelet_modulation_classification';
dataDirectory = fullfile(parentDir,dataDir);
ResultDir = 'trainedNetworks';

Задайте параметры обучающих данных. Обучающие данные состоят из 5 000 систем координат для каждого типа модуляции. Каждая система координат является 1 024 выборками долго и имеет частоту дискретизации 200 кГц. Для цифровых типов модуляции восемь выборок представляют символ. Примите центральную частоту 902 МГц и 100 МГц для цифровых и аналоговых типов модуляции, соответственно.

numFramesPerModType = 5000;
frameLength = 1024;
fs = 200e3;

Загрузите данные

Загрузите и разархивируйте обучающие данные, и обучил сеть. dataDirectory папка содержит папки, названные в честь каждого типа модуляции. Обучающие данные находятся в этих папках. Обучивший сеть, waveletModClassNet.mat, находится в ResultDir.

Если вы не хотите загружать данные, установите downloadData ко лжи. Функция помощника helperGenerateModWaveforms генерирует системы координат и хранит их в dataDirectory. В целях воспроизводимости, набор случайный seed.

downloadData = true;
if downloadData
    dataURL = 'https://ssd.mathworks.com/supportfiles/wavelet/waveletModulation/wavelet_modulation_classification.zip';
    zipFile = fullfile (parentDir,'wavelet_modulation_classification.zip');
    тик
    websave (zipFile, dataURL);
    disp'Download time: ', num2str (toc),' seconds'])
    тик
    разархивируйте (zipFile, parentDir);
    disp'Unzipping time: ', num2str (toc),' seconds'])
    trainedNetworkDir = fullfile (parentDir, dataDir,'results');
    состояние = copyfile (trainedNetworkDir, ResultDir);
else
    rng (1235)
    helperGenerateModWaveforms (dataDirectory, modulationTypes, numFramesPerModType, frameLength, фс);
end
Download time: 38.2209 seconds
Unzipping time: 7.9005 seconds

Другой пример, Классификация Модуляций с Глубоким обучением (Communications Toolbox), выполняет классификацию модуляций нескольких различных типов модуляции с помощью Communications Toolbox™. Функция помощника helperGenerateModWaveforms генерирует и увеличивает подмножество типов модуляции, используемых в том примере. Смотрите, что пример соединяется для всестороннего описания рабочего процесса, необходимого для цифровой и аналоговой классификации модуляций, и методы раньше создавали эти формы волны.

Постройте амплитуду действительных и мнимых частей представителя каждого типа модуляции. Функция помощника helperModClassPlotTimeDomain2 делает это.

helperModClassPlotTimeDomain2(dataDirectory,modulationTypes,fs)

Сгенерируйте Scalograms

Создайте представления частоты времени форм волны. Эти представления называются scalograms. scalogram является абсолютным значением коэффициентов CWT сигнала. Чтобы создать scalograms, предварительно вычислите набор фильтров CWT. Предварительное вычисление набора фильтров CWT является предпочтительным методом при получении CWT многих сигналов с помощью тех же параметров.

Прежде, чем сгенерировать весь scalograms, постройте scalograms от представителя каждого типа модуляции. Создайте набор фильтров CWT с помощью cwtfilterbank для сигнала с 1 024 выборками и использованием набор фильтров, чтобы взять CWT сигнала. Поскольку сигнал комплексный оцененный, CWT является трехмерным массивом. Первой страницей является CWT для положительных шкал (аналитическая часть или против часовой стрелки компонент), и второй страницей является CWT для отрицательных шкал (антианалитическая часть или по часовой стрелке компонент). Чтобы сгенерировать scalograms, примите абсолютное значение конкатенации каждой страницы. Функция помощника helperPlotScalogramsMod2 делает это.

helperPlotScalogramsMod2(dataDirectory,modulationTypes,frameLength,fs)

Если вы загрузили обучающие данные и обучили сеть, продолжите Делиться на Обучение, Тестирование и Данные о Валидации. В противном случае сгенерируйте весь scalograms, когда RGB отображает, и запишите им в соответствующий подкаталог в dataDirectory. Функция помощника helperGenerateCWTfiles2 делает это. Чтобы быть совместимым с архитектурой SqueezeNet, каждое изображение RGB является массивом размера 227 227 3.

if ~downloadData
    helperGenerateCWTfiles2(dataDirectory,modulationTypes,frameLength,fs)
end

Разделитесь на обучение, тестирование и данные о валидации

Загрузите изображения scalogram как datastore изображений. imageDatastore функционируйте автоматически помечает изображения на основе имен папок и хранит данные как объект ImageDatastore. Datastore изображений позволяет вам сохранить большие данные изображения, включая данные, которые не умещаются в памяти, и эффективно считать пакеты изображений во время обучения CNN.

folders = fullfile(dataDirectory,string(modulationTypes));
imds = imageDatastore(folders,...
    'FileExtensions','.jpg','LabelSource','foldernames');

Случайным образом разделите изображения на три группы, где 80% используются для обучения, 10% используются для валидации, и 10% используются для тестирования. Мы используем системы координат обучения и валидации во время сетевой учебной фазы. В целях воспроизводимости мы устанавливаем случайный seed.

rng(1235)
[imdsTrain,imdsTest,imdsValidation] = splitEachLabel(imds,0.8,0.1);

При необходимости создайте директорию, которая будет содержать обучивший сеть. Если вы загрузили данные, директория, заданная ResultDir уже exsts и файл waveletModClassNet.mat в этой директории содержит обучивший сеть.

if ~exist(ResultDir,'dir')
    mkdir(ResultDir)
end
MatFile = fullfile(ResultDir,'waveletModClassNet.mat');

Если вы загрузили zip-файл, загрузите обучивший сеть и затем продолжите Оценивать Сеть. В противном случае необходимо переобучить SqueezeNet.

if downloadData
    disp('Load ML model from the file')
    load(MatFile,'trainedNet','imdsValidation')
end
Load ML model from the file

SqueezeNet

SqueezeNet является предварительно обученным CNN, который может классифицировать изображения в 1 000 категорий объектов. Необходимо переобучить SqueezeNet, чтобы классифицировать формы волны их типом модуляции. До переобучения вы изменяете несколько слоев сети и устанавливаете различные опции обучения. После того, как переобучение завершено, вы сохраняете CNN в .mat файл. Исполняемый файл CUDA использует .mat файл.

Загрузите SqueezeNet и извлеките график слоев из сети. Смотрите последние пять слоев графика.

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

Последний learnable слой в SqueezeNet является сверточным слоем 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

Обучите CNN

Обучение нейронной сети является итеративным процессом, который включает минимизацию функции потерь. Используйте 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;

Установите случайный seed на значение по умолчанию и используйте trainNetwork (Deep Learning Toolbox) функция, чтобы обучить CNN. Сохраните обучившие сеть, испытательные параметры, учебное время выполнения, и отобразите datastore, содержащий изображения валидации. Из-за большого размера набора данных процесс займет много минут. По умолчанию обучение сделано на графическом процессоре, если вы доступны. Используя графический процессор требует Parallel Computing Toolbox™. Чтобы видеть, который поддерживаются графические процессоры, смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). В противном случае обучение сделано на центральном процессоре. Учебные графики точности в фигуре показывают прогресс изучения сети через все итерации.

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

Генерация кода графического процессора — задает функции

scalogram сигнала является входом "изображение" к глубокому CNN. Создайте функцию, cwtModType, это вычисляет scalogram формы волны с комплексным знаком и возвращает изображение в пользовательских заданных измерениях. Изображение использует jet(128) палитра. В целях генерации кода обработайте входной сигнал как 1024 2 матрица, где первый столбец содержит действительные части выборок формы волны, и второй столбец содержит мнимые части. %#codegen директива в функции указывает, что функция предназначается для генерации кода. При использовании coder.gpu.kernelfun прагма, генерация кода пытается сопоставить расчеты в cwtModType функционируйте к графическому процессору.

type cwtModType
function 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 функция, чтобы создать изображение scalogram. modelPredictModType функционируйте использует сеть, содержавшуюся в mdwv_model файл, чтобы классифицировать форму волны.

type modelPredictModType
function 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 Coder). Основной файл вызывает код, сгенерированный для функции точки входа MATLAB. Основной файл сначала читает сигнал формы волны из текстового файла, передает данные функции точки входа и пишет результаты предсказания в текстовый файл (predClassProb.txt). Чтобы максимизировать КПД расчета на графическом процессоре, исполняемый файл обрабатывает данные с одинарной точностью.

Если вы хотите просмотреть содержимое основных и заголовочных файлов, установите viewFiles к истине.

viewFiles = false;
if viewFiles
    ввод main_mod_jetson.cu
end
if viewFiles
    ввод main_mod_jetson.h
end

Генерация кода графического процессора — связывает с оборудованием

Чтобы связаться с оборудованием 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, 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 функция, чтобы создать настройку возражает для платформы Джетсона и присвоить ее Hardware свойство объекта cfg настройки кода. Используйте 'NVIDIA Jetson' для Jetson TX1 или плат TX2. Пользовательский основной файл является оберткой, которая вызывает функцию точки входа в сгенерированном коде. Пользовательский файл требуется для развернутого исполняемого файла.

Используйте coder.DeepLearningConfig (GPU Coder) функция, чтобы создать 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 = '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 функционируйте и передайте настройку графического процессора кода наряду с размером и типом входа для modelPredictModType функция точки входа. После того, как генерация кода на хосте завершена, сгенерированные файлы скопированы и основаны на цели.

codegen('-config ',cfg,Function_to_Gen,'-args',{single(ones(1024,2))},'-report');
Code generation successful: View report

Генерация кода графического процессора — выбирает Signal

Исполняемый файл CUDA выполняет классификацию модуляций путем генерации scalogram формы волны с комплексным знаком и применения переобученного CNN к scalogram. Выберите форму волны, которая была сгенерирована в начале этого примера. От 5 000 систем координат каждого типа модуляции выберите одну из первых 50 систем координат, сгенерированных установкой waveNumber. Постройте действительные и мнимые части системы координат и scalogram, сгенерированный от него. Используйте функцию помощника helperPlotWaveFormAndScalogram. Можно найти исходный код для этой функции помощника в разделе Supporting Functions в конце этого примера.

waveForm = modTypesList(6);
волновое число =  1;
signal_data = helperPlotWaveFormAndScalogram (dataDirectory, форма волны, волновое число);

Если вы скомпилировали исполняемый файл, который будет развернут на цели, запишите сигнал, вы выбрали к текстовому файлу 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 используется, чтобы извлечь функции из форм волны. Затем SqueezeNet переобучен, чтобы классифицировать сигналы на основе их scalograms. Две пользовательских функции созданы и скомпилированы на целевом устройстве 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

Смотрите также

Похожие темы