主要内容

基于小波分析的NVIDIA Jetson调制分类

此示例显示如何生成和部署CUDA®可执行文件,该文件使用连续小波变换(CWT)和预训练卷积神经网络(CNN)提取的特征执行调制分类。

调制分类是智能接收机的一个重要功能。调制分类有许多应用,如认知雷达和软件无线电。通常,为了识别这些波形并根据调制类型对它们进行分类,必须定义有意义的特征并将其输入到分类器中。虽然有效,但这个过程需要大量的努力和领域知识来产生准确的分类。这个例子探索了一个框架,自动提取信号的时频特征,并使用深度学习网络进行信号分类。

您可以使用CWT来创建复值信号的时频表示。您不需要将信号分成I和Q通道。您使用的表示,称为量图,并通过重新训练网络对信号进行分类来利用现有的CNN。这种对现有神经网络的利用被称为迁移学习

在这个例子中,我们使用了SqueezeNet,一个预先训练好的图像识别CNN,根据尺度图对每一帧的调制类型进行分类。然后,我们创建一个CUDA可执行文件,生成输入信号的标度图。我们将可执行的CNN部署到目标设备上,并对其进行重新训练,使其能够实时对信号进行分类。

默认情况下,本示例在一个ZIP文件中下载训练数据和训练网络小波\调制\分类.zip. ZIP文件的大小约为1.2 GB。您可以选择生成训练数据和训练网络。然而,两者都是耗时的操作。根据您的计算机硬件,生成培训数据可能需要一小时或更长时间。培训网络可能需要90分钟或更长时间。

调制类型

指定五种数字和三种模拟调制类型:

  • 二相移键控(BPSK)

  • 16进制正交调幅

  • 四元脉冲幅度调制(PAM4)

  • 高斯频移键控(GFSK)

  • 连续相移频键控(CPFSK)

  • 广播调频(B-FM)

  • 双边带调幅(DSB-AM)

  • 单边带调幅(SSB-AM)

modTypesList=[“BPSK”...“16 qam”“PAM4”“GFSK”“CPFSK”...“B-FM”“DSB-AM”“SSB-AM”];调制类型=分类(modTypesList);

指定父目录parentDir和目录名dataDir它会在里面parentDir.你一定要给我写封信parentDir。ZIP文件下载到parentDir.因为该示例默认下载数据,dataDir必须是“wavelet_modulation_classification”. 目录数据目录将包含本示例中使用的训练数据。结果指定将包含经过训练的网络的目录的名称。结果在与本示例相同的目录中,并将在必要时为您创建。

parentDir=tempdir;dataDir=“wavelet_modulation_classification”; dataDirectory=fullfile(parentDir,dataDir);结果=“trainedNetworks”

指定训练数据的参数。训练数据由每一种调制类型的5,000帧组成。每帧1024个采样长,采样率为200khz。对于数字调制类型,八个样本代表一个符号。假设数字调制和模拟调制的中心频率分别为902 MHz和100 MHz。

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

下载数据

下载并解压训练数据和训练网络。的数据目录文件夹包含以每种调制类型命名的文件夹。训练数据在这些文件夹中。训练网络,waveletModClassNet.mat,在结果

如果不想下载数据,请设置downloadData这是错误的。辅助函数helperGenerateModWaveforms生成帧并将其存储在数据目录.为了再现性,设置随机种子。

downloadData =符合事实的如果downloadData dataURL ='https://ssd.mathworks.com/金宝appsupportfiles/wavelet/waveletModulation/wavelet_modulation_classification.zip'; zipFile=fullfile(parentDir,“wavelet_modulation_classification.zip”);tic websave(zipFile,dataURL);disp([的下载时间:num2str (toc)“秒”])tic解压(zipFile,parentDir);显示([的测定时间:num2str (toc)“秒”])trainedNetworkDir=fullfile(父目录、数据目录、,“结果”);状态=复制文件(trainedNetworkDir ResultDir);其他的rng (1235) helperGenerateModWaveforms (dataDirectory、modulationTypes numFramesPerModType, frameLength, fs);结束
下载时间:38.2209秒
解压时间:7.9005秒

再比如,,基于深度学习的调制分类(通讯工具箱),使用“通信工具箱”对几种不同的调制类型执行调制分类™. 辅助函数helperGenerateModWaveforms生成并扩充该示例中使用的调制类型的子集。有关数字和模拟调制分类所需的工作流以及用于创建这些波形的技术的深入描述,请参阅示例链接。

