如果有一个低方差的模型,增加数据集的规模可以获得更好的结果。应该怎样应对一个有100万条记录的训练集?
以线性回归模型为例,每一次梯度下降迭代,都需要计算训练集的误差的平方和,如果学习算法需要有20次迭代,这便已经是非常大的计算代价。
首先应该做的事是去检查一个这么大规模的训练集是否真的必要,也许只用1000个训练集也能获得较好的效果,可以绘制学习曲线来帮助判断。
如果一定需要一个大规模的训练集,可以尝试使用随机梯度下降法来代替批量梯度下降法。
在随机梯度下降法中,定义代价函数为一个单一训练实例的代价:
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
随机梯度下降算法为:首先对训练集随机“洗牌”,然后:
Repeat (usually anywhere between1-10){
for i = 1 : m i = 1:m i=1:m{
θ : = θ j − α ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta:={\theta}_{j}-\alpha\left( {h}_{\theta}\left({x}^{(i)}\right)-{y}^{(i)} \right){ {x}_{j}}^{(i)} θ:=θj−α(hθ(x(i))−y(i))xj(i)
(for j = 0 : n j=0:n j=0:n)
}
}
随机梯度下降算法在每一次计算之后便更新参数 θ { {\theta }} θ ,而不需要首先将所有的训练集求和,在梯度下降算法还没有完成一次迭代时,随机梯度下降算法便已经走出了很远。但是这样算法存在的问题是,不是每一步都是朝着”正确”的方向迈出。因此算法虽然会逐渐走向全局最小值的位置,但是可能无法站到那个最小值的那一点,而是在最小值点附近徘徊。
小批量梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法,每计算常数 b b b次训练实例,便更新一次参数 θ { {\theta }} θ 。
Repeat {
for i = 1 : m i = 1:m i=1:m{
θ : = θ j − α 1 b ∑ k = i i + b − 1 ( h θ ( x ( k ) ) − y ( k ) ) x j ( k ) \theta:={\theta}_{j}-\alpha\frac{1}{b}\sum_{k=i}^{i+b-1}\left( {h}_{\theta}\left({x}^{(k)}\right)-{y}^{(k)} \right){ {x}_{j}}^{(k)} θ:=θj−αb1∑k=ii+b−1(hθ(x(k))−y(k))xj(k)
(for j = 0 : n j=0:n j=0:n)
i + = 10 i +=10 i+=10
}
}
通常会令 b b b 在 2-100 之间。这样做的好处在于,可以用向量化的方式来循环 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
随着不断地靠近全局最小值,通过减小学习率,迫使算法收敛而非在最小值附近徘徊。但是通常不需要这样做便能有非常好的效果了,对 α α α进行调整所耗费的计算通常不值得。
一种新的大规模的机器学习机制,叫做在线学习机制。在线学习机制可以模型化问题。
当今许多大型网站或者网络公司,使用不同版本的在线学习机制算法,从大批的涌入又离开网站的用户身上进行学习。如果有一个由连续的用户流引发的连续的数据流,进入网站,可以使用一个在线学习机制,从数据流中学习用户的偏好,然后使用这些信息来优化一些关于网站的决策。
假使我们正在经营一家物流公司,每当一个用户询问从地点A至地点B的快递费用时,给用户一个报价,该用户可能选择接受 ( y = 1 ) (y=1) (y=1)或不接受 ( y = 0 ) (y=0) (y=0)。现在需要构建一个模型,来预测用户接受报价使用我们的物流服务的可能性。因此报价是一个特征,其他特征为距离,起始地点,目标地点以及特定的用户数据。模型的输出是: p ( y = 1 ) p(y=1) p(y=1)。
在线学习的算法与随机梯度下降算法有些类似,对单一的实例进行学习,而非对一个提前定义的训练集进行循环。
Repeat forever (as long as the website is running) {
Get ( x , y ) \left(x,y\right) (x,y) corresponding to the current user
θ : = θ j − α ( h θ ( x ) − y ) x j \theta:={\theta}_{j}-\alpha\left( {h}_{\theta}\left({x}\right)-{y} \right){ {x}_{j}} θ:=θj−α(hθ(x)−y)xj
(for j = 0 : n j=0:n j=0:n)
}
一旦对一个数据的学习完成了,便可以丢弃该数据,不需要再存储它了。这种方式的好处在于,算法可以很好的适应用户的倾向性,算法可以针对用户的当前行为不断地更新模型以适应该用户。
每次交互事件并不只产生一个数据集,例如,一次给用户提供3个物流选项,用户选择2项,实际上可以获得3个新的训练实例,因而算法可以一次从3个实例中学习并更新模型。
在线学习的一个优点就是,如果有一个变化的用户群,又或者在尝试预测的事情,在缓慢变化,就像用户的品味在缓慢变化,这个在线学习算法,可以慢慢地调试所学习到的假设,将其调节更新到最新的用户行为。
映射化简和数据并行对于大规模机器学习问题而言是非常重要的概念。如果用批量梯度下降算法来求解大规模数据集的最优解,需要对整个训练集进行循环,计算偏导数和代价,再求和,计算代价非常大。如果能将数据集分配给不多台计算机,让每一台计算机处理数据集的一个子集,然后将计所的结果汇总在求和。这样的方法叫做映射简化。
如果任何学习算法能够表达为,对训练集的函数的求和,那么便能将这个任务分配给多台计算机(或者同一台计算机的不同CPU 核心),以达到加速处理的目的。
例如,有400个训练实例,可以将批量梯度下降的求和任务分配给4台计算机进行处理:
很多高级的线性代数函数库已经能够利用多核CPU的多个核心来并行地处理矩阵运算,这也是算法的向量化实现如此重要的缘故(比调用循环快)。
图像文字识别应用所作的事是,从一张给定的图片中识别文字。这比从一份扫描文档中识别文字要复杂的多。
为了完成这样的工作,需要采取如下步骤:
滑动窗口是一项用来从图像中抽取对象的技术。假使需要在一张图片中识别行人,首先用许多固定尺寸的图片来训练一个能够准确识别行人的模型。然后用之前训练识别行人的模型时所采用的图片尺寸在要进行行人识别的图片上进行剪裁,然后将剪裁得到的切片交给模型,让模型判断是否为行人,然后在图片上滑动剪裁区域重新进行剪裁,将新剪裁的切片也交给模型进行判断,如此循环直至将图片全部检测完。一旦完成后,按比例放大剪裁的区域,再以新的尺寸对图片进行剪裁,将新剪裁的切片按比例缩小至模型所采纳的尺寸,交给模型进行判断,如此循环。
滑动窗口技术也被用于文字识别:
如果模型是低方差的,那么获得更多的数据用于训练模型,是能够有更好的效果的。问题在于怎样获得数据,数据不总是可以直接获得的,有可能需要人工地创造一些数据。
以文字识别应用为例,可以字体网站下载各种字体,然后利用这些不同的字体配上各种不同的随机背景图片创造出一些用于训练的实例,这可以获得一个无限大的训练集。这是从零开始创造实例。
另一种方法是,利用已有的数据,然后对其进行修改,例如将已有的字符图片进行一些扭曲、旋转、模糊处理。只要认为实际数据有可能和经过这样处理后的数据类似,便可以用这样的方法来创造大量的数据。
有关获得更多数据的几种方法:
在机器学习的应用中,通常需要通过几个步骤才能进行最终的预测,如何能够知道哪一部分最值得花时间和精力去改善呢?这个问题可以通过上限分析来回答。
文字识别应用中,流程图如下:
流程图中每一部分的输出都是下一部分的输入,上限分析中,选取一部分,手工提供100%正确的输出结果,然后看应用的整体效果提升了多少。假使总体效果为72%的正确率。
如果令文字侦测部分输出的结果100%正确,发现系统的总体效果从72%提高到了89%。这意味着很可能会希望投入时间精力来提高文字侦测部分。
接着手动选择数据,让字符切分输出的结果100%正确,发现系统的总体效果只提升了1%,这意味着,字符切分部分可能已经足够好了。
最后手工选择数据,让字符分类输出的结果100%正确,系统的总体效果又提升了10%,这意味着可能也会应该投入更多的时间和精力来提高应用的总体表现。
- 由于网络延迟和其他与map-reduce相关的开销,如果我们使用N台计算机运行map-reduce,与使用1台计算机相比,我们可能会得到小于N倍的加速。(√)
- 使用上限分析并不会帮我们分析出哪个部分是high bias,哪个部分是high variance。(X)
- 执行此处的上限分析,需要我们对其它的三个流程都加上标签来判断对错(ground-truth)。(√)