摘要:本文详细介绍如何利用MATLAB实现手写数字的识别,其中特征提取过程采用方向梯度直方图(HOG)特征,分类过程采用性能优异的支持向量机(SVM)算法,训练测试数据集为学术及工程上常用的MNIST手写数字数据集,博主为SVM设置了合适的核函数,最终的测试准确率达99%的较高水平。根据训练得到的模型,利用MATLABGUI工具设计了可以手写输入或读取图片进行识别的系统界面,同时可视化图片处理过程及识别结果。本套代码集成了众多机器学习的基础技术,适用性极强(用户可修改图片文件夹实现自定义数据集训练),相信会是一个非常好的学习Demo。本博文目录如下:
机器学习中支持向量机(SVM)算法可谓是个超级经典,也许很多人倾向于使用深度神经网络解决问题,但在博主看来选择何种算法应该取决于具体的机器学习任务,对于复杂程度不高、数据量较少的任务,也许经典的机器学习算法能够更好地解决问题。手写数字识别这一任务要求正确分类出0-9的手写数字图片,最常用的数据集是MNIST,该数据集也是众多论文中经常用来测试对比算法的对象。博主想说的是其实SVM也可以很好地解决这一问题,本文介绍的代码就可以实现99%的测试准确率,所以想借此为大家提供一个学习的Demo共同交流。
在手写板中写入数字后可点击下方保存按钮保存为图片文件,手写输入及读图输入及保存功能的演示动图如下图所示。右侧为图像原图、灰度化处理、二值化处理及特征提取后的图像,方便了解识别的处理过程:
MNIST数据集来自美国国家标准与技术研究所(NationalInstituteofStandardsandTechnology,NIST)。训练集(TrainingSet)由来自250个不同人手写的数字构成,其中50%是高中学生,50%来自人口普查局的工作人员;测试集(TestSet)也是同样比例的手写数字数据。
将下载后的数据集文件放在一个文件夹下,用于后续处理,MNIST数据集文件如下图所示:
由于MNIST的原始文件并非常见的图片格式,因此为了方便后续处理,我们先将这几个文件转化为mat文件,然后逐个读取转换为图像矩阵并保存为图片文件。值得注意的是,我们需按照每条样本数据的标签将其分别放置在不同的文件夹中,如下方式在train文件夹中创建0-9的文件夹用来存放要写入的对应标签的图片:
这里写一个小脚本将数据集图片按标签存入对应文件夹中,其中的mat文件为读取原始数据并转存后的数据集,MNIST每张图片的尺寸均为28×28,所以可以先通过reshape恢复数据尺寸,然后利用imwrite函数写入文件中(路径为对应标签的子文件夹),该部分代码如下:
数据集准备完毕,现在可以通过文件夹读取图片了。在MATLAB中可使用imageDatastore函数方便地批量读取图片集,它通过递归扫描文件夹目录,将每个文件夹名称自动作为图像的标签,该部分代码如下:
trainSetDetail=countEachLabel(trainSet)%训练数据testSetDetail=countEachLabel(testSet)%测试数据执行以上代码运行结果如下:
下面读取几张训练和测试集的图片,显示原始图片帮助我们清楚该数据集的实际情况,按照两行显示:第一行为训练图片,第二行为测试图片,该部分代码如下:
figure;%显示训练、测试图片(第一行是训练图片、第二行是测试图片)subplot(2,5,1);imshow(trainSet.Files{4417});subplot(2,5,2);imshow(trainSet.Files{23696});subplot(2,5,3);imshow(trainSet.Files{31739});subplot(2,5,4);imshow(trainSet.Files{46740});subplot(2,5,5);imshow(trainSet.Files{54784});subplot(2,5,6);imshow(testSet.Files{53});subplot(2,5,7);imshow(testSet.Files{4572});subplot(2,5,8);imshow(testSet.Files{5163});subplot(2,5,9);imshow(testSet.Files{8381});subplot(2,5,10);imshow(testSet.Files{9549});执行该代码可以看到如下的运行结果:
在提取特征前我们对图片进行一些必要的预处理操作,首先读取图片后进行灰度化,然后进行二值化处理,以方便后续的特征提取。这里我们将原始图片和二值化后的图像显示在一个窗口中,其代码如下:
真正用于训练分类器的数据并不是原始图片数据,而是先经过特征提取后得到的特征向量,这里使用的特征类型是HOG,也就是方向梯度直方图。所以这里重要的一点是正确提取出HOG特征,extractHOGFeatures是MATLAB自带的HOG特征提取函数,该函数不仅可以有效提取特征,还可以返回特征的可视化结果以方便展示。这里通过调整每个细胞单元的尺寸大小实现不同尺寸的特征提取,可以通过可视化的结果看到细胞单元的尺寸对图像的形状信息量的影响:
下面我们使用以上提取的HOG特征训练支持向量机,以上的代码只是提取了一张图片的特征,训练前我们对整个训练数据集提取HOG特征并组合,为了方便后面的性能评估,这里对测试数据集也进行特征提取:
%使用混淆矩阵评估结果confMat=confusionmat(testLabels,predictedLabels);dispConfusionMatrix(confMat);%显示混淆矩阵运行结果如下:
以上代码显示了混淆矩阵的结果,但可能还不够直观,下面绘制混淆矩阵图帮助更好了解模型性能:
%绘制混淆矩阵图plotconfusion(testLabels,predictedLabels);运行代码后显示混淆矩阵图如下图所示,每行对角线上的网格(绿色网格)处显示了某类样本预测正确的数目及其占比。右下角网格表示分类的准确率,可以看出该分类器具有98.9%的总体分类准确率。
分类准确率还可以通过以下代码进行计算:
若您想获得博文中涉及的实现完整全部程序文件(包括数据集,m,UI文件等,如下图),这里已打包上传至博主的面包多平台和CSDN下载资源。本资源已上传至面包多网站和CSDN下载资源频道,可以点击以下链接获取,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:
注意:本资源已经过调试通过,下载后可通过MATLABR2020b运行;训练主程序为main_showData.mlx或DigitClassify_HOG_SVM.m文件,测试程序可运行testImage.mlx,要使用GUI界面请运行DigitClassifyUI.m文件(脚本文件可直接运行);其它程序文件大部分为函数而非可直接运行的脚本,使用时请勿直接点击运行!
注:以上两个链接为面包多平台下载链接,CSDN下载资源频道下载链接稍后上传。
由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。如果本博文反响较好,其界面部分也将在下篇博文中介绍,所有涉及的GUI界面程序也会作细致讲解,敬请期待!