主要内容

分类和代码生成的系统对象

这个例子展示了如何从MATLAB®System对象™生成C代码,该对象通过使用经过训练的分类模型对数字图像进行分类。这个例子还展示了如何在Simulink®中使用System对象进行分类。金宝app使用系统对象而不是MATLAB函数的好处是系统对象更适合处理大量流数据。更多信息请参见什么是系统对象?

本例基于代码生成的图像分类,这是另一种工作流程利用HOG特征进行数字分类(计算机视觉工具箱)

加载数据

加载digitimages

加载digitimages.mat

图片是一个28-×28-by-3000的数组uint16整数。每一页都是一个数字的光栅图像。每个元素都是像素强度。对应的标签在3000 × 1的数字向量中Y.有关详细信息,请输入描述在命令行。

存储观测的数量和预测变量的数量。创建一个指定保留20%数据的数据分区。从数据分区中提取训练和测试集索引。

rng (1);%的再现性n =大小(图像,3);p = numel(图像(:,:,1));cvp = cvpartition(n,“坚持”,0.20);Idxtrn =培训(CVP);iDxtest =测试(CVP);

重新调节数据

重新缩放像素强度,使其在每个图像的区间[0,1]内。具体来说,假设 p j 是像素强度 j 在图像 .对于图像 ,使用以下公式重新调整其所有像素强度:

p j p j - 最小值 j p j 马克斯 j p j - 最小值 j p j

X =双(图片);为了minX = min(min(X(:,:,i))));maxX = max (max (X(:,:我)));X(:,:,i) = (X(:,:,i) - minX)/(maxX - minX);结束

重塑数据

对于代码生成,用于训练的预测数据必须位于数字变量表或数字矩阵的表中。

将数据重塑为矩阵,使预测变量对应于列,图像对应于行。因为重塑按列顺序取元素,将其结果转置。

X =重塑(X, (p, n));

火车和优化分类模型

交叉验证SVM二元学习者的ECOC模型和基于训练观察的随机森林。用5倍交叉验证。

对于ECOC模型,指定预测器标准化,并在ECOC编码设计和SVM盒约束下优化分类误差。探索这些值的所有组合:

  • 对于ECOC编码设计,使用“一对一”和“一对所有”。

  • 对于SVM盒约束,使用从0.1到100的三个对数间隔值。对于所有的模型,存储5倍交叉验证的误分类率。

编码= {“onevsone”'Onevsall'};boxconstraint = logspace(1、2、3);cvLossECOC =南(元素个数(编码),元素个数(boxconstraint));%的预先配置为了i = 1:元素个数(编码)为了j = 1:numel(box) t = templateSVM(“BoxConstraint”boxconstraint (j),“标准化”,真正的);CVMdl = fitcecoc (X (idxTrn:), Y (idxTrn),“学习者”t'kfold'5,...“编码”、编码{我});cvLossECOC (i, j) = kfoldLoss (CVMdl);流('cvlossecoc =%f用于模型使用%s编码和框约束=%f \ n'...cvlossecoc(i,j),编码{i},boxconstraint(j))结束结束
使用onevsone cvLossECOC = 0.058333的模型编码和盒子使用onevsone约束= 0.100000 cvLossECOC = 0.057083模型编码和盒子使用onevsone约束= 3.162278 cvLossECOC = 0.050000模型编码和盒子使用onevsall约束= 100.000000 cvLossECOC = 0.120417模型编码和盒子约束= 0.100000 cvLossECOC =对于使用onevsall编码和box约束的模型,cvLossECOC = 0.121667 =3.162278

对于随机林,通过使用序列中的值来改变最大分割数 3. 2 3. 3. 3. .M是这样 3. 不比n- 1。若要再现随机预测器选择,请指定“重现”,真的

