应用实例:图片OCR
图像光学字符识别(optical character recognition)应用所作的事是,从一张给定的图片中识别文字。
这比从一份扫描文档中识别文字要复杂的多。
为了实现这样的应用,通常要经过以下过程:
- 文字检测(text detection):将图片上的文字与其他环境对象分离开来
- 字符分割(Character segmentation):将文字分割成一个个单一的字符
- 字符分类(Character classification):确定每一个字符是什么
滑动窗口
滑动窗口是一项用来从图像中抽取对象的技术。
图片OCR的第一步是在图片中检测文字,对于图片OCR来说这一步是比较困难的,因为图片中那些文字对应地矩形,其纵横比常常都是有较大的不同的。
为了清楚地理解滑动窗口这一机制,这里用行人检测作为例子。因为对于图片中的行人来说,其纵横比往往都是相似的。
为了建立一个行人检测系统,需要这样做:
首先假设给出的数据集中都是82*36的灰度图
假设现在有一张需要检测的图片,滑动窗口要做的事情就是,在图中按照给定的大小(82*36)随机选取一个矩形块,传给分类器,这时分类器需要去检测这个区域中是否有行人,然后将这个矩形块移动一点点,再进行检测,再移动。如此循环直到图片每个部位都被检测完毕。每次移动的距离被称为步长,显然步长为1像素的时候,是检测效果最好的,但是这样计算代价会非常之大,常用的步长一般在4像素或者8像素,或者更大一些,取决于图片大小以及要检测的对象的大小。
滑动窗口技术也被用于文字识别,首先训练模型能够区分字符与非字符,然后,运用滑动窗口技术识别字符,一旦完成了字符的识别,我们将识别得出的区域进行一些扩展,然后将重叠的区域进行合并。接着我们以宽高比作为过滤条件,过滤掉高度比宽度更大的区域(认为单词的长度通常比高度要大)。下图中绿色的区域是经过这些步骤后被认为是文字的区域,而红色的区域是被忽略的。
上面是文字检测阶段要做的事,接下来要进行的,是字符分割。
需要检测出位于字符之间的空白,存在这样的空白,意味着从这个空白中间切开就可以将两个字符分割开。
同样也可以运用滑动窗口法来进行对象的抽取。
最后字符分类只需要训练一个神经网络或者逻辑回归模型来进行一个多分类即可。
人工数据
提高机器学习系统性能的最具有普适性的方法,是使用更大量级的数据集。问题在于,我们怎样获得数据,数据不总是可以直接获得的,在机器学习领域当中,有一个概念叫做人工数据合成(artificial data synthesis)。
以文字识别应用为例,现代计算机内置有许多不同的字体,甚至还有许多免费的字体下载网,我们可以从这些字体网站下载各种字体,然后利用这些不同的字体配上各种不同的随机背景图片创造出一些用于训练的实例,这让我们能够获得一个近乎无限大的训练集。
能够看出来在文字识别应用当中,人工合成的数据和真实数据其实是非常接近的。这是从无到有创造数据集的方法。
另一种办法是基于已有的数据,引入失真(畸变),例如将已有的字符图片进行一些扭曲、旋转、模糊处理,或者针对语音识别问题,对已有的语音样本加入不同的噪声,等等诸如类的方法,来创造新的数据。
引入失真的一个要点是,这些添加进去的失真元素,应该是在测试集中具有代表性的,就是说,这些畸变后的样本是有可能在实际中出现的,要避免添加完全随机的或者无意义的噪声到数据当中去。
比如这个失真,仅仅只是给每个像素添加了不同的高斯噪声,即改变每个像素的亮度。这种在实际中是完全没有意义的噪声。
需要注意的是:
- 绘制学习曲线,来确保数据量的增加能够提高算法的性能,否则就不需要人工合成大量的数据。
- 如果为了获取更大数据量,所花费的代价太高昂,就没有必要去一味地获取更大量级的数据。但是通常情况下,这个时间不会太长,往往几天时间就能够获取有当前量级10倍以上的数据。获取数据的方法通常有:
- 人工数据合成
- 自行收集、标记数据
- 众包服务(例如Amazon Mechanical Turk),把数据收集的工作交给来自世界各地的人来做,这样有一个缺点就是数据的质量难以得到保证。
系统短板分析
在机器学习的应用中,我们通常需要通过几个步骤才能进行最终的预测,我们如何能够知道哪一部分最值得我们花时间和精力去改善呢?这个问题可以通过上限分析来回答。
还是以图片OCR为例子,流程如下:
流程图中每一部分的输出都是下一部分的输入。
假设经过测试后,发现整个系统最后输出的准确率为72%。
现在对每个部分的数据集都进行单独的一些操作,比如说这里对文字检测部分的数据集进行一些调整,使这部分的准确率达到100%。然后再检测系统的整体准确率,为89%,提升了17%。
然后再对其他部分进行操作,手动选择数据使得字符分割输出的结果为100%正确,发现系统最后的准确率为90%,比起之前仅提升了1%,说明字符分割这部分的性能可能已经足够好了,没有必要花太多的时间和精力去改善。
然后再手动选择数据,让字符分类输出的结果100%正确,发现系统总体效果为100%,又提升了10%。
这意味着在这个例子当中,主要需要对系统的文字检测和字符分类两部分投入更多的精力来优化其性能。