使用小波分析在NVIDIA杰森调制分类
这个例子展示了如何生成和部署CUDA®执行执行调制分类使用特点提取的连续小波变换(CWT),和一个pretrained卷积神经网络(CNN)。
调制分类是一个重要的功能的智能接收器。调制分类有许多应用,如认知雷达和软件定义无线电。通常,通过调制类型识别和分类这些波形有必要定义有意义的特性和输入到分类器。虽然有效,这个过程需要大量的努力和领域知识,从而生成一个精确的分类。这个例子中探索一个框架自动从信号中提取时频特性和使用深学习网络执行信号分类。
你使用类来创建复数信号的时频表示。您不需要单独的信号I和Q通道。你使用表示,称为量图由培训网络,并利用现有的CNN对信号进行分类。这种利用现有的神经网络转移学习。
在这个例子中,我们适应SqueezeNet, CNN pretrained图像识别,对每一帧的调制类型进行分类的基础上量图。然后我们创建一个CUDA可执行文件,生成一个输入信号的量图。我们部署可执行和重新训练CNN目标设备上,从而能够实时信号进行分类。
默认情况下,这个示例下载训练数据和训练网络在一个ZIP文件wavelet_modulation_classification.zip
。ZIP文件的大小大约是1.2 gb。您可以选择生成训练数据和训练网络。然而,两者都是耗时的操作。根据您的计算机硬件,生成训练数据需要一个小时或更长时间。培训网络可以把90分钟或更长时间。
调制类型
指定5个数字和三个模拟调制类型:
二进制相移键控(BPSK)
16-ary正交调幅(16-QAM)
4-ary脉冲幅度调制(PAM4)
高斯频移键控(GFSK)
连续相频移键控(CPFSK)
广播调频(B-FM)
双边带调幅(DSB-AM)
单边带调幅(SSB-AM)
modTypesList = [“BPSK”,…“16 qam”,“PAM4”,“GFSK”,“CPFSK”,…“B-FM”,“DSB-AM”,“SSB-AM”];modulationTypes =分类(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千赫。对于数字调制类型,8个样本代表一个符号。假设一个中心频率902 MHz和100 MHz的数字和模拟调制类型,分别。
numFramesPerModType = 5000;frameLength = 1024;fs = 200年e3;
下载数据
下载并解压缩训练数据和训练网络。的dataDirectory
文件夹包含文件夹命名每个调制类型。训练数据在这些文件夹。训练网络,waveletModClassNet.mat
,是在ResultDir
。
如果你不想下载数据,设置downloadData
为假。辅助函数helperGenerateModWaveforms
生成帧并将它们存储在dataDirectory
。为了再现性,设置随机种子。
downloadData =真正的;如果downloadData dataURL =“https://ssd.mathworks.com/金宝appsupportfiles/wavelet/waveletModulation/wavelet_modulation_classification.zip”;zipFile = fullfile (parentDir,“wavelet_modulation_classification.zip”);抽搐websave (zipFile dataURL);disp ([的下载时间:num2str (toc)“秒”])抽搐解压(zipFile parentDir);disp ([的测定时间:num2str (toc)“秒”])trainedNetworkDir = fullfile (parentDir dataDir,“结果”);状态=复制文件(trainedNetworkDir ResultDir);其他的rng (1235) helperGenerateModWaveforms (dataDirectory、modulationTypes numFramesPerModType, frameLength, fs);结束
下载时间:38.2209秒
测定时间:7.9005秒
另一个例子,调制分类与深度学习(通信工具箱),执行不同调制类型的调制分类使用通信工具箱™。辅助函数helperGenerateModWaveforms
生成和增强的一个子集,示例中使用的调制类型。参见示例链接的深入描述工作流所需的数字和模拟调制分类和技术用于创建这些波形。
情节的振幅的实部和虚部代表每个调制类型。辅助函数helperModClassPlotTimeDomain2
这是否。
helperModClassPlotTimeDomain2 (dataDirectory modulationTypes fs)
生成量图
创建波形的时频表示。这些表示被称为量图。量图是一个信号的变换系数的绝对值。要创建量图,预计算CWT滤波器组。预计算CWT过滤器银行是首选方法,获得许多信号的类使用相同的参数。
在生成所有量图之前,情节的量图每个调制类型的代表。创建一个类使用滤波器组cwtfilterbank
对于1024个样本的一个信号,并使用滤波器组信号的变换。因为信号复杂的价值,类是一个三维数组。第一页是积极的CWT尺度(逆时针分析部分或组件),和第二页的CWT -尺度(顺时针anti-analytic部分或组件)。生成量图,取绝对值的每个页面的连接。辅助函数helperPlotScalogramsMod2
这是否。
helperPlotScalogramsMod2 (dataDirectory modulationTypes frameLength, fs)
如果你下载了训练数据训练网络,继续数据分为训练、测试和验证。否则,生成所有量图的RGB图像和写他们适当的子目录dataDirectory
。辅助函数helperGenerateCWTfiles2
这是否。兼容SqueezeNet架构,每一个RGB图像数组大小227 - 227 - 3。
如果~ downloadData helperGenerateCWTfiles2 (dataDirectory modulationTypes frameLength, fs)结束
数据分为训练、测试和验证
加载量图图像作为一个图像数据存储。的imageDatastore
函数自动标签基于文件夹的名字和存储的图像数据作为ImageDatastore对象。图像数据存储可以存储大量图像数据,包括数据,并不适合在内存中,有效地阅读批图像在CNN的训练。
文件夹= fullfile (dataDirectory字符串(modulationTypes));imd = imageDatastore(文件夹,…“FileExtensions”,“jpg”,“LabelSource”,“foldernames”);
随机将图像划分为三组,80%用于培训,10%用于验证,10%是用于测试。我们使用的培训和验证帧在网络训练阶段。再现性的目的,我们将随机种子。
rng (1235) [imdsTrain、imdsTest imdsValidation] = splitEachLabel (imd, 0.8, 0.1);
如果有必要,创建的目录将包含训练网络。如果你下载数据,指定的目录ResultDir
已经存在,和文件waveletModClassNet.mat
在这个目录包含训练网络。
如果~存在(ResultDir“dir”mkdir (ResultDir)结束MatFile = fullfile (ResultDir,“waveletModClassNet.mat”);
如果你下载的ZIP文件,加载训练网络,然后继续评估网络。否则,你必须重新培训SqueezeNet。
如果downloadData disp (“从文件加载ML模式”)负载(MatFile“trainedNet”,“imdsValidation”)结束
负载毫升模型从文件
SqueezeNet
SqueezeNet pretrained CNN,可以分类图像到1000年对象类别。你必须重新培训SqueezeNet对波形的调制类型进行分类。培训之前,您修改几个网络层和设置各种培训选项。培训完成后,保存的CNN.mat
文件。CUDA执行使用.mat文件。
负载SqueezeNet和从网络提取层图。检查的最后五层图。
网= squeezenet;lgraph = layerGraph(净);lgraph.Layers (end-4:结束)
ans = 5×1层与层:数组1 conv10卷积1000 1×1×512旋转步[1]和填充[0 0 0 0]2的relu_conv10 ReLU ReLU 3“pool10”全球平均分担全球平均池4“概率”Softmax Softmax 5 ClassificationLayer_predictions的分类输出crossentropyex“鲤鱼”和999其他的类
最后可学的层在SqueezeNet 1×1回旋的层,“conv10”
。取代一层一层新的卷积过滤器的数量等于调制类型的数量。
numClasses =元素个数(modulationTypes);numClasses newLearnableLayer = convolution2dLayer (1,“名字”,“new_conv10”);lgraph = replaceLayer (lgraph lgraph.Layers (end-4) . name, newLearnableLayer);
用一个新的替换分类层没有类标签。输出层的类在训练时间自动设置。显示过去的五层确认更改。
newClassLayer = classificationLayer (“名字”,“new_classoutput”);lgraph = replaceLayer (lgraph lgraph.Layers(结束). name, newClassLayer);lgraph.Layers (end-4:结束)
ans = 5×1层阵列层:1‘new_conv10卷积8 1×1步[1]和填充的卷积[0 0 0 0]2的relu_conv10 ReLU ReLU 3“pool10”全球平均分担全球平均池4“概率”Softmax Softmax 5 new_classoutput crossentropyex分类输出
火车CNN
训练一个神经网络是一个迭代的过程,涉及最小化损失函数。使用trainingOptions
(深度学习工具箱)培训过程函数指定选项确保良好的网络性能。指的是trainingOptions
文档的描述每个选项。
OptimSolver =“亚当”;MiniBatchSize = 50;MaxEpochs = 20;InitialLearnRate = 1的军医;洗牌=“every-epoch”;选择= trainingOptions (OptimSolver,…“MiniBatchSize”MiniBatchSize,…“MaxEpochs”MaxEpochs,…“InitialLearnRate”InitialLearnRate,…“洗牌”洗牌,…“详细”假的,…“阴谋”,“训练进步”,…“ValidationData”,imdsValidation);
保存所有参数在一个结构。培训网络和结构将保存在晚些时候.mat
文件。
TrialParameter。OptimSolver =OptimSolver; TrialParameter.MiniBatchSize = MiniBatchSize; TrialParameter.MaxEpochs = MaxEpochs; TrialParameter.InitialLearnRate = InitialLearnRate;
设置默认值,使用随机种子trainNetwork
(深度学习工具箱)功能训练CNN。保存培训网络,试验参数,训练时间,包含验证图像的图像数据存储。因为数据集的大小,这个过程需要好几分钟。默认情况下,GPU来做培训是如果一个是可用的。使用GPU需要并行计算工具箱™。看到支持gpu,明白了金宝appGPU计算的需求(并行计算工具箱)。否则,培训是在CPU上完成的。训练精度情节图中显示网络的学习的进步所有迭代。
如果~ downloadData rng默认的抽搐;trainedNet = trainNetwork (imdsTrain、lgraph选项);trainingTime = toc;流(总培训时间:%。2 e秒\ n”,trainingTime);保存(MatFile,“TrialParameter”,“trainedNet”,“trainingTime”,“imdsValidation”);结束
评估网络
加载.mat
文件包含培训网络和训练参数。只保存在一个单独的训练网络.mat
文件。这个文件将使用CUDA可执行文件。
OutMatFile =“mdwv_model.mat”;data =负载(MatFile“trainedNet”);trainedNet = data.trainedNet;保存(OutMatFile,“trainedNet”);
评估培训网络得到的分类精度测试框架。
(YPred,聚合氯化铝)= (trainedNet imdsTest)进行分类;imdsTestLabels = imdsTest.Labels;modAccuracy = (YPred = = imdsTestLabels) /元素个数之和(imdsTestLabels) * 100
modAccuracy = 96.2250
总结训练网络的性能测试框架混乱图表。显示每个类的精度和召回通过使用列和行摘要。保存图。表底部的混乱图表显示精度值。桌子右边的图表显示混乱召回值。
图(“单位”,“归一化”,“位置”(0.2 - 0.2 0.5 - 0.5));ccDCNN = confusionchart (imdsTestLabels YPred);ccDCNN。Title = (的测试精度:num2str (modAccuracy)];ccDCNN。ColumnSummary =“column-normalized”;ccDCNN。RowSummary =“row-normalized”;AccFigFile = fullfile (ResultDir,“Network_ValidationAccuracy.fig”);saveas (gcf AccFigFile);
显示的大小训练网络。
信息=谁(“trainedNet”);ModelMemSize = info.bytes / 1024;流(“训练网络大小:% g kB \ n 'ModelMemSize)
训练网络的大小:2992.95 kB
确定网络的平均时间对一个图像进行分类。
NumTestForPredTime = 20;TrialParameter。NumTestForPredTime = NumTestForPredTime;流(“测试预测时间(数量的测试:% d)…”NumTestForPredTime)
测试预测时间(测试数量:20)……
图象尺寸= trainedNet.Layers (1) .InputSize;PredTime = 0 (NumTestForPredTime, 1);为i = 1: NumTestForPredTime x = randn(图象尺寸);抽搐;(YPred,聚合氯化铝)= (trainedNet x)进行分类;PredTime (i) = toc;结束AvgPredTimePerImage =意味着(PredTime);流(的平均预测时间:%。2 e秒\ n”,AvgPredTimePerImage);
平均预测时间:8.41 e-02秒
保存结果。
如果~ downloadData保存(MatFile“modAccuracy”,“ccDCNN”,“PredTime”,“ModelMemSize”,…“AvgPredTimePerImage”,“添加”)结束
GPU代码生成——定义函数
量图的一个信号是输入“图像”深CNN。创建一个函数,cwtModType
复数的计算量图波形,并返回一个图像在指定的维度。图像使用飞机(128)
colormap。为代码生成的目的,把输入信号1024 -,- 2的矩阵,其中第一列包含的真正部分波形样本,第二列包含虚部。的% # codegen
指令函数表明,函数是用于代码生成。当使用coder.gpu.kernelfun
编译指示,代码生成试图映射的计算cwtModType
函数的GPU。
类型cwtModType
函数im = cwtModType (inputSig imgSize) % # codegen %这个函数仅仅是为了支持小波深度学习的例子。金宝app%,它可能改变或在将来的版本中被删除。coder.gpu.kernel;%的输入是一个1024 x2矩阵,将它转换成复杂的表单(+ 1 * ib) cinputSig = convertToComplex (inputSig);(wt %小波时频表示,~,~]= cwt (cinputSig,莫尔斯,1,“VoicesPerOctave”, 48);%从信号生成小波时频系数cfs = abs ([wt (:,: 1);wt (:: 2)]);% %连接顺时针和逆时针表示图像生成im = generateImagefromCWTCoeff (cfs, imgSize);结束
创建的入口点函数,modelPredictModType
代码生成。作为一个指定的函数接受复值信号,1024 -,- 2的矩阵,作为输入并调用cwtModType
量图的函数来创建一个图像。的modelPredictModType
中包含的函数使用网络mdwv_model
文件对波形进行分类。
类型modelPredictModType
函数predClassProb = modelPredictModType (inputSig) % # codegen %这个函数仅仅是为了支持小波深度学习的例子。金宝app%,它可能改变或在将来的版本中被删除。coder.gpu.kernelfun ();%输入信号大小由- 2 1024 - %参数ModelFile =“mdwv_model.mat”;%文件保存神经网络模型imSize = (227 - 227);%的深入学习网络的输入图像%函数来转换信号小波时频图像im = cwtModType (inputSig imSize);%加载训练的深度学习网络持久模型;如果isempty(模型)模型=编码器。loadDeepLearningNetwork (ModelFile mynet);结束%预测信号调制predClassProb = model.predict (im); end
生成NVIDIA的CUDA可执行文件,可以部署目标,创建一个自定义主文件(main_mod_jetson.cu
)和一个头文件(main_mod_jetson.h
)。您可以生成一个例子主要文件和使用它作为一个模板重写新的主要和头文件。有关更多信息,请参见GenerateExampleMain
的属性coder.CodeConfig
(MATLAB编码器)。主文件调用MATLAB入口点函数所生成的代码。主文件首先读取波形信号从一个文本文件,将数据传递到入口点函数,并将预测结果写入一个文本文件(predClassProb.txt
)。在GPU计算效率最大化,可执行流程单精确数据。
如果你想查看的主要内容和标题文件,设置viewFiles
为true。
viewFiles =假;如果viewFiles类型main_mod_jetson.cu结束如果viewFiles类型main_mod_jetson.h结束
GPU代码生成,连接硬件
与NVIDIA硬件进行通信,您创建一个生活硬件连接对象使用杰森
函数。你必须知道主机名或IP地址,用户名和密码的目标板创建一个生活硬件连接对象。
创建一个住杰森硬件的硬件连接对象。在以下代码中,替换:
NameOfJetsonDevice
与杰森设备的名称或IP地址用户名
和你的用户名密码
用你的密码
在创建对象的过程中,软件执行硬件和软件检查,IO服务器安装和收集信息的外围设备连接到目标。这些信息显示在命令窗口。
hwobj =杰森(“NameOfJetsonDevice”,“用户名”,“密码”);
检查CUDA可用性目标……检查“nvcc”在目标系统路径…检查cuDNN库可用性目标……检查TensorRT库可用性目标……检查先决条件库完成。收集硬件信息…检查第三方库可用性目标……收集完成硬件细节。委员会名称:英伟达杰森TX1, NVIDIA杰森Nano CUDA版本:10.0 cuDNN版本:7.3 TensorRT版本:5.0 GStreamer版本:1.14.5 V4L2版本:1.14.2-1 SDL版本:1.2可用的网络摄像头:可用gpu: NVIDIA Tegra X1
使用coder.checkGpuInstall
(GPU编码器)功能和验证编译器和库所需的硬件上运行这个例子是正确设置。
envCfg = coder.gpuEnvConfig (“杰森”);envCfg。DeepLibTarget =“cudnn”;envCfg。DeepCodegen = 1;envCfg。HardwareObject = hwobj;envCfg。安静= 1;coder.checkGpuInstall (envCfg)
ans =结构体字段:gpu: 1 cuda: 1 cudnn: 1 tensorrt: 0 basiccodegen: 0 basiccodeexec: 0 deepcodegen: 1 deepcodeexec: 0 tensorrtdatatype: 0分析:0
GPU代码生成——指定目标
创建一个可执行文件,可以部署到目标设备,集CodeGenMode
等于1。如果你想创建一个可执行文件运行在本地和远程连接到目标设备,集CodeGenMode
等于2。Jetson_BuildDir
指定的目录在目标系统上执行远程构建过程。如果指定的目标构建目录不存在,那么软件创建一个目录的名字。
CodeGenMode =1;Function_to_Gen =“modelPredictModType”;ModFile =“mdwv_model.mat”;%文件保存神经网络模型;符合“main_mod_jetson.cu”ImgSize = (227 - 227);%毫升的输入图像大小模型Jetson_BuildDir =“~ / projectMDWV”;
创建一个GPU代码编译所需配置对象。使用coder.hardware
杰森平台的功能来创建一个配置对象,并将其分配给硬件
代码配置对象的属性cfg
。使用英伟达杰森的
杰森TX1或TX2董事会。自定义主文件是一个调用的入口点函数的包装器生成的代码。所需的自定义文件是可执行的部署。
使用coder.DeepLearningConfig
(GPU编码器)函数创建一个CuDNN
深度学习配置对象,并将其分配给DeepLearningConfig
GPU代码配置对象的属性。代码生成器利用NVIDIA CUDA技术®®深层神经网络库(cuDNN) NVIDIA gpu。cuDNN是一个GPU-accelerated库原语的深层神经网络。
如果CodeGenMode = = 1 cfg = coder.gpuConfig (exe”);cfg。硬件= coder.hardware (英伟达杰森的);cfg.Hardware。BuildDir = Jetson_BuildDir;cfg。DeepLearningConfig = coder.DeepLearningConfig (“cudnn”);cfg。CustomSource =“main_mod_jetson.cu”;elseifCodeGenMode = = 2 cfg = coder.gpuConfig (“自由”);cfg。VerificationMode =“公益诉讼”;cfg。硬件= coder.hardware (英伟达杰森的);cfg.Hardware。BuildDir = Jetson_BuildDir;cfg。DeepLearningConfig = coder.DeepLearningConfig (“cudnn”);结束
GPU -编译生成代码
生成CUDA代码,使用codegen
功能和通过GPU代码配置的大小和类型的输入modelPredictModType
入口点函数。代码生成主机上完成后,生成的文件复制,建立在目标。
codegen (“配置”cfg Function_to_Gen,“参数”,{((1024 2))},“报告”);
代码生成成功:查看报告
GPU代码生成,选择信号
CUDA可执行文件进行调制分类通过生成复数的量图波形,并应用培训CNN量图。选择一个波形生成的这个例子。5000帧的每个调制类型,选择的第一个50帧生成的设置波数
。情节框架的实部和虚部,并生成的量图。使用辅助函数helperPlotWaveFormAndScalogram
。你能找到这个helper函数的源代码金宝app支持功能节结束时这个例子。
波形=modTypesList (6);波数=1;signal_data = helperPlotWaveFormAndScalogram (dataDirectory、波形、波数);
如果你编译后的可执行文件部署到目标,写信号你选择的文本文件signalFile
。使用putFile ()
函数的硬件对象放置在目标文本文件。的workspaceDir
属性包含的路径codegen
在目标文件夹。的主要
函数在指定的可执行从文本文件中读取数据signalFile
并将分类结果写入resultFile
。
signalFile =“signalData.txt”;resultFile =“predClassProb.txt”;%符合“main_mod_jetson.cu”如果CodeGenMode = = 1支撑材= fopen (signalFile,' w ');为i = 1:长度(signal_data)流(fid,“% f \ n”真实(signal_data(我)));结束为i = 1:长度(signal_data)流(fid,“% f \ n”图像放大(signal_data(我)));结束文件关闭(fid);hwobj.putFile (signalFile hwobj.workspaceDir);结束
GPU执行代码生成
运行可执行文件。
运行时部署的可执行文件,删除以前的结果文件是否存在。使用runApplication ()
函数来启动可执行目标硬件,然后getFile ()
函数来检索结果。因为结果后立即可能不存在runApplication ()
函数调用返回,以允许通信延迟,设置一个抓取结果最大时间90秒。使用evalc
函数抑制命令行输出。
如果CodeGenMode = = 1%运行部署可执行maxFetchTime = 90;resultFile_hw = fullfile (hwobj.workspaceDir resultFile);如果ispc resultFile_hw = strrep (resultFile_hw,“\”,' / ');结束ta =抽搐;hwobj.deleteFile resultFile_hw evalc (“hwobj.runApplication (Function_to_Gen signalFile)”);tf =抽搐;成功= false;而toc (tf) < maxFetchTime试一试evalc (“hwobj.getFile (resultFile_hw)”);成功= true;抓我结束如果成功打破结束结束流('获取时间= %。3 e秒\ n”toc (tf));断言(成功,“无法获取预测”)PredClassProb = readmatrix (resultFile);PredTime = toc (ta);elseifCodeGenMode = = 2%公益诉讼运行可执行文件sigData =[真实(signal_data)”;图像放大(signal_data) ') ';ta =抽搐;eval (sprintf (' PredClassProb = % s_pil(单(sigData));“Function_to_Gen));PredTime = toc (ta);eval (sprintf (“清楚% s_pil;”Function_to_Gen));%公益诉讼终止执行结束
获取时间= 4.852 e + 00秒
GPU的代码生成——显示结果
的resultFile
包含了分类结果。为每一个可能的调制类型,网络分配一个概率的信号类型。显示所选的调制类型。使用辅助函数helperPredViz
显示分类结果。
如果CodeGenMode helperPredViz = = 1%获取预测结果文件读取elseifCodeGenMode = = 2 helperPredVizPil (PredClassProb)%阅读工作空间变量结束
流(“期望波形:% s \ n”、波形);
将波形:B-FM
总结
这个例子显示了如何创建和部署一个CUDA执行使用CNN进行调制分类。你也可以选择创建一个可执行文件在本地运行和连接到远程目标。在本例中给出了一个完整的工作流程。数据下载后,类用于从波形中提取特征。然后SqueezeNet重新训练分类根据信号量图。两个用户定义的函数创建和编译目标NVIDIA设备。可执行的结果与MATLAB进行比较。
金宝app支持功能
helperPlotWaveFormAndScalogram
函数sig = helperPlotWaveFormAndScalogram (dataDirectory wvType wvNum)%这个函数仅仅是为了支持小波深度学习的例子。金宝app%,它可能改变或在将来的版本中被删除。waveFileName = sprintf (“% s % 05 d.mat帧”、wvType wvNum);负载(fullfile (dataDirectory wvType waveFileName),“帧”);sig =框架;cfs = cwt(团体,“莫尔斯”,1“VoicesPerOctave”48岁);cfs = abs ([cfs(:,: 1);慢性疲劳综合症(:,:2)));次要情节(211)情节(真实(帧)在情节(图像放大(帧)从轴紧传奇(“真实”的,图像放大的str = sprintf ()“波形:% s /框架:% d \ n信号”、wvType wvNum);标题(str)次要情节(212)显示亮度图像(cfs)标题(的时频表示)%设置(gca、“xtick”, []);集(gca),“ytick”[]);结束
helperPredVizPil
函数helperPredVizPil (PredClassProb)%这个函数仅仅是为了支持小波深度学习的例子。金宝app%,它可能改变或在将来的版本中被删除。一会= {16 qam的;“B-FM”;“BPSK”;“CPFSK”;“DSB-AM”;“GFSK”;“PAM4”;“SSB-AM”};图酒吧(PredClassProb)集(gca,“XTickLabel”,一会)包含(“阶级标签”)ylabel (“概率”)标题(“调制分类输出”)轴紧网格在结束