分类和代码生成的系统对象
这个例子展示了如何从MATLAB®System对象™生成C代码,该对象通过使用训练过的分类模型对数字图像进行分类。这个例子还展示了如何在Simulink®中使用System对象进行分类。相比MATLAB函数,使用System对象的好处是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]内。具体来说,假设 是像素强度 在图像 .的图像 ,通过使用以下公式重新缩放其所有像素强度:
X =双(图片);为i = 1:n minX = min(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);流('cvLossECOC =%f用于使用%s编码和框约束=%f\n',...cvLossECOC (i, j),编码{我},boxconstraint (j))结束结束
cvLossECOC = 0.058333,对于使用单一编码和盒约束的模型,cvLossECOC = 0.057083,对于使用单一编码和盒约束的模型,cvLossECOC = 0.050000,对于使用单一编码和盒约束的模型,cvLossECOC = 0.120417,对于使用单一编码和盒约束的模型,cvLossECOC = 0.121667,对于使用单一编码和盒约束的模型,cvLossECOC = 0.127917,对于使用单一编码和盒约束的模型,cvLossECOC = 0.162278,对于使用单一编码和盒约束的模型,cvLossECOC = 0.127917
对于随机森林,使用序列中的值来改变最大分割数
.M是这样的
并不比n- 1。若要再现随机预测器选择,请指定“重现”,真的
.
n =大小(X, 1);M = floor(log(n - 1)/log(3));maxNumSplits = 3。^ (2:m);cvLossRF =南(元素个数(maxNumSplits));为i = 1:numel(maxnumslices) 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对于使用243作为最大分裂数的模型cvLossRF = 0.013333对于使用729作为最大分裂数的模型cvLossRF = 0.009583对于使用2187作为最大分裂数的模型
对于每种算法,确定产生最小误分类率的超参数指标。
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从% |'DigitImagesECOC加载经过训练的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从% |'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;标签=(分类器,X)步;结束
类型predictDigitRFSO.m显示predictDigitRFSO的内容。m文件
使用RF Model系统对象% predictDigitRFSO使用系统对象RFClassifier中的紧凑随机森林对X %的行中28 × 28的图像进行分类,%然后返回label中的类标签。分类器= RFClassifier;标签=(分类器,X)步;结束
编译MATLAB函数到MEX文件
将达到较好测试样本精度的预测函数编译到MEX文件中codegen
.方法指定测试集图像arg游戏
论点。
如果(mincvlossoc <= minCVLossRF)代码原predictDigitECOCSOarg游戏testImages其他的codegenpredictDigitRFSOarg游戏testImages结束
代码生成成功。
验证生成的MEX文件产生与MATLAB函数相同的预测。
如果(mincvlossoc <= minCVLossRF) mexLabels = predictDigitECOCSO_mex(testImages);verifyMEX = sum(mexLabels == testLabelsECOC) == numel(testLabelsECOC)其他的mexLabels = predictDigitRFSO_mex (testImages);verifyMEX = sum(mexLabels == testLabelsRF) == numel(testLabelsRF)结束
verifyMEX =逻辑1
verifyMEX
是1
,说明所生成的MEX文件与相应的MATLAB函数所做的预测是相同的。
在Simulink中使用系统对象预测标签
创建一个视频文件,逐帧显示测试集图像。
v = VideoWriter (“testImages.avi”,未压缩的AVI的);v.FrameRate = 1;开放(v);Dim =√(p)*[1 1];为j = 1:size(testImages,1) writeVideo(v,重塑(testImages(j,:),dim));结束关闭(v);
定义一个函数scalePixelIntensities.m
它将RGB图像转换为灰度,然后缩放得到的像素强度,使其值在区间[0,1]内。
类型scalePixelIntensities.m显示scalepixelintensity的内容。m文件
scalepixelintenties缩放图像像素强度% scalepixelintenties缩放图像像素强度%使得结果x是区间[0,1]中的值的行向量。imdat = rgb2gray (imdat);minimdat = min (min (imdat));maximdat = max (max (imdat));X = (imdat - minimdat)/(maximdat - minimdat);结束
加载Simulink®模型slexClassifyAndDisplayDigitImages.slx
.
SimMdlName =“slexClassifyAndDisplayDigitImages”;open_system (SimMdlName);
图中显示了Simulink®模型。在模拟开始时,From Multimedia File块加载测试集图像的视频文件。对于视频中的每张图片:
From Multimedia File块将图像转换并输出到一个28 × 28像素强度的矩阵。
Process Data块通过使用缩放像素强度
scalePixelIntensities.m
,并输出一个缩放强度的1 × 784向量。分类子系统块根据所处理的图像数据预测标签。该块选择最小化分类错误的System对象。在本例中,块选择随机森林。该块输出一个双精度标量标签。
数据类型转换块将标签转换为
int32
标量。Insert Text块将预测的标签嵌入到当前帧中。
To Video Display块显示带注释的帧。
模拟模型。
sim (SimMdlName)
该模型能快速显示所有600张测试集图像及其预测。最后的图像保留在视频显示中。您可以生成预测,并通过单击相应的图像逐一显示它们一步按钮。
如果您也有Simulink®Coder™许可证,那么您可以从slexClassifyAndDisplayDigitImages.slx
在Simulink®或从命令行使用slbuild
(模型).有关更多细节,请参见为模型生成C代码(仿真软件编码器).
另请参阅
loadLearnerForCoder
|saveLearnerForCoder
|预测
|预测