n =尺寸(x,1);m =楼层(日志(n  -  1)/ log(3));maxnumsplits = 3. ^(2:m);cvlossrf = nan(numel(maxnumsplits));为了i = 1:numel(maxnum劈叉)t = templateTree(“MaxNumSplits”,maxnumsplits(i),“复制”,真正的);CVMdl = fitcensemble (X (idxTrn:), Y (idxTrn),“方法”“包”“学习者”t...'kfold'5);cvLossRF (i) = kfoldLoss (CVMdl);流('cvLossRF = %f for model using %d as the maximum number of split \n'...cvlossrf(i),maxnumsplits(i))结束
cvLossRF使用9 = 0.323750为模型的最大数量的分裂cvLossRF = 0.198333模型使用27分裂cvLossRF = 0.075417的最大数量的模型使用81作为分裂cvLossRF = 0.017083的最大数量模型使用243作为分裂cvLossRF = 0.012083的最大数量模型使用729的最大数量split cvLossRF = 0.012083 for model using 2187 as the maximum number of splitting

对于每种算法,确定产生最小错误分类率的超参数指数。

minCVLossECOC = min (cvLossECOC (:))
minCVLossECOC = 0.0500
linidx = find(cvlossecoc == mincvlossecoc,1);[besti,bestj] = Ind2sub(大小(cvlossecoc),linidx);Bestcoding = Coding {Besti}
bestCoding = ' onevsone '
bestBoxConstraint = boxconstraint (bestJ)
bestBoxConstraint = 100
minCVLossRF = min (cvLossRF (:))
minCVLossRF = 0.0121
linIdx = find(cvLossRF == minCVLossRF,1);[bestI, bestJ] = ind2sub(大小(cvLossRF), linIdx);bestMNS = maxNumSplits (bestI)
bestMNS = 729

随机森林达到较小的交叉验证错误分类率。

使用培训数据培训ecoc模型和随机林。提供最佳的超参数组合。

t = templateSVM (“BoxConstraint”bestBoxConstraint,“标准化”,真正的);MdlECOC = fitcecoc (X (idxTrn:), Y (idxTrn),“学习者”t“编码”,最佳崇拜);t = templatetree(“MaxNumSplits”,bestmns);mdlrf = fitcensemble(x(idxtrn,:),y(idxtrn),“方法”“包”“学习者”,t);

为测试样本图像创建一个变量,并使用训练好的模型来预测测试样本标签。

testimages = x(iDxtest,:);testlabelsecoc = predict(mdlecoc,testimages);testlabelsrf = predict(mdlrf,testimages);

将“分类模式”保存到“磁盘”

MdlECOCmdlrf.是预测性分类模型,但是必须为代码生成做好准备。保存MdlECOCmdlrf.使用您的当前工​​作文件夹Savelarnerforcoder.

SavelAlnerForCoder(MDLecoc,“DigitImagesECOC”);saveLearnerForCoder (MdlRF“DigitImagesRF”);

为预测创建系统对象

创建两个系统对象,一个用于ECOC模型,另一个用于随机森林,如下:

  • 使用loadLearnerForCoder

  • 进行连续的预测方法。

  • 不强制对输入数据进行大小更改。

  • 强制双精度标量输出。

类型ECOCClassifier.m%显示ecocclassifier.m文件的内容
ClassDef Ecocclassifier 
              
类型RFClassifier.m%显示rfclassifier.m文件的内容
classdef RFClassifier < matlab。% % RFCLASSIFIER从% |'DigitImagesRF中加载训练好的随机森林。Mat '|,并根据训练模型的%预测新观测的标签。|'DigitImagesRF中的随机森林。米at'| % was cross-validated using the training data in the sample data % |digitimages.mat|. properties(Access = private) CompactMdl % The compacted, trained random forest end methods(Access = protected) function setupImpl(obj) % Load random forest from file obj.CompactMdl = loadLearnerForCoder('DigitImagesRF'); end function y = stepImpl(obj,u) y = predict(obj.CompactMdl,u); end function flag = isInputSizeMutableImpl(obj,index) % Return false if input size is not allowed to change while % system is running flag = false; end function dataout = getOutputDataTypeImpl(~) dataout = 'double'; end function sizeout = getOutputSizeImpl(~) sizeout = [1 1]; end end end

注意:如果您单击此页面右上方的按钮并在MATLAB®中打开此示例,那么MATLAB®将打开示例文件夹。此文件夹包含本例中使用的文件。

系统对象基本要求请参见定义基本系统对象

定义代码生成的预测函数

定义两个MATLAB函数调用预测地迪立索索姆predictDigitRFSO.m.功能:

  • 包含代码生成指令% # codegen

  • 接受与之相称的图像数据X

  • 使用ECOCClassifierRFClassifier分别系统对象。

  • 返回预测标签。

