主要内容

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

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

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

加载数据

加载digitimages

负载digitimages.mat

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

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

rng (1);%用于再现性N = size(图片,3);P = numel(images(:,:,1));CVP = cvpartition(n,“坚持”, 0.20);idxTrn = training(cvp);idxTest = test(cvp);

重新调节数据

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

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

X = double(图像);i = 1:n minX = min(min(X(:::,i)));maxX = max(max(X(:::,i)));X(:,:,i) = (X(:,:,i) - minX)/(maxX - minX);结束

重塑数据

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

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

X =重塑(X,[p,n])';

训练和优化分类模型

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

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

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

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

编码= {“onevsone”“onevsall”};Boxconstraint = logspace(-1,2,3);cvLossECOC = nan(数字(编码),数字(boxconstraint));预分配百分比I = 1:数字(编码)j = 1: number (boxconstraint) 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),编码{我},boxconstraint (j))结束结束
使用onevsone编码的cvLossECOC = 0.058333,框约束=0.100000,使用onevsone编码的cvLossECOC = 0.057083,框约束=3.162278,使用onevsone编码的cvLossECOC = 0.050000,框约束=100.000000,使用onevsall编码的cvLossECOC = 0.120417,使用onevsall编码的cvLossECOC =0.100000,使用onevsall编码的cvLossECOC = 0.121667,使用onevsall编码的cvLossECOC = 0.127917,框约束=100.000000

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

n = size(X,1);M = log(n - 1)/log(3);maxnumsplitting = 3.^(2:m);cvLossRF = nan(nummel (maxnumsplitting));i = 1:数字(maxnum) t = templateTree(“MaxNumSplits”maxNumSplits(我),“复制”,真正的);CVMdl = fitcensemble(X(idxTrn,:),Y(idxTrn),“方法”“包”“学习者”t...“KFold”5);cvLossRF(i) = kfoldLoss(CVMdl);流('cvLossRF = %f用于使用%d作为最大分割次数的模型\n'...cvLossRF(我),maxNumSplits(我))结束
cvLossRF = 0.319167,对于使用9作为最大分裂次数的模型,cvLossRF = 0.192917,对于使用27作为最大分裂次数的模型,cvLossRF = 0.066250,对于使用81作为最大分裂次数的模型,cvLossRF = 0.015000,对于使用729作为最大分裂次数的模型,cvLossRF = 0.013333,对于使用2187作为最大分裂次数的模型,cvLossRF = 0.009583

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

minCVLossECOC = min(cvLossECOC(:)))
minCVLossECOC = 0.0500
linIdx = find(cvLossECOC == minCVLossECOC,1);[bestI,bestJ] = ind2sub(size(cvlossecc),linIdx);bestCoding =编码{bestI}
bestCoding = 'onevsone'
bestBoxConstraint = boxconstraint(bestJ)
bestBoxConstraint = 100
minCVLossRF = min(cvLossRF(:))
minCVLossRF = 0.0096
linIdx = find(cvLossRF == minCVLossRF,1);[bestI,bestJ] = ind2sub(size(cvLossRF),linIdx);bestMNS = maxnumsplitting (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 = predict(MdlECOC,testImages);testLabelsRF = predict(MdlRF,testImages);

保存分类模型到磁盘

MdlECOC而且MdlRF是预测性分类模型,但必须为代码生成做好准备。保存MdlECOC而且MdlRF到您当前的工作文件夹使用saveLearnerForCoder

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

为预测创建系统对象

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

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

  • 进行顺序预测一步方法。

  • 强制不改变输入数据的大小。

  • 强制双精度,标量输出。

类型ECOCClassifier.m显示ECOCClassifier的内容。m文件
classdef ECOCClassifier < matlab。从训练好的ECOC模型中预测图像标签% % ECOCCLASSIFIER从% |' digittimagesecoc中加载训练好的ECOC模型。Mat '|,并基于训练过的模型预测新观测值%的标签。ECOC模型在% |' digittimagesecoc中。米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从% |'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函数称为predictDigitECOCSO.m而且predictDigitRFSO.m.功能:

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

  • 接受与图像数据相符的数据X

  • 使用ECOCClassifier而且RFClassifier分别为系统对象。

  • 返回预测的标签。

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

编写MATLAB函数到MEX文件

编译预测函数,以达到更好的测试样本精度的MEX文件使用codegen.属性指定测试集映像arg游戏论点。

如果(minCVLossRF)代码原predictDigitECOCSOarg游戏testImages其他的codegenpredictDigitRFSOarg游戏testImages结束
代码生成成功。

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

如果(minCVLossRF <= minCVLossRF) mexLabels = predictDigitECOCSO_mex(testImages);verifyMEX = sum(mexLabels == testLabelsECOC) == numel(testLabelsECOC)其他的mexLabels = predictDigitRFSO_mex(testImages);verifyMEX = sum(mexLabels == testLabelsRF) == nummel (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 = scalepixelintenties (imdat) % scalepixelintenties缩放图像像素强度% scalepixelintenties缩放图像像素强度%,使得结果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 Multimedia File块加载测试集图像的视频文件。对于视频中的每个图像:

  • “来自多媒体文件”块将图像转换并输出为像素强度的28 × 28矩阵。

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

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

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

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

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

模拟模型。

sim (SimMdlName)

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

如果您还拥有Simulink®Code金宝appr™许可证,则可以从slexClassifyAndDisplayDigitImages.slx在Si金宝appmulink®或从命令行使用slbuild(金宝app模型).详情请参见为模型生成C代码(金宝app仿真软件编码器)

另请参阅

|||

相关的话题