文档

为代码生成指定可变大小的参数

此示例演示了在为分类和回归模型对象的对象函数生成代码时如何指定可变大小的输入参数。可变大小数据是指其大小可能在运行时发生变化的数据。当编译时数据的大小未知时,指定可变大小的输入参数非常方便。此示例还描述了如何在入口点函数中包含名称-值对参数,以及如何在生成代码时指定它们。

有关更详细的代码生成工作流示例,请参见命令行机器学习模型预测的代码生成而且基于MATLAB Coder App的机器学习模型预测代码生成

列车分类模型

载入费雪的虹膜数据集。将标签转换为字符矩阵。

负载fisheriris物种= char(物种);

使用整个数据集训练分类树。

Mdl = fitctree(meas,种);

Mdl是一个ClassificationTree模型。

保存模型使用saveLearnerForCoder

将训练过的分类树保存到一个名为ClassTreeIris.mat在当前文件夹中使用saveLearnerForCoder

MdlName =“ClassTreeIris”;saveLearnerForCoder (Mdl MdlName);

定义入口点函数

在当前文件夹中,定义一个名为mypredictTree.m它的作用如下:

  • 接受列对应的测量值并接受有效的名值对参数。

  • 使用加载经过训练的分类树loadLearnerForCoder

  • 从装载的分类树中预测标签和相应的分数、节点号和类号。

您可以通过指定允许可选的名称-值对参数变长度输入宗量作为输入参数。详情请参见可变长度参数列表的代码生成(MATLAB编码器)。

类型mypredictTree.m显示mypredictTree的内容。m文件
% mypredictTree使用名为savedmdl的mat文件%中的分类树预测% n-by-4矩阵x中的n个观察结果的鸢尾物种,然后返回% array标签中的预测结果。每一行x包含鸢尾的花瓣%和萼片的长度和宽度(参见fishiris数据集)。有关其他输出%参数描述,请参见预测参考页。CompactMdl = loadLearnerForCoder(savedmdl);[label,score,node,cnum] = predict(CompactMdl,x,varargin{:});结束

注意:如果您单击位于此页右上角部分的按钮,并在MATLAB®中打开此示例,那么MATLAB®将打开示例文件夹。这个文件夹包括入口点函数文件。

生成代码

指定可变大小的参数

方法确定入口点函数中所有变量的属性,因为C和c++是静态类型语言arg游戏选择codegen

使用编码器。常数指定一个编译时常量输入。

coder.Constant (v)

coder.Constant (v)创建一个编码器。常数类型变量,其值为常量,与v,在代码生成期间。

使用coder.typeof指定一个可变大小的输入。

coder.typeof(example_value, size_vector, variable_dims)

的价值example_valuesize_vector,variable_dims指定生成的代码可以接受的输入数组的属性。

  • 输入数组的数据类型与中的示例值相同example_value

  • size_vector输入数组的数组大小是否对应variable_dims值是

  • size_vector数组大小的上限是否对应variable_dims值是真正的

  • variable_dims指定数组的每个维度的大小是可变的还是固定的。的值真正的(逻辑1)表示对应的维度大小是可变的;的值(逻辑0)表示对应的维度具有固定的大小。

入口点功能mypredictTree接受预测器数据、包含训练过的模型对象的mat文件名和可选的名值对参数。假设您希望为预测器数据生成接受可变大小数组的代码“子树”名称-值对参数,其值为一个可变大小的向量。然后有四个输入参数:预测器数据、mat文件名和“子树”名称-值对参数。

定义一个4乘1的单元格数组,并将入口点函数的每个输入参数类型分配给每个单元格。

ARGS = cell(4,1);

对于第一个输入,使用coder.typeof指定预测器数据变量具有双精度,列数与训练模型时使用的预测器数据相同,但观察数(行)是任意的。

p = numel(mml . predictornames);ARGS{1} = code .typeof(0,[Inf,p],[1,0]);

0example_valueValue表示数据类型为因为为MATLAB默认的数值数据类型。(正,p)size_vector价值和(1,0)variable_dims值表示第一个维度的大小是可变的、无界的,第二个维度的大小是固定的p

第二个输入是mat文件名,它必须是一个编译时常量。使用编码器。常数指定第二个输入的类型。

ARGS{2} = code . constant (MdlName);

的名称和值“子树”名称-值对参数。名称-值对参数的名称必须是编译时常量。

ARGS{3} =编码器。常数(“子树”);

使用coder.typeof的值指定“子树”是双精度行向量,并且行向量大小的上限是马克斯(Mdl.PrunedList)

m = max(mml . prunelist);ARGS{4} = code .typeof(0,[1,m],[0,1]);

再一次,0example_valueValue表示数据类型为因为为MATLAB默认的数值数据类型。(1米)size_vector价值和[0, 1]variable_dims值表示第一个维度的大小固定为1,第二个维度的大小是可变的,其上界为

使用生成代码codegen

从入口点函数生成MEX函数mypredictTree使用单元格数组arg游戏的输入参数类型mypredictTree.方法指定输入参数类型arg游戏选择。方法在生成的入口点函数中指定输出参数的数量-nargout选择。生成代码按照入口点函数定义中出现的顺序包含指定数量的输出参数。

codegenmypredictTreearg游戏arg游戏-nargout2

              

codegen生成MEX函数mypredictTree_mex在当前文件夹中使用与平台相关的扩展。

预测函数接受单精度值、双精度值和“所有”“子树”名称-值对参数。但是,在使用MEX函数进行预测时,只能指定双精度值,因为ARGS {4}是两倍。

验证生成的代码

使用生成的MEX函数和修剪级别1的子树,从训练数据中随机选择15个值,预测标签。将MEX函数的标签与函数预测的标签进行比较预测

rng (“默认”);%用于重现性Xnew = datasample(meas,15);[labelMEX,scoreMEX] = mypredictTree_mex(Xnew,MdlName,“子树”1);[labelPREDICT,scorePREDICT] = predict(Mdl,Xnew,“子树”1);labelPREDICT
labelPREDICT =15x10字符数组'virginica 'virginica 'setosa 'virginica 'versicolor' setosa 'setosa 'versicolor' virginica ' 'setosa ' 'virginica ' 'versicolor' virginica ' '
labelMEX
labelMEX =15x1单元阵列{' virginica}{‘virginica}{‘setosa}{‘virginica}{“癣”}{‘setosa}{‘setosa}{“癣”}{‘virginica}{‘virginica}{‘setosa}{‘virginica}{‘virginica}{“癣”}{' virginica '}

预测标签除数据类型不同外,与MEX功能标签一致。当响应数据类型为字符而且codegen不能确定的值子树是标量,则生成的代码的输出是字符向量的单元格数组。

对于比较,可以进行转换labelsPREDICT到单元格数组并使用isequal

cell_labelPREDICT = cellstr(labelPREDICT);verifyLabel = isequal(label,cell_labelPREDICT)
verifyLabel =逻辑1

isequal返回逻辑1 (真正的),这意味着所有的输入是相等的。

比较第二个输出。scoreMex可能包括四舍五入的差异与scorePREDICT.在本例中,进行比较scoreMEX而且scorePREDICT,允许小的公差。

find(abs(scorepredict - scoremax) > 1e-8)
Ans = 0x1空双列向量

找到之间的绝对差值返回空向量scorePREDICT而且scoreMEX是否大于规定的公差1 e-8.对比证实了scorePREDICT而且scoreMEX在公差范围内相等吗1 e-8

另请参阅

|||||

相关的话题