随机梯度下降法

在随机梯度下降法中,我们定义代价函数为一个单一训练实例的代价:

​ $$cost\left( \theta, \left( {x}^{(i)} , {y}^{(i)} \right) \right) = \frac{1}{2}\left( {h}_{\theta}\left({x}^{(i)}\right)-{y}^{{(i)}} \right)^{2}$$

随机梯度下降算法为:首先对训练集随机“洗牌”,然后: Repeat (usually anywhere between1-10){

for $i = 1:m${

​ $\theta:={\theta}{j}-\alpha\left( {h}{\theta}\left({x}^{(i)}\right)-{y}^{(i)} \right){{x}_{j}}^{(i)}$

​ (for $j=0:n$)

​ } }

随机梯度下降算法在每一次计算之后便更新参数 ${{\theta }}$ ,而不需要首先将所有的训练集求和,在梯度下降算法还没有完成一次迭代时,随机梯度下降算法便已经走出了很远。但是这样的算法存在的问题是,不是每一步都是朝着”正确”的方向迈出的。因此算法虽然会逐渐走向全局最小值的位置,但是可能无法站到那个最小值的那一点,而是在最小值点附近徘徊。

小批量梯度下降

小批量梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法,每计算常数$b$次训练实例,便更新一次参数 ${{\theta }}$ 。 Repeat {

for $i = 1:m${

​ $\theta:={\theta}{j}-\alpha\frac{1}{b}\sum\limits{k=i}^{i+b-1}\left( {h}{\theta}\left({x}^{(k)}\right)-{y}^{(k)} \right){{x}{j}}^{(k)}$

​ (for $j=0:n$)

​ $ i +=10 $

​ } }

通常我们会令 $b$ 在 2-100 之间。这样做的好处在于,我们可以用向量化的方式来循环 $b$个训练实例,如果我们用的线性代数函数库比较好,能够支持平行处理,那么算法的总体表现将不受影响(与随机梯度下降相同)

随机梯度下降收敛

在批量梯度下降中,我们可以令代价函数$J$为迭代次数的函数,绘制图表,根据图表来判断梯度下降是否收敛。但是,在大规模的训练集的情况下,这是不现实的,因为计算代价太大了。

在随机梯度下降中,我们在每一次更新 ${{\theta }}$ 之前都计算一次代价,然后每$x$次迭代后,求出这$x$次对训练实例计算代价的平均值,然后绘制这些平均值与$x$次迭代的次数之间的函数图表。

当我们绘制这样的图表时,可能会得到一个颠簸不平但是不会明显减少的函数图像(如上面左下图中蓝线所示)。我们可以增加$α$来使得函数更加平缓,也许便能看出下降的趋势了(如上面左下图中红线所示);或者可能函数图表仍然是颠簸不平且不下降的(如洋红色线所示),那么我们的模型本身可能存在一些错误。

如果我们得到的曲线如上面右下方所示,不断地上升,那么我们可能会需要选择一个较小的学习率$α$。

我们也可以令学习率随着迭代次数的增加而减小,例如令:

​ $$\alpha = \frac{const1}{iterationNumber + const2}$$

随着我们不断地靠近全局最小值,通过减小学习率,我们迫使算法收敛而非在最小值附近徘徊。 但是通常我们不需要这样做便能有非常好的效果了,对$α$进行调整所耗费的计算通常不值得

在线学习

在线学习的算法与随机梯度下降算法有些类似,我们对单一的实例进行学习,而非对一个提前定义的训练集进行循环。 Repeat forever (as long as the website is running) { Get $\left(x,y\right)$ corresponding to the current user ​ $\theta:={\theta}{j}-\alpha\left( {h}{\theta}\left({x}\right)-{y} \right){{x}_{j}}$ ​ (for $j=0:n$) }

一旦对一个数据的学习完成了,我们便可以丢弃该数据,不需要再存储它了。这种方式的好处在于,我们的算法可以很好的适应用户的倾向性,算法可以针对用户的当前行为不断地更新模型以适应该用户。

映射化简和数据并行

映射化简和数据并行对于大规模机器学习问题而言是非常重要的概念。之前提到,如果我们用批量梯度下降算法来求解大规模数据集的最优解,我们需要对整个训练集进行循环,计算偏导数和代价,再求和,计算代价非常大。如果我们能够将我们的数据集分配给不多台计算机,让每一台计算机处理数据集的一个子集,然后我们将计所的结果汇总在求和。这样的方法叫做映射简化。

具体而言,如果任何学习算法能够表达为,对训练集的函数的求和,那么便能将这个任务分配给多台计算机(或者同一台计算机的不同CPU 核心),以达到加速处理的目的。

例如,我们有400个训练实例,我们可以将批量梯度下降的求和任务分配给4台计算机进行处理: