首先来看一个最简单的例子,即线性回归。
与之前一样,我们从代价函数(cost function)开始。
![1_CSocAhQwk1xuncdV7aRdmA](https://i-blog.csdnimg.cn/blog_migrate/3e34af4646efbdab23bae586bdec948f.png)
线性回归复习完毕。
所以,梯度下降算法是什么?
![1_7EFYKfICK48B5jCxgYHVLQ](https://i-blog.csdnimg.cn/blog_migrate/3271621f220d8804b02242f9baca6da7.png)
上面算法的意思是说,为了执行梯度下降,我们就要计算代价函数 J 的梯度。为了计算代价函数的梯度,我们要对所有样本的代价进行求和(黄色圆圈)。也就是说,如果有300万个样本,我们每计算一次梯度就要循环计算300万次。
下面是Python代码:
1def gradientDescent(X, y, theta, alpha, num_iters):
2 """
3 执行梯度下降
4 """
5 m = y.size # 训练样本的数量
6 for i in range(num_iters):
7 y_hat = np.dot(X, theta)
8 theta = theta - alpha * (1.0/m) * np.dot(X.T, y_hat-y)
9 return theta
看到上面的 np.dot(X.T, y_hat-y)
了吗?这是 “循环(求和)300万个样本” 的矢量化版本。
等等….这只是向最小化迈进了一步,我们真的要每计算一次代价就要计算300万次吗?
是的,如果使用梯度下降的话。
但如果使用随机梯度(Stochastic Gradient Descent, SGD)下降,就没有必要计算这么多次!
![1_7LbtloKtsBZW1P0DmR4UDA](https://i-blog.csdnimg.cn/blog_migrate/91704ae4854a72c68a35aeb10bbcb33d.png)
基本上,在SGD中,我们在每次迭代时只使用 1 个样本的梯度,用它来代替所有样本的梯度之和。
1def SGD(f, theta0, alpha, num_iters):
2 """
3 参数:
4 f - 要优化的函数,它需要一个参数
5 并产生两个输出,一个代价和相对于参数的梯度
6 theta0 - 开始 SGD 的初始值
7 num_iters - SGD 的总迭代次数
8 返回:
9 theta - SGD 结束后的参数值
10 """
11 start_iter = 0
12 theta= theta0
13 for iter in xrange(start_iter + 1, num_iters + 1):
14 _, grad = f(theta)
15 theta = theta - (alpha * grad) # 没有使用点积
16 return theta
这是一个非常简单的算法!
有几点注意事项:
在SGD中,在循环之前,您需要随机更改训练样本。
在SGD中,因为它一次只使用一个样本,所以它的最小值路径比批量梯度的路径更嘈杂(更随机)。但是没关系,因为我们对路径漠不关心,只要它给我们最小的值和更短的训练时间。
小批量梯度下降在每次迭代时使用n个样本点(而不是SGD中的1个样本)。
原文:https://towardsdatascience.com/difference-between-batch-gradient-descent-and-stochastic-gradient-descent-1187f1291aa1