绘制每种调制类型代表的实部和虚部振幅。辅助函数helperModClassPlotTimeDomain2这是否。

helperModClassPlotTimeDomain2(数据目录、调制类型、fs)

生成比例图

创建波形的时频表示。这些表示被称为量图。比例图是信号CWT系数的绝对值。要创建比例图,请预计算CWT滤波器组。当使用相同参数获得多个信号的CWT时,预计算CWT滤波器组是首选方法。

在生成所有的标量图之前,绘制每种调制类型代表的标量图。使用。创建CWT滤波器组cwtfilterbank对于1024个样本的信号,使用滤波器组获取信号的CWT。由于信号是复数,CWT是一个三维数组。第一页是正尺度(分析部分或逆时针分量)的CWT,第二页是负尺度(反分析部分或顺时针分量)的CWT。若要生成比例图,请获取每个页面连接的绝对值。helper函数HelperPlotScaleGrammaSmod2这是否。

helperPlotScalogramsMod2 (dataDirectory modulationTypes frameLength, fs)

如果您下载了培训数据和培训网络,请转至分为培训、测试和验证数据.否则,生成所有的标量图为RGB图像,并将它们写入相应的子目录数据目录.辅助功能helperGenerateCWTfiles2为了与SqueezeNet架构兼容,每个RGB图像都是一个大小为227×227×3的数组。

如果~ downloadData helperGenerateCWTfiles2 (dataDirectory modulationTypes frameLength, fs)结束

分为培训、测试和验证数据

加载标量图图像作为图像数据存储。的图像数据存储函数根据文件夹名称自动标记图像,并将数据存储为ImageDatastore对象。图像数据存储使您能够存储大的图像数据,包括不适合内存的数据,并在训练CNN期间有效地读取批量图像。

文件夹= fullfile (dataDirectory字符串(modulationTypes));imd = imageDatastore(文件夹,...“文件扩展名”“jpg”“标签源”“foldernames”);

将图像随机分为三组,其中80%用于训练,10%用于验证,10%用于测试。我们在网络训练阶段使用训练和验证框架。为了重现性,我们设置了随机种子。

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

如有必要,创建包含经过培训的网络的目录。如果您下载了数据,则结果已存在,且文件waveletModClassNet.mat此目录中包含经过培训的网络。

