主要内容

图像分类的代码生成

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

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

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

设置C编译器

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

假设和限制

生成C代码,MATLAB Coder:

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

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

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

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

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

  • MATLAB Coder支金宝app持预测使用训练过的模型对观测数据进行分类,但不支持拟合模型金宝app

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

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

分类工作流程的代码生成

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

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

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

  3. 训练和优化分类模型。这一步包括选择合适的算法和调优超参数,即训练过程中模型参数不拟合。

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

  5. 定义一个用于分类新图像的函数。函数必须通过使用加载模型loadLearnerForCoder,并可以返回标签,例如分类分数。

  6. 设置C编译器。

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

  8. 为函数生成C代码。

加载数据

加载digitimages数据集。

负载digitimages

图片是一个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);

显示数据中的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 = double(图像);i = 1:n minX = min(min(X(:::,i)));maxX = max(max(X(:::,i)));X(:,:,i) = (X(:,:,i) - minX)/(maxX - minX);结束

或者,如果您拥有图像处理工具箱™许可证,则可以通过使用将图像的像素强度有效地重新调整为[0,1]mat2gray.详情请参见mat2gray(图像处理工具箱)

重塑数据

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

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

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

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

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

提取的特征

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

训练和优化分类模型

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

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

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

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

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

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

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

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

编码= {“onevsone”“onevsall”};Boxconstraint = logspace(-1,2,3);cvLoss = nan(数字(编码),数字(boxconstraint));预分配百分比I = 1:数字(编码)j = 1: number (boxconstraint) t = templateSVM(“BoxConstraint”boxconstraint (j),“标准化”,真正的);CVMdl = fitcecoc(X(idxTrn,:)),Y(idxTrn),“学习者”t“KFold”5,...“编码”、编码{我});cvLoss(i,j) = kfoldLoss(cvdl);流('cvLoss =%f用于使用%s编码的模型,并且框约束=%f\n'...cvLoss (i, j),编码{我},boxconstraint (j))结束结束
使用onevsone编码的模型cvLoss = 0.052083,盒子约束=0.100000,使用onevsone编码的模型cvLoss = 0.055000,盒子约束=3.162278,使用onevsone编码的模型cvLoss = 0.050000,盒子约束=100.000000,使用onevsall编码的模型cvLoss = 0.116667,使用onevsall编码的模型cvLoss =0.100000,使用onevsall编码的模型cvLoss = 0.123750,盒子约束=3.162278,使用onevsall编码的模型cvLoss = 0.125000,盒子约束=100.000000

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

minCVLoss = min(cvLoss(:))
minCVLoss = 0.0500
linIdx = find(cvLoss == minCVLoss);[bestI,bestJ] = ind2sub(size(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,:);testLabels = predict(Mdl,testImages);confusimatrix = confusichart (Y(idxTest),testLabels);

对角线元素和非对角线元素分别对应于正确分类和错误分类的观测值。Mdl似乎能正确地分类大多数图像。

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

保存分类模型到磁盘

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

saveLearnerForCoder (Mdl“DigitImagesECOC”

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

定义代码生成的预测函数

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

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

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

  • 负载DigitImagesECOC.mat使用loadLearnerForCoder

  • 返回预测的标签。

类型predictDigitECOC.m显示predictDigitECOC的内容。m文件
使用ECOC模型对图像中的数字进行分类% predictDigitECOC使用文件digtimagesecoc中的紧凑ECOC模型对X行的28 × 28图像进行分类。然后%返回label中的类标签。CompactMdl = loadLearnerForCoder(' digittimagesec .mat');label = predict(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编码器).外部命令可以包括不支持代码生成的函数。金宝appMEX函数中的所有外部命令都在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 (真正的),这意味着mexfile会产生预期的结果。

另请参阅

|||(MATLAB编码器)

相关的话题