为代码生成指定可变大小的参数
此示例演示了在为分类和回归模型对象的对象函数生成代码时如何指定可变大小的输入参数。可变大小数据是指其大小可能在运行时发生变化的数据。当编译时数据的大小未知时,指定可变大小的输入参数非常方便。此示例还描述了如何在入口点函数中包含名称-值对参数,以及如何在生成代码时指定它们。
有关更详细的代码生成工作流示例,请参见命令行机器学习模型预测的代码生成而且基于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_value
,size_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]);
0
为example_value
Value表示数据类型为双
因为双
为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]);
再一次,0
为example_value
Value表示数据类型为双
因为双
为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
.
另请参阅
codegen
|编码器。常数
|coder.typeof
|learnerCoderConfigurer
|loadLearnerForCoder
|saveLearnerForCoder