主要内容

用于图像分类的代码生成

这个例子展示了如何从MATLAB®函数生成C代码,该函数使用训练过的分类模型对数字图像进行分类。此示例演示了一个替代工作流利用HOG特征进行数字分类(计算机视觉工具箱).然而,要在该示例中支持代码生成,您可以遵循本示例中的代码生成步骤。

自动图像分类是一种无处不在的工具。例如,训练有素的分类器可以部署在无人机上,自动识别捕获的镜头中的陆地异常情况,或者部署在扫描信件上手写邮政编码的机器上。在后一个示例中,在机器找到邮政编码并存储单个数字图像后,部署的分类器必须猜测图像中有哪些数字,以重建邮政编码。

这个例子展示了如何训练和优化一个多类纠错输出码(ECOC)分类模型,以根据光栅图像中的像素强度对数字进行分类。ECOC模型包含二进制支持向量机(SVM)学习器。然后,这个示例展示了如何生成使用训练过的模型对新图像进行分类的C代码。这些数据是各种字体的扭曲数字合成图像,模拟手写数字。

设置C编译器

要生成C/ c++代码,必须能够访问配置正确的C/ c++编译器。MATLAB Coder™定位并使用一个支持的、已安装的编译器。您可以使用墨西哥人设置查看和更改默认编译器。有关更多细节,请参见改变默认的编译器

假设和限制

生成C代码,MATLAB Coder:

  • 需要一个正确配置的编译器。

  • 要求支持的函数位于您定义的MATLAB函数中。有关基本工作流程,请参见代码生成简介

  • 禁止将对象作为所定义函数的输入参数。

关于最后一个限制,请考虑:

  • 训练过的分类模型是对象

  • MATLAB编码器支持预测使用训练过的模型对观测数据进行分类,但不支持模型拟合

要绕过分类的代码生成限制,可以使用MATLAB训练分类模型,然后将得到的模型对象传递给saveLearnerForCoder.的saveLearnerForCoder函数删除一些预测不需要的属性,然后将训练过的模型作为结构数组保存到磁盘上。与模型一样,结构数组包含用于对新观测结果进行分类的信息。

将模型保存到磁盘后,在MATLAB函数中使用loadLearnerForCoder.的loadLearnerForCoder函数加载保存的结构数组,然后重构模型对象。在MATLAB函数中,为了对观察结果进行分类,可以将模型和预测器数据集(可以是函数的输入参数)传递给预测

分类工作流的代码生成

在将图像分类器部署到设备上之前:

  1. 获取足够数量的标签图像。

  2. 决定从图像中提取哪些特征。

  3. 训练和优化分类模型。该步骤包括选择合适的算法和调优超参数,即训练时模型参数不拟合。

  4. 使用将模型保存到磁盘saveLearnerForCoder

  5. 定义一个函数来对新图像进行分类。函数必须通过using加载模型loadLearnerForCoder,并可以返回标签,如分类分数。

  6. 设置C编译器。

  7. 决定在其中执行生成的代码的环境。

  8. 为函数生成C代码。

加载数据

加载digitimages数据集。

负载digitimages

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

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

rng (1)%的再现性n =大小(图片3);p =元素个数(图片(:,:1));本量利= cvpartition (n,“坚持”, 0.20);idxTrn =培训(cvp);idxTest =测试(cvp);

显示数据中的9个随机图像。

数字j = 1:9 subplot(3,3,j) selectImage = datasample(images,1,3);imshow (selectImage [])结束

重新调节数据

因为原始像素强度变化很大,所以在训练分类模型之前应该对它们的值进行规范化。重新调整像素强度,使其范围在区间[0,1]内。也就是说,假设 p j 是像素强度 j 在图像 .的图像 ,使用以下公式缩放所有像素强度:

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

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

或者,如果您拥有图像处理工具箱™许可证,那么您可以通过使用mat2gray.有关更多细节,请参见mat2gray(图像处理工具箱)

重塑数据

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

将数据重塑为一个矩阵,使预测变量(像素强度)对应列,图像(观察值)对应行。因为重塑按列取元素,必须对其结果进行转置。

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

为了确保预处理数据保持图像,绘制第一个观测图X

