主要内容

图像分类的代码生成

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

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

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

设置你的C编译器

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

假设和限制

生成C代码,MATLAB编码器:

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

  • 需要支持的函数在M金宝appATLAB函数中定义。有关基本工作流,请参见代码生成简介

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

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

  • 训练的分类模型是对象

  • MATLAB编码器支持金宝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 =大小(图片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 =双(图片);minX = min(min(X(:,:,i)));maxX = max (max (X(:,:我)));X(:,:,i) = (X(:,:,i) - minX)/(maxX - minX);结束

或者,如果您有Image Processing Toolbox™许可证,那么您可以通过使用mat2gray.有关详细信息,请参见mat2gray(图像处理工具箱)

重塑数据

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

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

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

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

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

提取的特征

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

训练和优化分类模型

线性支持向量机模型常用于图像数据集的分类。然而,SVM是二元分类器,在数据集中有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 for model using %s coding and box constraint=%f\n'...cvLoss (i, j),编码{我},boxconstraint (j))结束结束
使用onevsone cvLoss = 0.052083的模型编码和盒子使用onevsone约束= 0.100000 cvLoss = 0.055000模型编码和盒子使用onevsone约束= 3.162278 cvLoss = 0.050000模型编码和盒子使用onevsall约束= 100.000000 cvLoss = 0.116667模型编码和盒子约束= 0.100000 cvLoss = 0.123750模型使用onevsall编码和框约束=3.162278 cvLoss = 0.125000的模型使用onevsall编码和框约束=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,然后可以继续生成用于预测的代码。否则,可以继续调整超参数。例如,您可以尝试使用不同的核函数来训练SVM学习者。

保存分类模型到磁盘

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

saveLearnerForCoder (Mdl“DigitImagesECOC”

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

定义代码生成的预测函数

定义一个入口点函数名为predictDigitECOC.m它的作用如下:

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

  • 接受图像数据相称X

  • 负载DigitImagesECOC.mat使用loadLearnerForCoder

  • 回归预测标签。

类型predictDigitECOC.m%显示predictDigitECOC内容。m文件
% predictDigitECOC使用文件DigitImagesECOC中的compact ECOC模型%对X行中28 × 28的图像进行分类。,然后%返回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编码器).外部命令可能包括不支持代码生成的函数。金宝appMEX函数中的所有外部命令都在MATLAB中运行,但是codegen不为它们生成代码。

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

编译MATLAB函数到MEX文件

编译predictDigitECOC.m使用codegen.指定这些选项:

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

  • arg游戏- MATLAB编码器要求你指定所有函数输入参数的属性。做到这一点的一种方法是提供codegen这里有一个输入值的例子。因此,MATLAB编码器从示例值推断属性。指定与之相称的测试集图像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编码器)

相关的话题