主要内容

用于预测SVM的固定点代码生成

此示例显示如何为支持向量机(SVM)模型的预测生成定点C / C ++代码。金宝app与通用C / C ++代码生成工作流相比,固定点代码生成需要一个附加步骤,该步骤定义预测所需的变量的定点数据类型。通过使用创建固定点数据类型结构generatelearnerdatatypefcn.,并使用该结构作为输入参数loadlearnerforcoder.在一个入学点函数中。您还可以在生成代码之前优化固定点数据类型。

此流程图显示了定点代码生成工作流程。

  1. 训练SVM模型。

  2. 通过使用保存训练的模型Savelarnerforcoder.

  3. 通过使用由生成的数据类型函数定义预测所需的变量的定点数据类型generatelearnerdatatypefcn.

  4. 定义通过使用两者加载模型的入口点函数loadlearnerforcoder.和结构,然后拨打电话预测函数。

  5. (可选)优化固定点数据类型。

  6. 生成定点C/C++代码。

  7. 验证生成的代码。

步骤5是提高所生成的定点代码的性能的可选步骤。为此,请重复这两个步骤,直到您对代码性能满意:

  1. 通过使用记录变量的最小值和最大值以进行预测buildInstrumentedMex(定点设计师)

  2. 使用仪器使用showinstumastation.cresults.(定点设计师).然后,调优定点数据类型(如果必要的话),以防止溢出和下流,并提高定点代码的精度。

在此工作流中,通过使用生成的数据类型函数定义定点数据类型generatelearnerdatatypefcn..从算法中分离变量的数据类型使测试更简单。您可以通过使用数据类型函数的输入参数以编程方式在浮点和定点之间进行编程数据类型。此外,此工作流程兼容手动固定点转换工作流程(定点设计师)

预处理数据

加载人口普查1994.数据集。该数据集包括来自美国人口普查局的人口统计数据,用于预测个人每年赚50,000美元。

加载人口普查1994.

考虑一个模型,预测员工的薪酬类别,鉴于其年龄,工人阶级,教育水平,资本收益和损失以及每周工作时间的数量。提取感兴趣的变量并使用表保存它们。

台= adultdata (:, {'年龄',“教育数量”,“资本收益”,'capital_loss',“hours_per_week”});

打印表的摘要。

摘要(TBL)
变量:年龄:32561x1双倍值:最小17中位数37最大90教育人数:32561x1双倍值:最小1中位数10最大16资本收益:32561x1双倍值:最小0中位数0最大9999资本损失:32561x1双倍值:最小0中位数0最大4356小时/周:32561x1双倍值:最小1中位数40最大99

变量的尺度不一致。在这种情况下,可以通过指定“标准化”名称 - 值对参数fitcsvm.但是,将标准化的操作添加到固定点代码可以减少精度并提高内存使用。相反,您可以手动标准化数据集,如本示例所示。该示例还介绍了如何在最后检查内存使用。

固定点代码生成不支持表或分类阵列。金宝app所以,定义预测器数据X使用数字矩阵,并定义类标签Y使用逻辑向量。在二进制分类问题中,逻辑向量使用内存的效率最高。

x = table2Array(TBL);Y = AdultData.Salary =='<= 50k';

定义观测权值W

w = adultdata.fnlwgt;

随着模型中的支持向量的数量增加,记忆使用训练模型增加。金宝app为了减少支持向量的数量,您可以使用使用时培训时增金宝app加框约束'boxconstraint'名称 - 值对参数或使用用于培训的分布代表数据。请注意,增加框约束可以导致较长的训练时间,并且使用限制数据集可以降低训练模型的准确性。在此示例中,您可以从数据集中随机示例,并使用用于训练的限制数据。

rng (“默认”)%的再现性[x_sampled,idx] = datasample(x,1000,'代替',错误的);y_sampled = y(idx);w_sampled = w(idx);

使用使用模型来找到加权手段和标准偏差'重量'“标准化”名称值对参数。

tempmdl = fitcsvm(x_sampled,y_sampled,'重量'w_sampled,'骨箱','高斯',“标准化”,真的);mu = tempmdl.mu;sigma = tempmdl.sigma;

如果你不使用“成本”,“之前”, 或者'重量'的名称-值对参数,然后可以通过使用ZScore.函数。

[标准化x_sampled,mu,sigma] = zscore(x_sampled);

通过使用标准化预测器数据西格玛

标准化x =(x-mu)./ sigma;标准化x_sampled =标准化x(idx,:);

您可以使用测试数据集来验证培训的模型并测试仪表后的MEX功能。指定测试数据集并通过使用标准化测试预测器数据西格玛

xtest = table2array(AdutherTest(:,{'年龄',“教育数量”,“资本收益”,'capital_loss',“hours_per_week”}));standardizedXTest = (XTest-mu)。/σ;欧美=成人。工资= ='<= 50k';

火车模型

培训二进制SVM分类模型。

mdl = fitcsvm(标准化x_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”,[standardizedX;standardizedXTest])