图imshow(重塑(X (1:), sqrt (p) * [1]), [],“InitialMagnification”“健康”

提取的特征

计算机视觉工具箱™为图像提供了几种特征提取技术。其中一种技术是定向梯度(HOG)特征的直方图提取。要了解如何使用HOG特征训练ECOC模型,请参见利用HOG特征进行数字分类(计算机视觉工具箱).有关其他支持的技术的详细信息,请参见局部特征检测与提取(计算机视觉工具箱).本例使用重新缩放的像素强度作为预测变量。

训练和优化分类模型

线性支持向量机模型常用于图像数据集的分类。然而,支持向量机是二进制分类器,在数据集中有10个可能的类。

您可以创建多个二进制支持向量机学习者的多类模型使用fitcecocfitcecoc使用编码设计组合多个二进制学习器。默认情况下,fitcecoc应用一对一的设计,它指定训练二元学习者基于对所有类组合的观察。例如,在一个有10个类的问题中,fitcecoc必须训练45个二进制支持向量机模型。

一般来说,在训练分类模型时,应该调优超参数,直到获得满意的泛化误差为止。也就是说,您应该针对特定的超参数集交叉验证模型,然后比较超出折叠的错误分类率。

您可以选择自己的超参数值集,也可以指定来实现贝叶斯优化。(有关贝叶斯优化的一般细节,请参见贝叶斯优化工作流程)。此示例在选定的值网格上执行交叉验证。

为了交叉验证基于训练观察的支持向量机二元学习者的ECOC模型,使用5倍交叉验证。虽然预测值具有相同的范围,但为了避免训练时的数值困难,需要将预测值标准化。优化了ECOC编码设计和支持向量机框约束。使用这些值的所有组合:

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

  • 对于SVM框约束,使用三个对数间隔的值,每个值从0.1到100。

对于所有模型,存储5倍交叉验证误分类率。

编码= {“onevsone”“onevsall”};boxconstraint = logspace(1、2、3);cvLoss =南(元素个数(编码),元素个数(boxconstraint));%的预先配置i = 1:元素个数(编码)j = 1:numel(boxconstraint) t = templateSVM(“BoxConstraint”boxconstraint (j),“标准化”,真正的);CVMdl = fitcecoc (X (idxTrn:), Y (idxTrn),“学习者”t“KFold”5,...“编码”、编码{我});cvLoss (i, j) = kfoldLoss (CVMdl);流('cvLoss =%f用于使用%s编码的模型,并且框约束=%f\n'...cvLoss (i, j),编码{我},boxconstraint (j))结束结束
cvLoss = 0.052083,对于使用单一编码和盒约束的模型,cvLoss = 0.055000,对于使用单一编码和盒约束的模型,cvLoss = 0.050000,对于使用单一编码和盒约束的模型,cvLoss = 0.116667,对于使用单一编码和盒约束的模型,cvLoss = 0.116667,对于使用单一编码和盒约束的模型,cvLoss = 0.123750,对于使用单一编码和盒约束的模型,cvLoss = 0.125000,对于使用单一编码和盒约束的模型,cvLoss =100.000000

确定产生最小误分类率的超参数指标。使用训练数据训练ECOC模型。将训练数据标准化,给出观察到的最优超参数组合。

minCVLoss = min (cvLoss (:))
minCVLoss = 0.0500
linIdx = find(cvLoss == minCVLoss);[bestI, bestJ] = ind2sub(大小(cvLoss), linIdx);bestCoding编码= {bestI}
bestCoding = ' onevsone '
bestBoxConstraint = boxconstraint (bestJ)
bestBoxConstraint = 100
t = templateSVM (“BoxConstraint”bestBoxConstraint,“标准化”,真正的);Mdl = fitcecoc (X (idxTrn:), Y (idxTrn),“学习者”t“编码”, bestCoding);

为测试集图像构造一个混淆矩阵。

testImages = X (idxTest:);testImages testLabels =预测(Mdl);confusionMatrix = confusionchart (Y (idxTest), testLabels);

对角线和非对角线元素分别对应正确分类和错误分类的观测结果。Mdl似乎大部分图像都能正确分类。

如果您对的表现满意Mdl,然后可以继续生成用于预测的代码。否则,可继续调整超参数。例如,您可以尝试使用不同的核函数来训练支持向量机学习者。

将分类模型保存到磁盘

Mdl是预测性分类模型,但必须为代码生成做好准备。保存Mdl到您当前的工作目录使用saveLearnerForCoder

saveLearnerForCoder (Mdl“DigitImagesECOC”

saveLearnerForCoder契约Mdl,将其转换为结构数组,并将其保存在mat文件中DigitImagesECOC.mat

定义代码生成的预测函数

定义一个名为predictDigitECOC.m它的作用如下:

  • 包括代码生成指令% # codegen在函数的某个地方。

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

  • 负载DigitImagesECOC.mat使用loadLearnerForCoder

  • 回归预测标签。

类型predictDigitECOC.m显示predictDigitECOC的内容。m文件
% predictDigitECOC使用ECOC模型对图像中的数字进行分类。% predictDigitECOC使用文件DigitImagesECOC中的紧凑ECOC模型对X行中的28 × 28图像进行分类。Mat,然后%返回label中的类标签。CompactMdl = loadLearnerForCoder(“DigitImagesECOC.mat”);标签=预测(CompactMdl X);结束

注意:如果单击位于此页右上角部分的按钮并在MATLAB中打开此示例,则MATLAB将打开示例文件夹。这个文件夹包括入口点函数文件。

验证预测函数返回相同的测试集标签预测

pfLabels = predictDigitECOC (testImages);verifyPF = isequal (pfLabels testLabels)
verifyPF =逻辑1

isequal返回逻辑1 (真正的),这意味着所有的输入是相等的。的predictDigitECOC产生预期的结果。

决定在哪个环境中执行生成的代码

生成的代码可以运行:

  • 在MATLAB环境中作为C-MEX文件

  • 在MATLAB环境之外作为一个独立的可执行文件

  • 在MATLAB环境之外作为一个共享实用程序链接到另一个独立的可执行文件

这个示例生成一个要在MATLAB环境中运行的MEX文件。生成这样的MEX文件允许您在将函数部署到MATLAB环境之外之前使用MATLAB工具测试生成的代码。在MEX函数中,通过将命令声明为外部使用,可以包括用于验证的代码,但不包括用于代码生成的代码coder.extrinsic(MATLAB编码器).外部命令可以包含不支持代码生成的函数。MEX函数中的所有外部命令都在MATLAB中运行,但是codegen不会为它们生成代码。

如果您计划将代码部署到MATLAB环境之外,那么您必须生成一个独立的可执行文件。指定编译器选择的一种方法是使用配置选择codegen.例如,要生成静态C可执行文件,请指定配置:exe当你打电话codegen.有关设置代码生成选项的详细信息,请参见配置选择codegen(MATLAB编码器)

编译MATLAB函数到MEX文件

编译predictDigitECOC.m到MEX文件使用codegen.指定这些选项:

  • 报告-生成一个编译报告,识别原始的MATLAB代码和相关的文件codegen在代码生成期间创建。

  • arg游戏- MATLAB Coder要求你指定所有函数输入参数的属性。其中一种方法是提供codegen有一个输入值的例子。因此,MATLAB Coder从示例值中推断出属性。指定对应的测试集图像X

codegenpredictDigitECOC报告arg游戏{testImages}
代码生成成功:查看报告

codegen成功生成预测函数的代码。,可以查看报告查看报告链接或输入打开(“codegen /墨西哥人/ predictDigitECOC / html / report.mldatx”)在命令窗口中。如果代码生成不成功,那么报告可以帮助您进行调试。

codegen创建目录pwd / codegen /墨西哥人/ predictDigitECOC,在那里松材线虫病您当前的工作目录。在子目录中,codegen生成(除其他外)mex文件predictDigitECOC_mex.mexw64

验证MEX文件返回的标签是否与预测

mexLabels = predictDigitECOC_mex (testImages);verifyMEX = isequal (mexLabels testLabels)
verifyMEX =逻辑1

isequal返回逻辑1 (真正的),这意味着mex文件产生预期的结果。

另请参阅

|||(MATLAB编码器)

相关的话题

Baidu
map