主要内容

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

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

这个例子是基于代码生成图像分类,这是一个替代工作流程使用HOG特征的数字分类(计算机视觉工具箱)

加载数据

加载digitimages

负载digitimages.mat

图片是一个28 * 28 * 3000的数组uint16整数。每一页都是一个数字的光栅图像。每个元素都是一个像素强度。对应的标签在3000乘1的数字向量中Y.要了解更多细节,请输入描述在命令行。

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

RNG(1);%的再现性n =大小(图片3);p =元素个数(图片(:,:1));本量利= 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(X(:,:,i)));maxX = max (max (X(:,:我)));X(:,:,i) = (X(:,:,i) - minX)/(maxX - minX));结束

重塑数据

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

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

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

训练和优化分类模型

交叉验证支持向量机二元学习器的ECOC模型和基于训练观察的随机森林。用5倍交叉验证。

对于ECOC模型,指定预测器标准化和优化分类错误的ECOC编码设计和支持向量机盒约束。探究这些值的所有组合:

  • 对于ECOC编码设计,使用一对一和一对一。

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

编码= {“onevsone”“onevsall”};boxconstraint = logspace(1、2、3);cvLossECOC =南(元素个数(编码),元素个数(boxconstraint));预付款的百分比i = 1:元素个数(编码)j = 1:numel(boxconstraint) t = templateSVM()“BoxConstraint”boxconstraint (j),“标准化”,真正的);CVMdl = fitcecoc (X (idxTrn:), Y (idxTrn),“学习者”t“KFold”5,...“编码”、编码{我});cvLossECOC (i, j) = kfoldLoss (CVMdl);流(“使用%s编码和框约束的模型的cvLossECOC =%f”...cvLossECOC (i, j),编码{我},boxconstraint (j))结束结束
CVLOSSECOC = 0.058333用于使用OneVSONE编码和框约束= 0.057083的型号使用Onevsone编码和框3.162278使用OneVSONE编码和框约束= 0.050000使用OneVSALL编码和框约束模型使用OneVSALL编码和框约束= 3.162278 CVLOSSECOC = 0.127917的型号使用OneVSALL编码和框约束= 100.000000

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

n =大小(X, 1);M = floor(log(n - 1)/log(3));maxNumSplits = 3。^ (2:m);cvLossRF =南(元素个数(maxNumSplits));i = 1:numel(maxnumpartitions) t = templateTree()“MaxNumSplits”maxNumSplits(我),“复制”,真正的);CVMdl = fitcensemble (X (idxTrn:), Y (idxTrn),“方法”“包”“学习者”t...“KFold”5);cvLossRF (i) = kfoldLoss (CVMdl);流('cvLossRF = %f为模型,使用%d作为最大拆分数\n'...cvLossRF(我),maxNumSplits(我))结束
cvLossRF使用9 = 0.319167为模型的最大数量的分裂cvLossRF = 0.192917模型使用27分裂cvLossRF = 0.066250的最大数量的模型使用81作为分裂cvLossRF = 0.015000的最大数量模型使用243作为分裂cvLossRF = 0.013333的最大数量模型使用729的最大数量使用2187作为最大拆分数的模型拆分cvLossRF = 0.009583

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

minCVLossECOC = min (cvLossECOC (:))
minCVLossECOC = 0.0500
linIdx = find(cvLossECOC == minCVLossECOC,1);[bestI, bestJ] = ind2sub(大小(cvLossECOC), linIdx);bestCoding编码= {bestI}
bestCoding = ' onevsone '
bestBoxConstraint = boxconstraint (bestJ)
bestBoxConstraint = 100
minCVLossRF = min (cvLossRF (:))
minCVLossRF = 0.0096
linIdx = find(cvLossRF == minCVLossRF,1);[bestI, bestJ] = ind2sub(大小(cvLossRF), linIdx);bestMNS = maxNumSplits (bestI)
bestMNS = 2187

随机森林具有较小的交叉验证误分类率。

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

t = templateSVM (“BoxConstraint”bestBoxConstraint,“标准化”,真正的);MdlECOC = fitcecoc (X (idxTrn:), Y (idxTrn),“学习者”t“编码”, bestCoding);t = templateTree (“MaxNumSplits”, bestMNS);MdlRF = fitcensemble (X (idxTrn:), Y (idxTrn),“方法”“包”“学习者”t);

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

testImages = X (idxTest:);testLabelsECOC =预测(MdlECOC testImages);testLabelsRF =预测(MdlRF testImages);

保存分类模型到磁盘

