大白话 5 分钟带你走进人工智能 - 第八节梯度下降之批量梯度下降和随机梯度下降 (3)

第八节梯度下降之批量梯度下降和随机梯度下降 (3)

上一节中,我们讲解了梯度下降的大概流程,从多元问题了解举例了解了梯度更新的过程,本节的话我们接着上一节的问题继续。把问题再陈述一遍,

\frac{\partial J(\theta )}{\theta _{j}}=\frac{\partial J(\theta )}{\theta {j}}\cdot \frac{1}{2}(h{\theta(x)}-y)^{2}

这里面的损失函数不应该是 m 个样本累加吗?我们更新梯度的时候每一次都要把全部的 w 代入计算一遍吗?这样会不会太耗时间?有什么其他的办法吗? 我们追个分析。
J(\theta)是什么?mse。mse 是一条数据计算出的 mse,还是全部数据计算出的 mse,当然是全部数据计算出的 mse,所以(h_{\theta(x)}-y)^{2}是一条的数据,按理说怎么样?要写成 i 从 1 到 m 的求和号,也就是\sum_{i=1}^{m}(h_{\theta(x)}-y)^{2},在求导的过程中求和号不会被干掉,它是 m 项相加,每一项本质里边都是这个(h_{\theta(x)}-y)^{2},最后结果也是这么多项相加,求和号不会影响求导过程,会一直存活下来。那么每次更新 W 的时候, 就得把全部的数据都代一遍,才能算出负梯度 。 为什么要全代?因为损失函数要求你全代,求全代的损失函数的负梯度当然也得全代,求完导就这样,没办法。但是这样效率并不高,而且这样的效率会随着数据集的变多,我们每一步梯度下降的计算成本会逐渐增加? 而这就是 批量梯度下降。迭代公式 如下:

\theta {j}=\theta{j}+\alpha \frac{1}{m}\sum_{i=1}^{m}(y^(i)-h_{\theta}(x^{i}))x_{j}^{i}

那么这就有一个问题了,之前说损失函数写成

J(\theta )=\sum_{i=1}^{m}(h_{\theta}x^{i}-y^{i})^{2}

i 从 1 到 m 这种写法前面应不应该加 1/m?也就是

J(\theta )=\frac{1}{m}\sum_{i=1}^{m}(h_{\theta}x^{i}-y^{i})^{2}

按照之前的理论加 1/m 或者不加 1/m 都无所谓,因为你求它相对最小就够了,但这里梯度下降想用梯度干什么?用它决定下降多少,如果不加 1/m 的话,是不是数据集越大,你的λ就得调得越小。 因为数据集越大,肯定最后下降值的绝对就越大 ,即

\theta {j}=\theta{j}+\alpha \frac{1}{m}\sum_{i=1}^{m}(y^(i)-h_{\theta}(x^{i}))x_{j}^{i}

中的

\sum_{i=1}^{m}(y^(i)-h_{\theta}(x^{i}))x_{j}^{i}

就越大, 如果不加 1/m 的话,1 万条数据跟 10 万条数据相比,肯定是 10 万条数据绝对值更大一些,这时候还得根据不同数据的样本集调小λ ,很麻烦。所以在梯度下降的时候用的所谓损失函数都是前面加上 1/m 或者 2/m。我们通俗的 模拟下批量梯度下降的过程。 假如你是计算机,每次更新 W 的时候,要怎么计算?除了我们人为的设置需要迭代多少次的次数 k 的循环之外?还有两层循环,外层循环是假如有 n 个 w, 相当于 n 个维度,每个 w 都要更新一次,所以要循环 n 次。内层循环要循环几次?实际上是 m 次。因为是 m 个样本,比如更新 w1 的时候, 即

\theta {1}=\theta{1}+\alpha \frac{1}{m}\sum_{i=1}^{m}(y^(i)-h_{\theta}(x^{i}))x_{1}^{i}

这里面的 i 是变量,i 代表着我们的每一条样本,有多少个样本,就要循环几次,所以是 m 次。过程是首先把第一条数据 X1 拿出来,跟瞎蒙出来那组 W(初始 W)求出一个预测结果 hθ(x)来,然后减去第一个真实的 y,再乘以第一条数据 X 里面的第 J 个维度,因为要更新 W1,乘的就是第一条数据 X 的第一个维度x_{1}^{1},实际上就是第一行第一列,再把第二条数据拿出来,与瞎蒙出来那组 W,算出来 hθ(x),减去第二个真实的 y , 然后再乘以第二条数据 X 里边的第一个数,也就是第二行第一列x_{1}^{2}?依次这样操作,所有的数据全部都计算一遍,累加结果之后,最后乘 1/m,就是要更新 W1 所计算的所有内容下图为举例说明批量梯度下降的过程:

20190318203941223.png

所以批量梯度下降的特点是:每次求梯度的时候度需要做 m 次加和(假设有 m 个数据点)。优点是: 在每次迭代时都保证严格按照损失函数负梯度方向下降 缺点是: 每次迭代运算量比较大,时间长。 所以往往我们 不去代全部的数据,而只拿出一条数据来 。也就是:

\theta {j}=\theta{j}+\alpha(y^(i)-h_{\theta}(x^{i}))x_{j}^{i}

通俗点就是随机梯度下降的方式就是原来把所有的 Y 跟 X 一堆运算完了加一下求平均数,现在变成不求平均数了,随便挑出一条来,相当于把这个\frac{1}{m}\sum_{i=1}^{m}直接干掉,这个过程叫随机梯度下降。那么随机梯度下降求出来的结果是负梯度吗?其实不是,我们近似的把它看成负梯度,这样会导致一个什么结果呢?会导致我们的每一次更新就不带着求和号了。会有什么不好的影响呢?它每次下降的负梯度还准吗?原来应该是平均值,而现在变成了一个单独的数,那么下降的梯度就有可能不准,比如下面的例子:
20190318203941223.png

按理说应该损失函数直着下来就完了,但是它这个东西上来第一步走歪了,第二步又走歪了,第三步又走歪了,第四步,甚至走反了,第五步走歪了,它迭代的次数会增加,但虽然次数增加了,你本来原来十次能达到最优解,现在可能需要一百次才能达到最优解。但是每一次的计算内部计算量却少了很多,原来批量梯度下降内部要把 10 万条数据算一遍,现在你只算一条了,等于总的整体的计算量还是减小了的这么一种优化,或者你管它叫做妥协,那么最后它可能永远达不到真正的最优解的点,这会儿 tolerance( 即上一步梯度和下一步梯度中间差值小于多少就认为是收敛了这个阈值就是 tolerance )出来就工作了,达到差不多就得了。 所以随机梯度下降才是我们真正在实践中使用的梯度下降,它不是完美的按照函数的负梯度走,而是用一条数据计算出来的那个东西代替真实的负梯度让它进行下降,虽然有可能走错,但是肯定更多的步数是走对了的,最后相当于用量补充上它的方向的不完美。而它为什么能用量补充?因为这批量运算里面的每一步的计算代价很小,所以我无所谓你多走几次,所以这个叫随机梯度下降。 所以随机梯度下降是对批量提速下降的一种粗犷的近似, 就是为了增加计算效率的。随机梯度下降活跃在整个机器学习算法背后各种各样的场景里面,很多应用场景基本都是用随机梯度下降来进行处理的。