generatelearnerdatatypefcn.生成myMdl_数据类型函数。显示内容mymdl_datatype.m.通过使用类型函数。

类型mymdl_datatype.m.
函数T=myMdl\u数据类型(dt)%myMdl\u数据类型定义定点代码生成的数据类型%%T=myMdl\u数据类型(dt)返回数据类型结构T,它为生成用于预测机器学习模型的定点C/C++代码%所需的变量定义%数据类型。T的每个字段包含fi返回的%定点对象。输入参数dt指定定点对象的%DataType属性。将dt指定为“fixed”(默认值)%用于定点代码生成,或将dt指定为“Double”以模拟定点代码的%浮点行为。%%使用输出结构T作为入口点%函数的输入参数和%entry point函数中loadLearnerForCoder的第二个输入参数。有关详细信息,请参阅loadLearnerForCoder。%File:myMdl_数据类型。m%统计和机器学习工具箱版本12.1(R2021a版)%由MATLAB生成,2021年2月23日19:10:54,如果nargin<1 dt=‘固定’;结束%设置定点数学设置fm=fimath('RoundingMethod'、'Floor'、…'OverflowAction'、'Wrap'、…'ProductMode'、'FullPrecision'、…'MaxProductWordLength',128、'SumMode'、'FullPrecision'、…'MaxSumWordLength',128);%预测数据的数据类型T.XDataType=fi([],true,16,11,fm,'DataType',dt);%输出分数T.ScoreDataType=fi([],true,16,14,fm,'DataType',dt);%内部变量%距离平方的数据类型dist=(x-sv)^2对于高斯核G(x,sv)=exp(-dist),%其中x是观测的预测数据,sv是支持向量T.InnerProductDataType=fi([],true,16,6,fm,'DataType',dt);结束金宝app

笔记:如果单击该示例的右上角的按钮并在MATLAB®中打开示例,则MATLAB将打开示例文件夹。此文件夹包含入口点函数文件。

这个myMdl_数据类型函数使用默认字长度(16)并提出最大分数长度,以避免每个变量的默认字长度(16)和安全距(10%)避免溢出。

创建一个结构T通过使用定义固定点数据类型myMdl_数据类型

T=myMdl_数据类型('固定的')
t =结构与字段:XDatatype:[0x0 Embedded.fi] scoringatatype:[0x0嵌入式.fi] InnerProductDattype:[0x0嵌入式.FI]

结构T包括运行所需的名称和内部变量的字段预测函数。每个字段包含一个定点对象,由fi(定点设计师).例如,显示预测器数据的固定点数据类型属性。

t.xdatatype.
ANS = []数据款项:FIRED POINT:二进制点缩放签名:签名WordLength:16 FractionLength:11 roundingMethod:地板溢出:Wrap ProductionMode:FullPrecision MaxProductwordLength:128 Summode:FullPrecision MaxSumwordLength:128

有关生成的函数和结构的更多详细信息,请参阅数据类型功能

定义入口点函数

定义命名的入口点函数myfixedpointpredict这有以下内容:

  • 接受预测的数据X和定点数据类型结构T

  • 使用两者加载训练的SVM分类模型的定点版本loadlearnerforcoder.和结构T.

  • 使用加载的模型预测标签和分数。

功能(标签,分数)= myFixedPointPredict (X, T)%#codegen.Mdl=loadLearnerForCoder(“myMdl”,'数据类型'T);(标签,分数)=预测(Mdl X);结尾

(可选)优化定点数据类型

通过使用优化固定点数据类型buildInstrumentedMexshowinstumastation.cresults..通过使用记录所有命名和内部变量的最小值和最大值buildInstrumentedMex.使用仪器使用showinstumastation.cresults.;然后,根据结果,调整变量的定点数据类型属性。

指定输入参数函数的输入参数类型

的输入参数类型myfixedpointpredict使用2×1个单元格阵列。

ARGS=单元(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);

创建仪表型MEX功能

通过使用创建仪器化的MEX功能buildInstrumentedMex(定点设计师)

  • 使用该输入点函数的输入参数类型-args选择。

  • 通过使用使用的MEX函数名称-O选择。

  • 通过使用来计算直方图-直方图选择。

  • 允许使用完整的代码生成支持金宝app- 探讨选择。

buildInstrumentedMexmyfixedpointpredict-argsARGS-OmyFixedPointPredict\u仪表化-直方图- 探讨
代码成功。

测试仪器型MEX功能

运行仪器化的MEX功能以记录仪器结果。

[labels_fx1,scores_fx1]=myFixedPointPredict_instrumented(X_fx,T);

您可以多次运行录音MEX功能以从各种测试数据集记录结果。使用仪器化的MEX功能使用标准化的东西

xtest_fx = cast(标准化名称,'喜欢',t.xdatatype);[labels_fx1_test,scors_fx1_test] = myfixedpointpredict_instrumented(xtest_fx,t);

查看仪表型MEX功能的结果

称呼showinstumastation.cresults.(定点设计师)打开包含仪器结果的报告。查看模拟最小值和最大值,提出的分数长度,电流范围的百分比和整个数字状态。

