为代码生成指定可变大小的参数
此示例展示了如何在为分类和回归模型对象的对象函数生成代码时指定可变大小的输入参数。可变大小的数据是其大小可能在运行时改变的数据。当您在编译时拥有未知大小的数据时,指定可变大小的输入参数非常方便。此示例还描述如何在入口点函数中包含名称-值对参数,以及如何在生成代码时指定它们。
有关更详细的代码生成工作流示例,请参见命令行机器学习模型预测的代码生成而且利用MATLAB编码器应用程序生成机器学习模型预测的代码.
列车分类模型
加载费雪的虹膜数据集。将标签转换为字符矩阵。
负载fisheriris物种= char(物种);
使用整个数据集训练分类树。
Mdl = fitctree(meas,种);
Mdl
是一个ClassificationTree
模型。
使用保存模型saveLearnerForCoder
将训练好的分类树保存到一个名为ClassTreeIris.mat
在当前文件夹中使用saveLearnerForCoder
.
MdlName =“ClassTreeIris”;saveLearnerForCoder (Mdl MdlName);
定义入口点函数
在当前文件夹中,定义名为mypredictTree.m
它的作用如下:
接受列对应的测量值
量
并接受有效的名值对参数。使用加载训练好的分类树
loadLearnerForCoder
.从加载的分类树中预测标签和相应的分数、节点号和类号。
您可以通过指定允许可选的名称-值对参数变长度输入宗量作为输入参数。详细信息请参见可变长度参数列表的代码生成(MATLAB编码器).
类型mypredictTree.m显示mypredictTree的内容。m文件
function [label,score,node,cnum] = mypredictTree(x,savedmdl,varargin) %#codegen % mypredictTree使用分类树预测虹膜物种% mypredictTree使用mat文件%中名称在savedmdl中的分类树预测% n-by-4矩阵x中n个观测值的虹膜物种,然后返回%数组标签中的预测结果。x的每一行都包含了鸢尾花的花瓣%和萼片的长度和宽度(参见fishiriris数据集)。有关其他输出%参数的描述,请参阅预测参考页。CompactMdl = loadLearnerForCoder(savedmdl);[label,score,node,cnum] = predict(CompactMdl,x,varargin{:});结束
注意:如果单击该页右上方部分的按钮并在MATLAB®中打开此示例,则MATLAB®将打开示例文件夹。此文件夹包括入口点函数文件。
生成代码
指定可变大小的参数
因为C和c++都是静态类型语言,所以必须在编译时使用arg游戏
选择codegen
.
使用编码器。常数
(MATLAB编码器)指定一个编译时常数输入。
coder.Constant (v)
coder.Constant (v)
创建一个编码器。常数
类型变量,其值为常量,与v
,在代码生成期间。
使用coder.typeof
(MATLAB编码器)指定一个可变大小的输入。
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 =数字(Mdl.PredictorNames);ARGS{1} = code .typeof(0,[Inf,p],[1,0]);
0
为example_value
值表示数据类型为双
因为双
是MATLAB默认的数值数据类型。(正,p)
为size_vector
价值和(1,0)
为variable_dims
Value表示第一个维度的大小是可变的、无界的,第二个维度的大小是固定的p
.
第二个输入是mat文件名,它必须是一个编译时常量。使用编码器。常数
指定第二个输入的类型。
ARGS{2} = code . constant (MdlName);
的名称和值“子树”
名称-值对参数。名称-值对参数的名称必须是编译时常量。
ARGS{3} =编码器。常数(“子树”);
使用coder.typeof
的值“子树”
是双精度行向量,行向量大小的上界是多少马克斯(Mdl.PrunedList)
.
m = max(mll . prunelist);ARGS{4} = code .typeof(0,[1,m],[0,1]);
再一次,0
为example_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字符数组“维珍”“维珍”“塞托萨”“维珍”“万紫千红”“塞托萨”“万紫千红”“维珍”“维珍”“塞托萨”“维珍”“维珍”“万紫千红”“维珍”
labelMEX
labelMEX =15 x1细胞{' virginiica '} {' virginiica '} {'setosa'} {' virginiica '} {' vericolor '} {'setosa'} {' vericolor '} {' virginiica '} {' virginiica '} {' veritolor '} {' virginiica '} {' veritolor '} {' virginiica '}
预测标签与MEX函数标签相同,只是数据类型不同。时,响应数据类型为字符
而且codegen
的值不能确定子树
是标量,则生成的代码的输出是字符向量的单元格数组。
对于比较,您可以进行转换labelsPREDICT
到单元格数组并使用isequal
.
cell_labelPREDICT = cellstr(labelPREDICT);verifyLabel = isequal(labelMEX,cell_labelPREDICT)
verifyLabel =逻辑1
isequal
返回逻辑1 (真正的
),这意味着所有的输入都是相等的。
还可以比较第二个输出。scoreMex
可能包括四舍五入的差异与scorePREDICT
.在这种情况下,比较一下scoreMEX
而且scorePREDICT
,允许一个小的公差。
find(abs(scorePREDICT-scoreMEX) > 1e-8)
Ans = 0x1空双列向量
找到
之间的绝对差值,则返回空向量scorePREDICT
而且scoreMEX
不大于规定的公差1 e-8
.这个比较证实了scorePREDICT
而且scoreMEX
在容忍范围内是否相等1 e-8
.
另请参阅
codegen
(MATLAB编码器)|coder.typeof
(MATLAB编码器)|loadLearnerForCoder
|编码器。常数
(MATLAB编码器)|saveLearnerForCoder
|learnerCoderConfigurer