一文实现0~9手写数字识别系统

一文实现0~9手写数字识别系统

上一篇《机器学习分类算法之k-近邻代码分析》中,大家后台留言有以下错误:

一文实现0~9手写数字识别系统

在此,统一给大家答复:这是由于Python 3与Python 2之间的割裂以及向下不兼容造成的,iteritems是Python2里的写法,Python3中使用items。出错的童鞋使用的环境是Python3,大家可以查看下自己的Python版本。

后续的代码分享,均使用Python3,如果有Python2和Python3不一致的地方,我会做好标注。

修改后正确的运行结果,如下:

一文实现0~9手写数字识别系统一文实现0~9手写数字识别系统

本节分享的是Peter机器学习实战中2.3示例手写识别系统。怎样一步步构建并使用k-近邻分类器进行数字0~9的手写识别。

一文实现0~9手写数字识别系统

这个图应该不陌生,是经典的识别数字的卷积网络LeNet-5。通过简单的图像处理(处理的都是小patchs,比如28*28或32*32、图像归一化等操作,将像素数据送入卷积网络训练。

一文实现0~9手写数字识别系统


Peter机器学习从数据机器学习角度给了另一种实现手写识别的思路,作为识别数字的入门实现思路之一,还是不错的。也能很好的说明k-近邻分类器的用途。

按照掌握的k-近邻的实现路线,实现手写数字识别大致需要以下过程:

(1)收集数据:图像数据转化成文本数据(虽然文本格式存储图像不能利用内存空间,但是为了方便理解,还是转成文本格式,本文中图像大小采用32*32)

(2)准备数据:编写classify0()函数,将图像格式转换为分类器使用的list格式。另,数据需要分为两部分,一部分作为测试样本,另一部分作为非测试样本,非测试样本是已经完成分类的数据。

(3)分析数据:检查数据,确保数据符合要求。

(4)测试算法:用已知分类的数据和classify0()去测试分类结果与已知分类是否一致

(5)使用算法:从图像中提取数字,并完成数字识别。(此过程《机器学习实战》中没有)


收集数据:将图像转换为测试向

为了方便,直接使用2.3示例中提供的数据,数据情况如下:

一文实现0~9手写数字识别系统

数据目录

一文实现0~9手写数字识别系统

图像数据:如0,2

为了直接使用上一篇中的createDataSet()和classify0(),将每个32*32的二进制图像矩阵转化为1*1024向量。

需要定义函数img2vector,原理比较简单,循环读出32行,写入数字。下面以trainingDigits里的0_0.txt为例:

一文实现0~9手写数字识别系统

测试算法

该过程使用classify0()计算某个图像数据向量与一堆向量哪个向量最相近,便将最相近向量对应的标签作为该图像数据的标签。

算法测试原理:用trainingDigits里的数据做验证,该数据集里的命名方式"数字_该数字第几个实例.txt"。用classify0()测试trainingDigits下每一个数据是否正确。因为要遍历整个数据集文件目录,所以需要引入listdir函数(from os import listdir)。代码由三部分构成,分别是获取trainingDigits的文件目录内容、从文件名中解析出分类数字、classify0()识别出每个文件的分类数字。

一文实现0~9手写数字识别系统

代码实现

一文实现0~9手写数字识别系统

结果


PS:该过程又出现了Python3和Python2的不同之处:print。

python3中print是一个内置函数,有多个参数,而python2中print是一个语法结构;Python2打印时可以不加括号:print 'hello world', Python3则需要加括号   print("hello world")。


使用算法(该部分书本中没有)

写了一个简单的函数useClassify(filename),供大家参考,下面是函数实现:

一文实现0~9手写数字识别系统

小编自己从一副二值化的32*32的图像(数字0)转化为文本格式的数据,拿来做算法使用测试,测试结果如下:

一文实现0~9手写数字识别系统


总结:

数据量大了后,算法的执行效率不高,一是因为占用存储空间,另一个是已知分类数据多的情况下,耗时也会增长。再有k-近邻的原理导致没办法使用表征数据更好的特征。


一文实现0~9手写数字识别系统

理财快讯:如果你没能赶上打新股,那就参与打新债吧!

一文实现0~9手写数字识别系统

欢迎转发到朋友圈或分享给好友