显示仪器结果('myfixedpointpredict_instrumented')

中建议的单词长度和分数长度X与那些相同XDataType在结构中T

通过单击查看变量的直方图在这一点变量标签。

窗口包含具有有关变量信息的直方图和对话面板。有关此窗口的信息,请参阅numerictyPescope.(定点设计师)参考页面。

通过使用清除结果clearInstrumentationResults.(定点设计师)

clearInstrumentationResults('myfixedpointpredict_instrumented')

验证仪器函数

比较输出预测myFixedPointPredict\u仪表化

[标签,分数]=预测(Mdl,standardizedX);验证标签1=isequal(标签,标签1)
验证_labels1 =符合逻辑的0

等质量如果返回逻辑1(true)如果标签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_数据类型函数并创建新结构,然后使用新结构生成代码。更新myMdl_数据类型功能,您可以手动修改函数文件中的固定点数据类型(mymdl_datatype.m.)。或者,您可以通过使用来生成功能generatelearnerdatatypefcn.并指定较长的单词长度,如本例所示。有关详细信息,请参见提示

生成一个新的数据类型函数。指定单词长度为32和名称myMdl_数据类型2为生成的函数。

generatelearnerdatatypefcn(“myMdl”,[standardizedX;standardizedXTest],“字”,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_数据类型2函数指定字长32,并建议最大分数长度以避免溢出。

创建一个结构T2.通过使用定义固定点数据类型myMdl_数据类型2

T2 = myMdl_datatype2 ('固定的')
t2 =结构与字段:XDatatype:[0x0 Embedded.fi] scoringatatype:[0x0嵌入式.fi] InnerProductDattype:[0x0嵌入式.FI]

创建一个新的仪表函数,记录结果,并通过使用查看结果buildInstrumentedMexshowinstumastation.cresults.

X_fx2=铸件(标准化X,'喜欢', T2.XDataType);buildInstrumentedMexmyfixedpointpredict-args{x_fx2,coder.constant(t2)}-Omyfixedpointpredict_instrumented2-直方图- 探讨
代码成功。
[labels_fx2,scors_fx2] = myfixedpointpredict_instrumented2(x_fx2,t2);显示仪器结果(“myFixedPointPredict\u instrumented2”)

查看仪器报告,然后清除结果。

clearInstrumentationResults(“myFixedPointPredict\u instrumented2”)

验证myfixedpointpredict_instrumented2

验证\u labels2=isequal(标签,标签\u fx2)
验证_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)的那些。

有关通过检测MATLAB®代码优化定点数据类型的更多详细信息,请参阅参考页buildInstrumentedMex(定点设计师),showinstumastation.cresults.(定点设计师), 和clearInstrumentationResults.(定点设计师),以及例子使用min / max仪器设置数据类型(定点设计师)

生成代码

使用生成入口点函数的代码Codegen..而不是指定用于预测器数据集的可变大小输入,请通过使用指定固定大小的输入Coder.typeof..如果您知道传递给生成的代码的预测器数据集的大小,则优选为固定大小输入的代码用于代码的简单性。

Codegen.myfixedpointpredict-args{coder.typeof(X_fx2[1,5],[0,0]),coder.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),scores_fx(i,:)]=myFixedPointPredict_mex(X_fx2(idx(i),:),T2);结尾验证标签是否相等(标签取样,标签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((scors_fx(:,1)-scores_sampled(:,1))./ scores_sampled(:,1))))
diff_scores = 0.0638.

记忆使用

良好做法是在培训模型之前手动标准化预测器数据。如果你使用“标准化”名称值对参数,然后生成的固定点代码包括标准化操作,这可能导致精度损失并增加内存使用。

如果生成静态库,则可以使用代码生成报告查找生成代码的内存使用情况。指定配置:自由要生成静态库,并使用-报告选项生成代码生成报告。

Codegen.myfixedpointpredict-args{coder.typeof(X_fx2[1,5],[0,0]),coder.Constant(T2)}-Omyfixedpointpredict_lib.配置:自由-报告

在这一点总结在代码生成报告的选项卡上,单击代码指标.函数信息部分显示累积的堆栈大小。

找到模型培训的内存使用'标准化','真',您可以运行以下代码。

mdl = fitcsvm(x_sampled,y_sampled,'重量'w_sampled,'骨箱','高斯',“标准化”,对);saveLearnerForCoder(Mdl,“myMdl”);generatelearnerdatatypefcn(“myMdl”,[X;xtest],“字”,32,'OutputFunctionName',“myMdl_standardize_datatype”)T3=myMdl\u标准化\u数据类型('固定的'); X_fx3=铸件(X_取样,'喜欢', T3.XDataType);Codegen.myfixedpointpredict-args{coder.typeof (X_fx3 [1,5], [0]), coder.Constant (T3)}-OmyFixedPointPredict_standardize_lib配置:自由-报告

另见

|||(定点设计师)|(定点设计师)|(定点设计师)|(定点设计师)|(定点设计师)|(MATLAB编码器)

相关话题