用于图像分类的代码生成
这个例子展示了如何从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函数中,为了对观察结果进行分类,可以将模型和预测器数据集(可以是函数的输入参数)传递给预测
.
分类工作流的代码生成
在将图像分类器部署到设备上之前:
获取足够数量的标签图像。
决定从图像中提取哪些特征。
训练和优化分类模型。该步骤包括选择合适的算法和调优超参数,即训练时模型参数不拟合。
使用将模型保存到磁盘
saveLearnerForCoder
.定义一个函数来对新图像进行分类。函数必须通过using加载模型
loadLearnerForCoder
,并可以返回标签,如分类分数。设置C编译器。
决定在其中执行生成的代码的环境。
为函数生成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]内。也就是说,假设 是像素强度 在图像 .的图像 ,使用以下公式缩放所有像素强度:
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个可能的类。
您可以创建多个二进制支持向量机学习者的多类模型使用fitcecoc
.fitcecoc
使用编码设计组合多个二进制学习器。默认情况下,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文件产生预期的结果。
另请参阅
saveLearnerForCoder
|loadLearnerForCoder
|预测
|codegen
(MATLAB编码器)