类型预测地迪立索索姆%显示predictDigitECOCSO内容。m文件
函数标签= predictigitecocso(x)%#codegen%predictigigocso使用ecoc模型系统对象%predictigiTecocso使用系统对象eCocclassifier中的Compact Ecoc模型分类x%行中的28×28图像中的28×28图像然后返回标签中的类标签。分类= ecocclassifier;标签=(分类器,X)步;结束
类型predictDigitRFSO.m%显示predictDigitRFSO内容。m文件
函数标签= predictDigitRFSO (X) % # codegen % predictDigitRFSO数字使用射频模型在图像分类系统对象% predictDigitRFSO分类28-by-28图像的行X %使用紧凑的系统对象RFClassifier随机森林,和%然后返回类标签的标签。分类器= RFClassifier;标签=(分类器,X)步;结束

将MATLAB函数编译为MEX文件

将实现较好测试样本精度的预测函数编译到一个MEX文件中codegen.属性指定测试集图像arg游戏论点。

如果(mincvlossecoc <= mincvlossrf)codegen预测附图标准索索arg游戏testImages别的codegenpredictDigitRFSOarg游戏testImages结束

验证生成的MEX文件产生与MATLAB函数相同的预测。

如果(mincvlossecoc <= mincvlossrf)mexlabels = predictdigitecocso_mex(testimages);verifymex = sum(mexlabels == testlabelsecoc)== numel(testlabelsecoc)别的mexlabels = predictdigitrfso_mex(testimages);verifymex = sum(mexlabels == testlabelsrf)== numel(testlabelsrf)结束
verifyMEX =逻辑1

verifyMEX1,表示由生成的MEX文件和相应的MATLAB函数所做的预测是相同的。

在Simulink中使用系统对象预测标签金宝app

创建一个视频文件,逐帧显示测试集图像。

v = VideoWriter ('testimages.avi''未压缩的avi');v.FrameRate = 1;开放(v);Dim = sqrt(p)*[1 1];为了j = 1:size(testImages,1) writeVideo(v,重塑(testImages(j,:),dim));结束关闭(v);

定义一个函数scalepixelintensities.m将RGB图像转换为灰度,然后缩放产生的像素强度,使其值在区间[0,1]内。

类型scalepixelintensities.m%显示scalepixelintensity的内容。m文件
函数x = scalepixelintensity (imdat) % scalepixelintensity缩放图像的像素强度% scalepixelintensity缩放图像的像素强度,使结果x是一个区间[0,1]值的行向量。imdat = rgb2gray (imdat);minimdat = min (min (imdat));maximdat = max (max (imdat));X = (imdat - minimdat)/(maximdat - minimdat);结束

加载Simulin金宝appk®模型slexClassifyAndDisplayDigitImages.slx

simmdlname =“slexClassifyAndDisplayDigitImages”;open_system (SimMdlName);

图中显示了Simulink®模型。金宝app在模拟的开始,从多媒体文件块加载测试集图像的视频文件。对于视频中的每一张图片:

  • 从多媒体文件块转换并输出图像到28 × 28像素强度矩阵。

  • 过程数据块通过使用缩放像素强度scalepixelintensities.m,输出一个1乘784的强度矢量。

  • 分类子系统块预测给定的图像数据的标签。该块选择最小化分类错误的系统对象。在这种情况下,块选择随机林。块输出双精度标量标签。

  • 数据类型转换块将标签转换为int32标量。

  • 插入文本块将预测的标签嵌入到当前帧中。

  • To Video Display块显示带注释的框架。

模拟模型。

SIM(SIMMDLNAME)

该模型可快速显示所有600幅测试集图像及其预测结果。最后的图像保留在视频显示中。您可以生成预测,并将它们与相应的图像一一显示一步按钮代替。

如果您还拥有Simulink®Code金宝appr™许可,那么您可以从slexClassifyAndDisplayDigitImages.slx在Si金宝appmulink®中或从命令行中使用rtwbuild(金宝app仿真软件编码器).更多信息请参见为模型生成C代码(金宝app仿真软件编码器)

也可以看看

|||

相关的话题