如果~存在(ResultDir“dir”mkdir (ResultDir)结束MatFile = fullfile (ResultDir,“waveletModClassNet.mat”);

如果您下载了ZIP文件,请加载经过训练的网络,然后继续评估网络.否则,你必须重新培训SqueezeNet。

如果下载数据显示('从文件加载ML模型')负载(MatFile“trainedNet”“imdsValidation”结束
从文件中加载ML模型

SqueezeNet

SqueezeNet是一个经过训练的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=numel(调制类型);newLearnableLayer=convolution2dLayer(1,numClasses,“名字”“new_conv10”); lgraph=replaceLayer(lgraph,lgraph.Layers(end-4).Name,newLearnableLayer);

将分类层替换为不带类别标签的新分类层。该层的输出类别在培训时自动设置。显示最后五个层以确认更改。

newClassLayer = classificationLayer (“名字”“新类输出”);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] 2 'relu_conv10' ReLU ReLU 3 'pool10' Global Average Pooling Global Average Pooling 4 ' prox ' Softmax Softmax 5 'new_classoutput' Classification Output crossentropyex . png

训练CNN

训练神经网络是一个迭代过程,涉及到最小化损失函数。使用培训选项(深度学习工具箱)功能指定训练过程的选项,以确保良好的网络性能。指的是培训选项每个选项的说明文档。

OptimSolver =“亚当”;MiniBatchSize = 50;MaxEpochs = 20;InitialLearnRate = 1的军医;洗牌=“每个时代”;选择= trainingOptions (OptimSolver,...“MiniBatchSize”,小批量,...“MaxEpochs”,MaxEpochs,...“InitialLearnRate”,InitialLearnRate,...“洗牌”洗牌,...“冗长”错误的...“阴谋”“训练进步”...“验证数据”,IMDSV验证);

保存结构中的所有参数。经过训练的网络和结构将在以后保存在.mat文件。

TrialParameter.OptimSolver=OptimSolver;TrialParameter.MiniBatchSize=MiniBatchSize;TrialParameter.MaxEpochs=MaxEpochs;TrialParameter.InitialLearnRate=InitialLearnRate;

将随机种子设置为默认值,并使用trainNetwork(深度学习工具箱)用于训练CNN的函数。保存训练过的网络、试验参数、训练运行时间以及包含验证图像的图像数据存储。由于数据集较大,此过程将花费数分钟。默认情况下,如果GPU可用,则在GPU上完成训练。使用GPU需要并行计算工具箱™. 要查看支持哪些GPU,请参阅金宝appGPU版金宝app本支持(并行计算工具箱).否则,训练将在CPU上进行。图中的训练精度图显示了网络在所有迭代中学习的进度。

如果~下载数据rng默认的抽搐;trainedNet = trainNetwork (imdsTrain、lgraph选项);trainingTime = toc;流('总培训时间:%.2e秒\n', trainingTime);保存(MatFile,“TrialParameter”“trainedNet”“培训时间”“imdsValidation”);结束

评估网络

加载.mat包含训练网络和训练参数的文件。只保存单独训练过的网络.mat文件。这个文件将被CUDA可执行文件使用。

OutMatFile =“mdwv_model.mat”;数据=加载(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(modaccurity)];ccDCNN.com摘要=“column-normalized”;ccDCNN.row摘要=“行规范化”;AccFigFile = fullfile (ResultDir,“网络验证准确性。图”);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(图像大小);tic;[YPred,probs]=分类(trainedNet,x);PredTime(i)=toc;结束AvgPredTimePerImage =意味着(PredTime);流('平均预测时间:%.2e秒\n',AvgPredTimePerImage);
平均预测时间:8.41e-02秒

保存结果。

如果~下载数据保存(MatFile,“modAccuracy”“ccDCNN”“赛前”“ModelMemSize”...“AvgPredTimePerImage”“添加”结束

GPU代码生成-定义函数

信号的标量图是深度CNN的输入“图像”。创建一个函数,cwtModType,它计算复值波形的标量图,并返回用户指定尺寸的图像。图像使用飞机(128)colormap。出于代码生成的目的,将输入信号视为1024 × 2矩阵,其中第一列包含波形样本的实部,第二列包含虚部。的% # codegen指示函数中用于代码生成的函数。当使用coder.gpu.kernelfunpragma,代码生成尝试将计算映射到cwtModType功能到GPU。

类型cwtModType
函数im=cwtModType(inputSig,imgSize)%#codegen%此函数仅用于支持小波深度学习示例。%n它可能会在将来的版本中更改或删除。coder.gpu.k金宝appernel;%输入是1024x2矩阵,将其转换为复数形式(a+1*ib)cinputSig=convertToComplex(inputSig);%小波时频表示[wt,~,~]=cwt(cinputSig,'morse',1,'VoicesPerOctave',48);%从信号cfs=abs([wt(:,:,1);wt(:,:,2)]生成小波时频系数;%连接顺时针和逆时针表示%Image generation im=GenerateImagefromCWTCeff(cfs,imgSize);结束

创建入口点函数,modelPredictModType,用于代码生成。该函数将复数值信号(指定为1024×2矩阵)作为输入,并调用cwtModType函数创建比例图的图像modelPredictModType函数使用中包含的网络mdwv_model文件对波形进行分类。

类型modelPredictModType
函数predClassProb=modelPredictModType(inputSig)%#codegen%此函数仅用于支持小波深度学习示例。%n它可能会在将来的版本中更改或删除。coder.gpu.金宝appkernelfun();%输入信号大小为1024×2%参数ModelFile='mdwv#model.mat';%保存神经网络模型imSize的文件=[227 227];%深度学习网络的输入图像大小%函数将信号转换为小波时频图像im=cwtModType(inputSig,imSize);%加载经过训练的深度学习网络持久化模型;如果isempty(model)model=coder.loadDeepLearningNetwork(ModelFile,'mynet');end%预测信号调制predClassProb=模型。预测(im);end

要生成可部署到NVIDIA目标的CUDA可执行文件,请创建自定义主文件(main_mod_jetson.cu)和头文件(main_mod_jetson.h)。您可以生成一个示例主文件,并将其用作重写新主文件和头文件的模板。有关更多信息,请参阅GenerateExampleMain的属性coder.CodeConfig(MATLAB编码器). 主文件调用为MATLAB入口点函数生成的代码。主文件首先从文本文件读取波形信号,将数据传递给入口点函数,并将预测结果写入文本文件(predClassProb.txt).为了在GPU上最大化计算效率,可执行文件处理单精度数据。

如果要查看主文件和头文件的内容,请设置viewFiles这是真的。

viewFiles =如果viewFiles类型main_mod_jetson.cu结束如果viewFiles类型main_mod_jetson.h结束

GPU代码生成-连接到硬件

要与NVIDIA硬件通信,您可以使用杰森功能。要创建实时硬件连接对象,必须知道目标板的主机名或IP地址、用户名和密码。

为Jetson硬件创建实时硬件连接对象。在硬件实时对象创建过程中,检查硬件、IO服务器安装和收集目标上的外围设备信息。此信息显示在命令窗口中。

hwobj=jetson(“gpucoder-nano-2”ubuntu的ubuntu的);
检查CUDA在目标上的可用性…在目标系统路径中检查'nvcc'…检查cuDNN库在目标上的可用性…在Target上检查TensorRT库的可用性…检查先决库已经完成。收集硬件信息…在Target上检查第三方库的可用性…收集硬件细节已经完成。NVIDIA Jetson TX1, NVIDIA Jetson Nano CUDA版本:10.0 cuDNN版本:7.3 TensorRT版本:5.0 GStreamer版本:1.14.5 V4L2版本:1.14.1 -1 SDL版本:1.2可用的Webcams:可用的gpu: NVIDIA Tegra X1

使用coder.checkGpuInstall(GPU编码器)函数并验证运行此示例所需的编译器和库是否在硬件上正确设置。

envCfg=coder.gpuEnvConfig(“杰森”);envCfg。DeepLibTarget =“cudnn”;envCfg.DeepCodegen=1;envCfg.HardwareObject=hwobj;envCfg.Quiet=1;coder.checkGpuInstall(envCfg)
ans =结构体字段:Gpu: 1 cuda: 1 cudnn: 1 tensorrt: 0 basiccodegen: 0 basiccodeexec: 0 deepcodegen: 1 deepcodeexec: 0 tensorrtdatatype: 0 profiling: 0

GPU代码生成-指定目标

要创建可部署到目标设备的可执行文件,请设置编码模式等于1。如果要创建本地运行并远程连接到目标设备的可执行文件,请设置编码模式等于2。Jetson_BuildDir指定在目标上执行远程生成过程的目录。如果目标上不存在指定的生成目录,则软件将创建具有给定名称的目录。

CodeGenMode =1; 功能_至_Gen=“modelPredictModType”;ModFile=“mdwv_model.mat”%保存神经网络模型的文件;与“main_mod_jetson.cu”一致ImgSize=[227 227];%ML模型的输入图像大小捷信大厦=“~/projectMDWV”

创建编译所需的GPU代码配置对象。使用编码器硬件函数为Jetson平台创建配置对象并将其分配给硬件代码配置对象的属性cfg.使用英伟达杰森的用于Jetson TX1或TX2板。自定义主文件是在生成的代码中调用入口点函数的包装器。自定义文件是部署的可执行文件所必需的。

使用coder.DeepLearningConfig(GPU编码器)函数创建CuDNN的深度学习配置对象,并将其分配给深度学习配置图形处理器代码配置对象的属性。代码生成器利用NVIDIA®CUDA®深神经网络库(cuDNN)为NVIDIA gpu。cuDNN是一个gpu加速的深度神经网络原语库。

如果CodeGenMode == 1 cfg = code . gpuconfig (exe”);cfg.Hardware=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.Hardware=coder.Hardware(英伟达杰森的);cfg.Hardware.BuildDir=Jetson_BuildDir;cfg.DeepLearningConfig=coder.DeepLearningConfig(“cudnn”);结束

GPU代码生成-编译

要生成CUDA代码,请使用codegen函数,并传递图形处理器代码配置以及输入的大小和类型modelPredictModType入口点函数。在主机上完成代码生成后,将复制生成的文件并在目标上构建。

codegen (“配置”cfg Function_to_Gen,“参数”,{single(one(1024,2))},“-报告”);
代码生成成功:查看报告

GPU代码生成-选择信号

CUDA可执行文件通过生成复数波形的标度图并将重新训练的CNN应用于标度图来执行调制分类。选择本例开头生成的波形。从每种调制类型的5000帧中,选择通过设置生成的前50帧之一波数.绘制帧的实部和虚部,以及由此生成的比例图。使用helper函数HelperPlot波形和比例图.中可以找到此helper函数的源代码金宝app支持功能小节。

波形=modTypesList (6);波数=1;signal_data=HelperPlotWaveformandScalgram(数据目录、波形、波数);

如果编译了要部署到目标的可执行文件,则将选择的信号写入文本文件信号文件.使用putFile()硬件对象在目标上放置文本文件的函数workspaceDir属性包含codegen文件夹在目标上。的主要的可执行文件中的函数从指定的文本文件中读取数据信号文件并将分类结果写入结果文件

信号文件=“signalData.txt”;结果文件=“predClassProb.txt”%与“main_mod_jetson.cu”一致如果CodeGenMode==1 fid=fopen(信号文件,' w ');I = 1:length(signal_data) fprintf(fid,“% f \ n”,实(信号_数据(i));结束I = 1:length(signal_data) fprintf(fid,“% f \ n”,imag(信号_数据(i));结束fclose(fid);hwobj.putFile(signalFile,hwobj.workspaceDir);结束

GPU代码生成-执行

运行可执行文件。

在运行部署的可执行文件时,如果前面的结果文件存在,请删除它。使用运行应用程序()函数在目标硬件上启动可执行文件,然后getFile()函数检索结果。因为结果可能不会立即存在运行应用程序()函数调用返回,为了考虑到通信延迟,将获取结果的最大时间设置为90秒。使用evalc函数以抑制命令行输出。

如果CodeGenMode = = 1%运行部署的可执行文件maxFetchTime=90;resultFile_hw=fullfile(hwobj.workspaceDir,resultFile);如果ispc结果文件\u hw=strrep(结果文件\u hw,'\'' / ');结束ta =抽搐;hwobj.deleteFile resultFile_hw evalc ('hwobj.runApplication(函数到生成,信号文件)');tf =抽搐;成功= false;虽然toc (tf) < maxFetchTime尝试评估('hwobj.getFile(resultFile_hw)'); 成功=真实;接住结束如果成功打破结束结束流('获取时间= %。3 e秒\ n”,toc(tf));断言(成功),'无法获取预测')PredClassProb=读取矩阵(结果文件);PredTime=toc(ta);elseifCodeGenMode = = 2%运行PIL可执行文件sigData=[real(信号数据)';imag(信号数据)'”;ta=tic;eval(sprintf(' PredClassProb = % s_pil(单(sigData));“,功能_至_根));PredTime=toc(ta);评估(短跑)(“清楚% s_pil;”Function_to_Gen));%终止PIL执行结束
提取时间=4.852e+00秒

GPU的代码生成-显示结果

结果文件包含分类结果。对于每种可能的调制类型,网络分配了信号属于该类型的概率。显示所选调制类型。使用辅助功能helperPredViz以显示分类结果。

如果CodeGenMode == 1%读取获取的预测结果文件elseifCodeGenMode==2 helperPredVizPil(PredClassProb)%读取工作区变量结束

流('预期波形:%s\n'波形);
将波形:B-FM

总结

这个例子展示了如何创建和部署CUDA可执行文件,它使用CNN来执行调制分类。您还可以选择创建一个可执行文件,在本地运行并连接到远程目标。在这个例子中给出了一个完整的工作流。数据下载后,使用CWT从波形中提取特征。然后,SqueezeNet再接受训练,根据信号的尺度图对信号进行分类。在目标NVIDIA设备上创建并编译两个用户定义函数。将可执行程序的结果与MATLAB进行了比较。

金宝app支持功能

HelperPlot波形和比例图

作用sig = helperPlotWaveFormAndScalogram (dataDirectory wvType wvNum)%此函数仅用于支持小波深度学习示例。金宝app%它可能会在未来的版本中改变或被删除。waveFileName = sprintf (“% s % 05 d.mat帧”,wvType,wvNum);加载(fullfile(dataDirectory,wvType,waveFileName),“帧”);sig=帧;cfs=cwt(sig,“莫尔斯”1.“VoicesPerOctave”48岁);cfs = abs ([cfs(:,: 1);慢性疲劳综合症(:,:2)));次要情节(211)情节(真实(帧)在…上情节(图像放大(帧)牢固的传奇(“真的”“Imag”) STR = sprintf('波形:%s /帧:%d\n信号'、wvType wvNum);Title (str) subplot(212) imagesc(cfs) Title (“时频表示法”%集合(gca,'xtick',[]);set(gca,“ytick”[]);结束

helperPredVizPil

作用helperPredVizPil (PredClassProb)%此函数仅用于支持小波深度学习示例。金宝app%它可能会在未来的版本中改变或被删除。类名={“16QAM”“B-FM”“BPSK”“CPFSK”“DSB-AM”“GFSK”“PAM4”“SSB-AM”};图形条(PredClassProb)集合(gca,“XTickLabel”,类名)xlabel(“阶级标签”)伊拉贝尔(“概率”)头衔(“调制分类输出”)轴心牢固的网格在…上结束

另请参阅

相关话题