十六、应用实例:图片文字识别
1. 问题描述和流程图
我们希望可以通过扫描图片从提取关键字,这样当我们输入关键字时机器就能帮我们正确找到对应的照片,而不用我们煞费心思去找一些图片,接下来我们就来讲讲**照片OCR流水线(pipeline)**的处理。
我们首先会对图片中含有文字的地方进行检测并提取出来,然后自动将其分割成不同字符并进行分类,正如下面流程图:
2. 滑动窗口
在讲字符检测的具体方法之前,我们先看看是如何对行人进行检测的。
比如我们会从数据集中收集一些82×36的照片即正负样本,其中有包含行人的即y=1,其中有不包括行人的即y=0,然后给机器学习,接下来我们就可以利用滑动窗口对图片进行检测了。
我们会用一个82×36的窗口在图片上滑动,每次滑动的距离就是步长,每次会将窗口中的信息传递给分类器去判断是1还是0,对整张图片检测完后,会换一个更大的窗口再进行滑动检测。这里要注意的是,使用更大的窗口时,要将窗口中的图片转化成82×36的再传入分类器,这样就能找出所有行人了。
所以,我们就可以用检测行人的方法,去检测字符。
我们同样从数据集中找一些正负样本,然后让机器进行学习。
我们在检测文字时同样也用到滑动窗口对图片进行扫描,然后得到上面黑白的图像,区域越白说明这个地方有字符的概率越大。最后在此基础上,使用放大算子,将有白色的地方周围一部分也变为白色,然后舍弃那些白色区域长宽比例与文字不配的地方,将没舍弃的地方框起来即可。接下来,我们再进行字符的分割。
还是同样的方法,从数据集中收集正负样本让机器学习,然后在我们上面框出来的字符中再次进行扫描,将字符分割出来。要注意的是,这里的滑动窗口是一维的。
3. 获取大量数据和人工数据
我们前面知道,一个最可靠去得到高性能机器学习系统的方法是使用一个低偏差高方差的机器学习算法,并且使用庞大的数据集去训练它,但是我们要从哪得到这么多的数据呢,这就要引入人工数据合成概念了。
其中一种方法是,网上有庞大的各种各样的字体库,然后可以从这些字体中剪切一小块字体出来,粘贴到不同的背景上,最终得到一个人工合成的数据集。
另一种方法是,可以从真实的样本中演变出更多的样本,例如可以对其进行图像拉伸等失真操作,得到更多的数据。这种操作也可以用于语音识别应用中,我们可以将一段语音通过失真合成数据例如加一些噪音之类的,从而扩充样本。
当然,进行失真操作时,也要选取有效的失真,比如扭曲图像,但是像上图下面那个通过增加高斯噪声扩充样本的方法不可取,只是改变了每个像素的亮度,跟原来的样本几乎没什么两样。
学完上述内容,你应该静下心好好想想,如果我要获得我现在数据十倍的数据量,我需要花费多少时间,有时候你自己思考一会或者和你的小组成员讨论一会后都会发现,其实所花费的时间并不多,可能就几天时间,但是这样做却能让你的算法性能提高很多。当然,如果你觉得自己做这些工作浪费时间的话,也可以去网上找一些廉价但质量高的网站去帮你进行一些标签标注工作。
4. 上限分析:哪部分管道的接下去做
在你日后的研究中,不希望出现的是当你花了几周或几月之后,才发现某些模块对你的算法性能提升没什么帮助,所以接下来我将为你介绍上限分析(ceiling analysis),指导你哪些模块是值得去花时间研究的。
我们来看看上面这个例子,如果让我们去决定每个部分该投入的精力是多少,这时候就可以引入一个数值标准,例如图像识别的准确率。
假设正常通过机器完成识别的整个系统准确率为72%,接下来我对每个部分接连进行人工处理,先人为选择文本框,再人为分割字符,最后再人为的判断字符,这样我们就分别得到89%、90%和100%的准确率。
然后,我们就可以进行上限分析,每个部分提升的性能有多少,如果提升的高例如人为处理文本框能提升17%的性能,我可以花更多精力在这部分上面,如果提升的少我就不用花太多精力再这上面了。
接下来,我们再看一个人脸识别的例子。
我们首先将图片进行去背景处理,然后利用滑动窗口检测到人脸,再进行眼睛、鼻子和嘴巴的分割,再将这些得到的信息归总于逻辑回归分类器,得到最终的标签。
然后我们同样的对每个模块接连进行人工处理,得到不同的准确率,再通过上限分析,得到哪些模块值得我去花时间,例如上面的人脸处理,提升了5.9%,哪些不值得去花时间,例如去除背景,只提升了0.1%。