此示例显示如何为支持向量机(SVM)模型的预测生成定点C / C ++代码。万博1manbetx与通用C / C ++代码生成工作流相比,固定点代码生成需要一个附加步骤,该步骤定义预测所需的变量的定点数据类型。通过使用创建固定点数据类型结构generatelearnerdatatypefcn.
,并使用该结构作为输入参数loadLearnerForCoder
在一个入学点函数中。您还可以在生成代码之前优化固定点数据类型。
此流程图显示了定点代码生成工作流程。
训练SVM模型。
通过使用保存训练的模型Savelarnerforcoder.
.
通过使用由生成的数据类型函数定义预测所需的变量的定点数据类型generatelearnerdatatypefcn.
.
定义一个入口点函数,通过使用这两个函数来加载模型loadLearnerForCoder
和结构,然后调用预测
函数。
(可选)优化定点数据类型。
生成固定点C / C ++代码。
验证生成的代码。
步骤5是一个可选步骤,用于改进生成的定点代码的性能。要做到这一点,重复这两个步骤,直到您对代码性能感到满意:
使用方法记录变量的最小值和最大值,用于预测buildinstrumentedmex.
(定点设计师).
使用仪器使用showInstrumentationResults
(定点设计师).然后,调优定点数据类型(如果必要的话),以防止溢出和下流,并提高定点代码的精度。
在此工作流程中,您可以使用从中生成的数据类型函数来定义固定点数据类型generatelearnerdatatypefcn.
.从算法中分离变量的数据类型使测试更简单。您可以通过使用数据类型函数的输入参数以编程方式在浮点和定点之间进行编程数据类型。此外,此工作流程兼容手动固定点转换工作流程(定点设计师).
加载人口普查1994.
数据集。该数据集包括来自美国人口普查局的人口统计数据,用于预测个人每年赚50,000美元。
加载人口普查1994.
考虑一个模型,预测员工的薪酬类别,鉴于其年龄,工人阶级,教育水平,资本收益和损失以及每周工作时间的数量。提取感兴趣的变量并使用表保存它们。
台= adultdata (:, {“年龄”那'教育_num'那'资本收益'那'capital_loss'那'每周几小时'});
打印表的摘要。
摘要(TBL)
变量:年龄:32561x1双重值:min 17中位数37 max 90教育:32561x1双重值:min 1中位数10 max 16 capital_gain:32561x1双重值:min 0中位0 max 99999 capical_loss:32561x1双值:min 0中位0 max 4356HOUDE_PER_WEEK:32561x1双倍值:MIN 1中位数40 MAX 99
变量的尺度不一致。在这种情况下,您可以使用标准化数据来培训模型来指定标准化的数据'标准化'
名称 - 值对参数fitcsvm
.然而,在定点代码中添加标准化操作可能会降低精度并增加内存使用。相反,您可以手动标准化数据集,如本例所示。该示例还描述了如何在最后检查内存使用情况。
固定点代码生成不支持表或分类阵列。万博1manbetx所以,定义预测器数据X
使用数字矩阵,并定义类标签y
使用逻辑向量。逻辑向量在二进制分类问题中最有效地使用内存。
X = table2array(台);Y = adultdata。工资= =“< = 50 k”;
定义观测权值W.
.
w = adultdata.fnlwgt;
随着模型中支持向量数量的增加,训练模型的记忆使用也会增加。万博1manbetx为了减少支持向量的数量,可以在训练时通过使用万博1manbetx“BoxConstraint”
名称 - 值对参数或使用用于培训的分布代表数据。请注意,增加框约束可以导致较长的训练时间,并且使用限制数据集可以降低训练模型的准确性。在此示例中,您可以从数据集中随机示例,并使用用于训练的限制数据。
rng (“默认”)%的再现性[x_sampled,idx] = datasample(x,1000,'代替',错误的);y_sampled = y(idx);w_sampled = w(idx);
通过对模型的训练,得到加权平均值和标准差'重量'
和'标准化'
名称值对参数。
tempmdl = fitcsvm(x_sampled,y_sampled,'重量'w_sampled,'骨箱'那“高斯”那'标准化',真正的);μ= tempMdl.Mu;σ= tempMdl.Sigma;
如果你不使用'成本'
那“之前”
,或'重量'
的名称-值对参数,然后可以通过使用ZScore.
函数。
[标准化x_sampled,mu,sigma] = zscore(x_sampled);
通过使用标准化预测器数据亩
和Sigma.
.
standardizedX = (xμ)。/σ;standardizedX_sampled = standardizedX (idx:);
您可以使用测试数据集来验证经过训练的模型,并测试仪器化的MEX函数。使用指定测试数据集并标准化测试预测器数据亩
和Sigma.
.
xtest = table2array(AdutherTest(:,{“年龄”那'教育_num'那'资本收益'那'capital_loss'那'每周几小时'}));standardizedXTest = (XTest-mu)。/σ;欧美=成人。工资= =“< = 50 k”;
培训二进制SVM分类模型。
Mdl = fitcsvm (standardizedX_sampled Y_sampled,'重量'w_sampled,'骨箱'那“高斯”);
MDL.
是A.ClassificationSVM
模型。
计算培训数据集的分类错误和测试数据集。
损失(MDL,标准化x_sampled,y_sampled)
ans = 0.1663
损失(MDL,标准化标准,ytest)
ans = 0.1905
SVM分类器错误分类约17%的培训数据和19%的测试数据。
将SVM分类模型保存到文件中myMdl.mat
通过使用Savelarnerforcoder.
.
SavelAlnerForCoder(MDL,'mymdl');
采用generatelearnerdatatypefcn.
生成一个函数,定义支持向量机模型预测所需变量的定点数据类型。使用所有可用的预测器数据来获得定点数据类型的真实范围。
generateLearnerDataTypeFcn ('mymdl',[标准化x;标准化标准])
generatelearnerdatatypefcn.
生成mymdl_datatype.
函数。显示mymdl_datatype.m.
通过使用类型
函数。
类型mymdl_datatype.m.
函数t = mymdl_datatype(dt)%mymdl_datatype定义了固定点代码生成%t = mymdl_datatype(dt)的数据类型返回数据类型结构t,该数据类型结构t,其定义生成固定点C / C ++所需的变量的%数据类型代码%以预测机器学习模型。每个T的每个字段都包含FI返回的%固定点对象。输入参数DT指定“固定点”对象的%DataType属性。将DT指定为“固定”(默认)为固定点代码生成或指定DT为“双”以模拟固定点代码的%浮点行为。%%使用输出结构t作为入口点%函数的输入参数和%入口点函数中的loadlearnerforcoder的第二个输入参数。有关更多信息,请参阅LoadLearnerForCoder。%文件:mymdl_datatype.m%统计和机器学习工具箱版本12.1(发布r2021a)%由matlab生成,23-feb-2021 19:10:54如果nargin <1 dt ='固定';END%SET定点数学设置FM = FIMATH('roundingMethod','floor',...'overflowation','wrap',...'productmode','fullprecision',...'maxproductwordlength',128,...'summode','fourprecision',...'maxsumwordlength',128);预测器数据的%数据类型t.xdatatype = fi([],true,16,11,fm,'datatype',dt); % Data type for output score T.ScoreDataType = fi([],true,16,14,fm,'DataType',dt); % Internal variables % Data type of the squared distance dist = (x-sv)^2 for the Gaussian kernel G(x,sv) = exp(-dist), % where x is the predictor data for an observation and sv is a support vector T.InnerProductDataType = fi([],true,16,6,fm,'DataType',dt); end
注意:如果您点击位于此示例右上角部分的按钮,并在MATLAB®中打开示例,则MATLAB将打开示例文件夹。这个文件夹包括入口点函数文件。
这mymdl_datatype.
函数使用默认字长度(16)并提出最大分数长度,以避免每个变量的默认字长度(16)和安全距(10%)避免溢出。
创建一个结构T.
通过使用定义固定点数据类型mymdl_datatype.
.
t = mymdl_datatype('固定的')
t =结构与字段:XDatatype:[0x0 Embedded.fi] scoringatatype:[0x0嵌入式.fi] InnerProductDattype:[0x0嵌入式.FI]
结构T.
包括运行所需的名称和内部变量的字段预测
函数。每个字段包含一个定点对象,由FI.
(定点设计师).例如,显示预测器数据的固定点数据类型属性。
t.xdatatype.
ans = [] DataTypeMode: Fixed-point: binary point scaling signature: Signed WordLength: 16 FractionLength: 11 RoundingMethod: Floor OverflowAction: Wrap ProductMode: FullPrecision MaxProductWordLength: 128 SumMode: FullPrecision MaxSumWordLength: 128
有关生成的函数和结构的更多详细信息,请参阅数据类型功能.
定义命名的入口点函数myFixedPointPredict
这有以下内容:
接受预测数据X
和定点数据类型结构T.
.
使用两者加载训练的SVM分类模型的定点版本loadLearnerForCoder
以及结构T。
使用加载模型预测标签和分数。
功能(标签,分数)= myFixedPointPredict (X, T)% # codegenmdl = loadlearnerforcoder('mymdl'那“数据类型”T);(标签,分数)=预测(Mdl X);结尾
通过使用优化固定点数据类型buildinstrumentedmex.
和showInstrumentationResults
.通过使用记录所有命名和内部变量的最小值和最大值buildinstrumentedmex.
.使用仪器使用showInstrumentationResults
;然后,根据结果调优变量的定点数据类型属性。
指定入口点函数的输入参数类型
的输入参数类型myFixedPointPredict
使用2×1个单元格阵列。
args = cell(2,1);
第一个输入参数是预测器数据。这xdatatype.
结构领域T.
指定预测器数据的定点数据类型。转换X
到指定的类型t.xdatatype.
通过使用投
(定点设计师)函数。
x_fx =施法(标准化x,'像', T.XDataType);
测试数据集不具有与训练数据集相同的大小。指定args {1}
通过使用Coder.typeof.
(MATLAB编码器)因此MEX功能可以采用可变大小的输入。
ARGS {1} = coder.typeof (X_fx、大小(standardizedX) [1,0]);
第二个输入参数是结构T.
,它必须是一个编译时常量。采用编码器.Constant.
(MATLAB编码器)指定T.
在代码生成期间作为常量。
args {2} =编码器.Constant(t);
Create Instrumented MEX函数
通过使用创建仪器化的MEX功能buildinstrumentedmex.
(定点设计师).
使用该输入点函数的输入参数类型- args.
选择。
通过使用使用的MEX函数名称- o
选择。
通过使用来计算直方图- 犹太图
选择。
允许使用完整的代码生成支持万博1manbetx编码器
选择。
buildinstrumentedmex.myFixedPointPredict- args.args.- omyfixedpointpredict_instumented.- 犹太图编码器
代码生成成功。
测试仪器型MEX功能
运行仪器化的MEX功能以记录仪器结果。
[labels_fx1,scors_fx1] = myfixedpointpredict_instrumented(x_fx,t);
您可以多次运行录音MEX功能以从各种测试数据集记录结果。使用仪器化的MEX功能使用标准化的东西
.
Xtest_fx =投(standardizedXTest,'像', T.XDataType);[labels_fx1_test, scores_fx1_test] = myFixedPointPredict_instrumented (Xtest_fx T);
查看仪表型MEX功能的结果
调用showInstrumentationResults
(定点设计师)打开包含测量结果的报告。查看模拟的最小值和最大值,建议的分数长度,当前范围的百分比,和整数状态。
showinstrumentationresults('myfixedpointpredict_instrumented')
中建议的单词长度和分数长度X
和在?xdatatype.
在结构中T.
.
通过单击查看变量的直方图在这一点变量标签。
窗口包含具有有关变量信息的直方图和对话面板。有关此窗口的信息,请参阅numerictyPescope.
(定点设计师)参考页面。
通过使用清除结果clearInstrumentationResults.
(定点设计师).
clearInstrumentationResults('myfixedpointpredict_instrumented')
验证仪器函数
比较预测
和myfixedpointpredict_instumented.
.
[标签,分数] =预测(MDL,标准化x);验证_labels1 = isequal(标签,标签_fx1)
verify_labels1 =逻辑0.
是平等的
返回逻辑1 (true) if标签
和labels_fx1
是平等的。如果标签不等于,则可以根据以下计算错误分类标签的百分比。
diff_labels1 = sum(strcmp(strcmp(labels_fx1),string(标签))== 0)/长度(标签_fx1)* 100
diff_labels1 = 0.1228
找出分数输出之间的最大相对差异。
diff_scores1 = max(abs((scors_fx1.double(:,1)-scores(:,1))./ scores(:1))))
diff_scores1 = 83.0713.
调谐定点数据类型
如果录制的结果显示溢出或下溢,或者您想提高生成的代码的精度,则可以调整固定点数据类型。通过更新来修改固定点数据类型mymdl_datatype.
函数并创建新结构,然后使用新结构生成代码。更新mymdl_datatype.
函数,您可以在函数文件(mymdl_datatype.m.
).或者,您可以使用generatelearnerdatatypefcn.
并指定较长的单词长度,如本例所示。有关详细信息,请参见提示.
生成一个新的数据类型函数。指定单词长度为32和名称mymdl_datatype2.
为生成的函数。
generateLearnerDataTypeFcn ('mymdl',[标准化x;标准化标准,“字”32岁的'OutputFunctionName'那“myMdl_datatype2”)
显示myMdl_datatype2.m
.
类型myMdl_datatype2.m
函数t = mymdl_datatype2(dt)%mymdl_datatype2定义了固定点代码生成的数据类型,生成%%t = mymdl_datatype2(dt)返回数据类型结构t,它为生成固定点C / C ++所需的变量定义%数据类型代码%以预测机器学习模型。每个T的每个字段都包含FI返回的%固定点对象。输入参数DT指定“固定点”对象的%DataType属性。将DT指定为“固定”(默认)为固定点代码生成或指定DT为“双”以模拟固定点代码的%浮点行为。%%使用输出结构t作为入口点%函数的输入参数和%入口点函数中的loadlearnerforcoder的第二个输入参数。有关更多信息,请参阅LoadLearnerForCoder。%文件:mymdl_datatype2.m%统计和机器学习工具箱版本12.1(发布r2021a)%由matlab生成,23-feb-2021 19:12:22如果nargin <1 dt ='固定';END%SET定点数学设置FM = FIMATH('roundingMethod','floor',...'overflowation','wrap',...'productmode','fullprecision',...'maxproductwordlength',128,...'summode','fourprecision',...'maxsumwordlength',128);预测器数据的%数据类型t.xdatatype = fi([],true,32,27,fm,'datatype',dt); % Data type for output score T.ScoreDataType = fi([],true,32,30,fm,'DataType',dt); % Internal variables % Data type of the squared distance dist = (x-sv)^2 for the Gaussian kernel G(x,sv) = exp(-dist), % where x is the predictor data for an observation and sv is a support vector T.InnerProductDataType = fi([],true,32,22,fm,'DataType',dt); end
这mymdl_datatype2.
函数指定字长32并提出最大分数长度以避免溢出。
创建一个结构T2
通过使用定义固定点数据类型mymdl_datatype2.
.
t2 = mymdl_datatype2('固定的')
T2 =结构与字段:XDatatype:[0x0 Embedded.fi] scoringatatype:[0x0嵌入式.fi] InnerProductDattype:[0x0嵌入式.FI]
创建一个新的仪表函数,记录结果,并通过使用查看结果buildinstrumentedmex.
和showInstrumentationResults
.
x_fx2 =施放(标准化x,'像', T2.XDataType);buildinstrumentedmex.myFixedPointPredict- args.{x_fx2,coder.constant(t2)}- omyfixedpointpredict_instrumented2- 犹太图编码器
代码生成成功。
[labels_fx2, scores_fx2] = myFixedPointPredict_instrumented2 (X_fx2, T2);showinstrumentationresults('myfixedpointpredict_instrumented2')
查看仪器报告,然后清除结果。
clearInstrumentationResults('myfixedpointpredict_instrumented2')
核实myfixedpointpredict_instrumented2
.
验证_labels2 = isequal(标签,labels_fx2)
verify_labels2 =逻辑0.
diff_labels2 = sum(strcmp(string(labels_fx2),string(标签))== 0)/ length(labels_fx2)* 100
diff_labels2 = 0.0031
diff_scores2 = max(abs((scores_fx2.double(:,1)-scores(:,1))./ scores(:1)))
diff_scores2 = 2.0602
错误分类标签的百分比diff_labels2.
得分值的相对差异diff_scores2.
小于使用默认字长度生成的先前MEX函数(16)的那些。
有关通过仪器仪表仪器策略优化固定点数据类型的详细信息,请参阅参考页面buildinstrumentedmex.
(定点设计师)那showInstrumentationResults
(定点设计师), 和clearInstrumentationResults.
(定点设计师),以及例子使用Min/Max Instrumentation设置数据类型(定点设计师).
使用生成入口点函数的代码codegen
.而不是指定用于预测器数据集的可变大小输入,请通过使用指定固定大小的输入Coder.typeof.
.如果您知道传递给生成代码的预测器数据集的大小,那么为固定大小的输入生成代码对于代码的简单性更可取。
codegenmyFixedPointPredict- args.{coder.typeof(x_fx2,[1,5],[0,0]),编码器.Constant(T2)}
代码生成成功。
codegen
生成MEX函数myFixedPointPredict_mex
与平台相关的扩展。
你可以验证myFixedPointPredict_mex
以与您验证所录制的MEX功能的方式相同。看看验证仪器函数部分细节。
[labels_sampled, scores_sampled] =预测(Mdl standardizedX_sampled);n =大小(standardizedX_sampled, 1);labels_fx = true (n, 1);scores_fx = 0 (n, 2);为了i = 1:n [labels_fx(i),scors_fx(i,:)] = myfixedpointpredict_mex(x_fx2(idx(i),:),t2);结尾验证_labels = isequal(Labels_sampled,labels_fx)
验证_labels =.逻辑1
diff_labels = sum(strcmp(string(labels_fx),string(labels_sampled))== 0)/ length(labels_fx)* 100
diff_labels = 0
diff_scores = max (abs (scores_fx (: 1) -scores_sampled(: 1))。/ scores_sampled (: 1)))
diff_scores = 0.0638.
良好做法是在培训模型之前手动标准化预测器数据。如果你使用'标准化'
名称-值对参数,然后生成的定点代码包括标准化操作,这可能导致精度损失和内存使用增加。
如果生成静态库,则可以使用代码生成报告找到生成的代码的内存使用。指定-config:lib
要生成静态库,请使用-报告
选择代码生成报告的选项。
codegenmyFixedPointPredict- args.{coder.typeof(x_fx2,[1,5],[0,0]),编码器.Constant(T2)}- omyfixedpointpredict_lib.-config:lib-报告
在总结代码生成报告的选项卡,单击代码指标.函数信息部分显示累积的堆栈大小。
找出训练过的模型的记忆用途“标准化”,“真正的”
,您可以运行以下代码。
Mdl = fitcsvm (X_sampled Y_sampled,'重量'w_sampled,'骨箱'那“高斯”那'标准化',真正的);SavelAlnerForCoder(MDL,'mymdl');generateLearnerDataTypeFcn ('mymdl',[X;xtest],“字”32岁的'OutputFunctionName'那'mymdl_standardize_datatype')t3 = mymdl_standardize_datatype('固定的');x_fx3 = cast(x_sampled,'像', T3.XDataType);codegenmyFixedPointPredict- args.{coder.typeof (X_fx3 [1,5], [0]), coder.Constant (T3)}- omyfixedpointpredict_standardize_lib.-config:lib-报告
generatelearnerdatatypefcn.
|loadLearnerForCoder
|Savelarnerforcoder.
|buildinstrumentedmex.
(定点设计师)|投
(定点设计师)|clearInstrumentationResults.
(定点设计师)|FI.
(定点设计师)|showInstrumentationResults
(定点设计师)|codegen
(MATLAB编码器)