mdlecoc.MdlRF是预测分类模型,但是您必须为代码生成准备它们。保存mdlecoc.MdlRF到当前工作文件夹saveLearnerForCoder

saveLearnerForCoder (MdlECOC“DigitImagesECOC”);saveLearnerForCoder (MdlRF“DigitImagesRF”);

创建预测系统对象

创建两个System对象,一个用于ECOC模型,另一个用于随机森林,即:

  • 使用加载先前保存的训练过的模型loadLearnerForCoder

  • 进行连续的预测一步方法。

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

  • 强制双精度标量输出。

类型ECOCClassifier.m显示ECOCClassifier的内容。m文件
classdef ECOCClassifier < matlab。系统% ECOCCLASSIFIER从训练的ECOC模型预测图像标签% % ECOCCLASSIFIER从% |' digittimagesecoc加载训练的ECOC模型。Mat '|,并根据训练的模型预测新的观测值%的标签。在% |' digittimagesecoc中的ECOC模型。米at'| was cross-validated using the training data % in the sample data |digitimages.mat|. properties(Access = private) CompactMdl % The compacted, trained ECOC model end methods(Access = protected) function setupImpl(obj) % Load ECOC model from file obj.CompactMdl = loadLearnerForCoder('DigitImagesECOC'); 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
类型RFClassifier.m% RFClassifier显示内容。m文件
classdef RFClassifier < matlab。系统% RFCLASSIFIER从训练的随机森林中预测图像标签% % RFCLASSIFIER从% |' digimagesrf加载训练的随机森林。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函数调用predictDigitECOCSO.mpredictDigitRFSO.m.功能:

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

  • 接受相应的图像数据X

  • 使用ECOCClassifierRFClassifier分别系统对象。

  • 回归预测标签。

类型predictDigitECOCSO.m%显示predictDigitECOCSO的内容。m文件
函数标签= predictDigitECOCSO (X) % # codegen % predictDigitECOCSO数字使用ECOC模型在图像分类系统对象% predictDigitECOCSO分类28-by-28图像的行X %使用紧凑ECOC模型系统中的对象ECOCClassifier和%然后返回类标签标签。分类器= ECOCClassifier;标签=(分类器,X)步;结束
类型predictDigitRFSO.m%显示predictdigitrfso.m.m文件的内容
函数标签= predictDigitRFSO (X) % # codegen % predictDigitRFSO数字使用射频模型在图像分类系统对象% predictDigitRFSO分类28-by-28图像的行X %使用紧凑的系统对象RFClassifier随机森林,和%然后返回类标签的标签。分类器= RFClassifier;标签=(分类器,X)步;结束

编译MATLAB函数到MEX文件

编译预测函数,以实现更好的测试样例精度到一个MEX文件codegen.方法指定测试集图像arg游戏论点。

如果(minCVLossECOC <= minCVLossRF) codegenpredictDigitECOCSOarg游戏testImages其他的codegenpredictDigitRFSOarg游戏testImages结束
代码生成成功。

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

如果(minCVLossECOC <= minCVLossRF) mexLabels = predictdigitecoso_mex (testimates);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 =√(p)*[1 1];j = 1:大小(testimages,1)writevideo(v,重塑(testimages(j,:),dim));结束关闭(v);

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

类型scalePixelIntensities.m%显示scalepixelintensities.m文件的内容
函数x = scalepixelties (imdat) % scalepixelties缩放图像的像素强度,使得结果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在仿真开始时,来自多媒体文件块加载测试集图像的视频文件。对于视频中的每个图像:

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

  • 过程数据块通过使用缩放像素强度scalePixelIntensities.m,并输出一个1 × 784的按比例强度矢量。

  • 分类子系统块预测给定处理过的图像数据的标签。该块选择了使分类错误最小化的System对象。在本例中,块选择了随机森林。该块输出一个双精度标量标签。

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

  • Insert Text块将预测的标签嵌入到当前帧中。

  • TO键显示块显示注释帧。

模拟模型。

sim (SimMdlName)

该模型可以快速显示所有600张测试集图像及其预测。最后一个图像仍然在视频显示中。单击,可以生成预测并将其与相应的图像一一显示一步按钮。

如果您也有Simulink®Coder金宝app™许可证,那么您可以从生成C代码slexClassifyAndDisplayDigitImages.slx在Si金宝appmulink®或从命令行使用slbuild(金宝app模型).有关详细信息,请参见为模型生成C代码(金宝app仿真软件编码器)

另请参阅

|||

相关的话题