来源:原始 Jupyter Notebook。内容已转换为网页阅读格式;下载原文件。
sklearn 中的梯度下降法
上面的求解过程中,我们每次的迭代都用到了所有样本,这样做可以让收敛速度最快,但是如果样本数非常多,计算性能就会变低,上面的例子中一共也就3个样本,所以不明显。像这种每次迭代都使用全部样本的方法,叫做 批量梯度下降(Batch gradient descend,BGD)。为了提高计算性能,可以在每次迭代中随机选取一个样本(或部分样本)用于计算,这样也可以保证收敛,虽然收敛的速度慢了点,但计算快很多,而且可以有效的避免陷入局部极小值情况。这种方法叫做 随机梯度下降(Stochastic gradient descend,SGD)。
sklearn 中的 SGDRegressor 实现的就是随机梯度下降算法。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import SGDRegressor
X = np.array([0,1,2])
Y = np.array([0.9, 3.1, 5.1])
#X = np.array([39.93, 42.05, 43.18])
#Y = np.array([199, 290, 298])
model = SGDRegressor(max_iter=1000, tol=0.01)
model.fit(X.reshape(-1,1), Y.ravel())
plt.plot(X, Y, 'k.')
x = [[0],[10]]
#x = [[30],[60]]
y = model.predict(x)
b = y[0]
a = (y[1]-b)/x[1][0]
print("a = {0}, b = {1}".format(a, b))
plt.plot(x, y, 'g-')
plt.show()
运行结果
a = 1.5356587127294614, b = 1.0052652195613447
运行结果

使用批量梯度下降法 BGD 时,每次迭代是对所有样本进行计算,当目标函数为凸函数时,BGD 一定能够得到全局最优解,并且计算过程可以转换为矩阵计算,易于并行实现;不过当样本数目很多时,训练过程会很慢。使用随机梯度下降法 SGD 可以加快训练速度,不过缺点也显而易见,它的准确度要低很多,得到的可能不是全局最优解。为了在两种方法的性能之间取得一个折衷,可以采用 小批量梯度下降法(Mini-batch Gradient Descent,简称 MBGD),MBGD 在每次更新参数时使用 b 个样本(一般为10)。
批量梯度下降的更新公式为:
随机梯度下降的更新公式为(注意没有求和符号):
小批量梯度下降的更新公式为: