Week10 大规模机器学习与OCR应用实例
基于吴恩达《机器学习》课程
参考黄海广的笔记
本篇博客为第十周的内容。
如果我们有一个低方差的模型,增加数据集的规模可以帮助你获得更好的结果。但是刚开始并不知道算法表现如何,直接用大量数据可能会有极大代价。
首先应该做的事是去检查一个这么大规模的训练集是否真的必要,可以绘制学习曲线来帮助判断。
可参考第六周内容《评估、选择、诊断、设计》
如果我们一定需要一个大规模的训练集,我们可以尝试使用随机梯度下降法来代替批量梯度下降法。
在随机梯度下降法中,我们定义代价函数为单一训练样本的代价:
c o s t ( θ , ( x ( i ) , y ( i ) ) ) = 1 2 ( h θ ( x ( i ) ) − y ( i ) ) 2 cost\left( \theta, \left( {x}^{(i)} , {y}^{(i)} \right) \right) = \frac{1}{2}\left( {h}_{\theta}\left({x}^{(i)}\right)-{y}^{{(i)}} \right)^{2} cost(θ,(x(i),y(i)))=21(hθ(x(i))−y(i))2
首先对训练集随机“洗牌”,然后用循环对每一个样本进行一次梯度下降同时更新参数 θ {{\theta }} θ 。一般遍历1-10遍,如果样本量m足够大,遍历一遍就可以得到较好的结果。
算法会逐渐走向全局最小值的位置,但是可能无法站到那个最小值的那一点,而是在最小值点附近徘徊。
小批量梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法,每计算 b b b个训练样本,便更新一次参数 θ {{\theta }} θ 。通常我令 b b b 在2-100(比如取10)之间,可以用向量化的方式来循环 b b b个训练实例效果更好。
在批量梯度下降中,我们可以令代价函数 J J J为迭代次数的函数,绘制图表,根据图表来判断梯度下降是否收敛。但在大规模的训练集下,计算代价函数代价太大了。
在随机梯度下降中,我们在每一次更新 θ {{\theta }} θ 之前都计算一次代价,然后每 x x x次迭代后,求出这 x x x次代价的平均值,然后绘制这些平均值与 x x x次迭代的次数之间的函数。
如果得到一个颠簸不平但是不会明显减少的函数图像(如上面左下图中蓝线所示),我们可以增加 α α α来使得函数更加平缓,也许便能看出是否有下降趋势了。
如果我们得到的曲线不断地上升,那么我们可能会需要选择一个较小的学习率 α α α。
我们也可以令学习率随着迭代次数的增加而减小,例如令:
α = c o n s t 1 i t e r a t i o n N u m b e r + c o n s t 2 \alpha = \frac{const1}{iterationNumber + const2} α=iterationNumber+const2const1
随着我们不断地靠近全局最小值,学习率也不断减小。但是对 α α α进行调整所耗费的计算通常不值得。
在线学习算法指的是对数据流而非离线的静态数据集的学习,例如有持续不断的用户流的在线网站。
与随机梯度下降算法有些类似,在线学习是对当前单个样本进行学习,而不是对一个提前定义的训练集进行循环。对一个数据的学习完成了,便可以丢弃该数据,不需要存储。
这样的算法可以很好的适应用户的倾向性,可以针对用户的当前行为不断地更新模型以适应该用户。
这种算法可以用于新闻推荐、商品推荐、点击率(CTR)预测等。
而且每次交互事件并不只产生一个数据样本,例如,一次给用户推荐3条新闻,用户看了1条,这时算法可以一次从3个实例中学习并更新模型。
如果我们用批量梯度下降算法来求解大规模数据集,我们需要对整个训练集进行循环,计算偏导数和代价,再求和,计算代价非常大。一个解决办法是将数据集分配给不多台计算机,让每一台计算机处理数据集的一个子集,然后我们将计所的结果汇总在求和。这样的方法叫做映射化简(Map Reduce),是一种分布式数据处理方式。
具体而言,如果某个学习算法能够表达为对训练集的函数的求和,那么便能将这个任务分配给多台计算机(或者同一台计算机的不同CPU 核心),以达到加速处理的目的。
很多高级的线性代数函数库已经能够利用多核CPU的多个核心来并行地处理矩阵运算,这也是算法的向量化实现如此重要的缘故(比调用循环快)。
OCR(光学字符识别)所作的事是,从一张给定的图片中识别文字。
为了完成这样的工作,需要采取如下步骤:
文字侦测(Text detection)——将图片上的文字与其他环境对象分离开来
字符切分(Character segmentation)——将文字分割成一个个单一的字符
字符分类(Character classification)——确定每一个字符是什么
一般最后还要进行拼写矫正来处理识别错误的字。
可以用任务流程图来表达这个问题,每一项任务可以由一个单独的小团队来负责解决:
大型机器学习系统往往都是流水线结构,构建时就要考虑好各部分的功能。
滑动窗口是一项用来从图像中抽取对象的技术。
假使我们需要在一张图片中识别行人:
用许多固定尺寸的图片来训练一个能够准确识别行人的模型。
用这个固定尺寸的窗口在我们要进行识别的图片上进行剪裁,将剪裁得到的切片交给模型判断是否为行人,随后在图片上滑动剪裁区域重新进行剪裁,将新剪裁的切片也交给模型进行判断,如此循环直至将图片全部检测完。
完成后,按比例放大剪裁的区域,再以新的尺寸对图片进行剪裁,将新剪裁的切片按比例缩小至模型用的尺寸,交给模型进行判断,如此循环。
滑动窗口技术也被用于文字识别。
文字侦测阶段:首先训练模型能够区分字符与非字符,然后运用滑动窗口技术识别字符,完成了字符的识别后,将识别得出的区域进行一些扩展放大,将重叠的区域进行合并。接着以宽高比作为过滤条件,过滤掉不符合文字宽高的区域。
字符切分阶段:训练一个模型来完成将文字分割成一个个字符,训练集为单个字符的图片和两个相连字符之间的图片。模型训练完后,仍然是使用滑动窗口技术来进行字符识别。
字符分类阶段:利用神经网络、支持向量机或者逻辑回归算法训练一个分类器即可。
如果我们的模型是低方差的,那么获得更多的数据能够有更好的效果。
以我们的文字识别应用为例,我们可以字体网站下载各种字体,然后利用这些不同的字体配上各种不同的随机背景图片,这让我们能够从零获得一个无限大的训练集。
另一种方法是,利用已有的数据对其进行修改,例如将已有的字符图片进行一些扭曲、旋转、模糊处理。但是这些失真需要有意义、有代表性。
获得更多数据的几种方法:
人工数据合成
手动收集、标记数据
众包
在大型机器学习项目中,我们通常需要通过几个步骤才能进行最终的预测,我们如何能够知道哪一部分最值得我们花时间和精力去改善呢?这时就需要上限分析。
文字识别应用中,我们的流程图如下:
流程图中每一部分的输出都是下一部分的输入。
上限分析中,我们选取某部分,手工提供100%正确的输出结果,然后看应用的整体效果提升了多少。
假使我们的例子中总体效果为72%的正确率。令文字侦测部分输出的结果100%正确,发现系统的总体效果从72%提高到了89%。这意味着我们很可能会希望投入时间精力来提高我们的文字侦测部分。
接着我们手动选择数据,让字符切分输出的结果100%正确,发现系统的总体效果只提升了1%,这意味着,我们的字符切分部分可能已经足够好了。
这样对每个部分进行分析,即可知道改善哪个部分效率最高。