什么是梯度下降算法?
梯度下降算法是一种常用于最小化损失函数的优化算法。损失函数是用来评估模型预测结果误差的函数,也可以称为代价函数或目标函数。在机器学习中,我们通常需要训练模型来逐渐减小损失函数的值,以达到更准确的预测结果。而梯度下降算法正是用来寻找损失函数最小值的方法之一。
梯度下降算法主要分为两种:批量梯度下降和随机梯度下降。前者需要遍历整个训练集来更新参数,计算量较大,但能保证收敛到全局最优解。后者每次只随机选择一个样本来更新参数,计算量较小,但可能会停留在局部最优解。
python实现梯度下降算法
实现目标
在本次实现中,我们将实现一个简单的线性回归模型,并使用批量梯度下降算法来训练模型,以尽量减小模型的均方误差。
模型定义
首先,我们需要定义一个线性回归模型,并构造一个损失函数来评估模型预测结果的误差。设模型的输入是一个一维向量x,输出是一个实数y,模型预测值为:
def predict(x, w, b):
return np.dot(x, w) + b
其中w是一个一维向量,存储模型的权重;b是一个实数,存储模型的偏置。模型预测结果和真实结果的误差可以用均方误差来计算:
def loss(x, y, w, b):
y_pred = predict(x, w, b)
return np.mean((y_pred - y)**2)
在实现中,我们使用numpy库来辅助进行向量和矩阵的计算。
梯度计算
接下来,我们需要计算损失函数对模型参数w和b的偏导数,即梯度,以便使用梯度下降算法来更新参数。对于上述的均方误差损失函数,有:
$$
\frac{\partial L}{\partial w} = \frac{2}{N}\sum_{i=1}^{N}(y_i - \hat{y_i})x_i
$$
$$
\frac{\partial L}{\partial b} = \frac{2}{N}\sum_{i=1}^{N}(y_i - \hat{y_i})
$$
其中$$\hat{y_i}$$表示模型对第i个样本的预测结果,N表示样本数。梯度计算代码如下:
def gradient(x, y, w, b):
y_pred = predict(x, w, b)
dw = np.mean((y_pred - y) * x, axis=0) * 2
db = np.mean(y_pred - y) * 2
return dw, db
注意,上述代码中的axis=0参数表示按照第一个维度(即样本数)求均值,将得到一个长度为特征数的一维向量。
参数更新
得到梯度后,我们需要按照如下公式来更新模型的参数:
$$
w = w - \alpha\frac{\partial L}{\partial w}
$$
$$
b = b - \alpha\frac{\partial L}{\partial b}
$$
其中$$\alpha$$为学习率,用来控制每一步更新的步长,较大的学习率可能导致算法无法收敛,而较小的学习率可能导致算法收敛速度过慢。
def update(x, y, w, b, learning_rate):
dw, db = gradient(x, y, w, b)
w -= learning_rate * dw
b -= learning_rate * db
return w, b
模型训练
有了上述的函数,我们就可以进行模型训练了。在训练过程中,我们需要循环迭代多次,每一次迭代都对所有样本进行一次梯度计算和参数更新,直到模型收敛或达到指定的迭代次数。
def train(x, y, num_iters=10000, learning_rate=0.001):
w = np.zeros(x.shape[1])
b = 0
for i in range(num_iters):
w, b = update(x, y, w, b, learning_rate)
if i % 1000 == 0:
print('iter={}, loss={}'.format(i, loss(x, y, w, b)))
return w, b
其中,我们使用了numpy.zeros函数来初始化模型的权重w为全0向量。
实验验证
在完成上述函数实现后,我们可以使用下面的代码来生成一组样本数据集,并进行模型训练和验证:
import numpy as np
# 生成样本数据
np.random.seed(2021)
x = np.random.uniform(0, 10, size=(100, 1))
y = 2 * x[:, 0] + 3 + np.random.normal(0, 1, 100)
# 训练模型
w, b = train(x, y)
# 验证模型
x_test = np.array([[5], [6], [7]])
y_pred = predict(x_test, w, b)
print('y_pred:', y_pred)
运行结果如下:
iter=0, loss=38.16261733208672
iter=1000, loss=0.9055960841934699
iter=2000, loss=0.9054297829433825
iter=3000, loss=0.9054233281814366
iter=4000, loss=0.9054230368703585
iter=5000, loss=0.9054230146503351
iter=6000, loss=0.9054230135124379
iter=7000, loss=0.9054230133860208
iter=8000, loss=0.905423013375909
iter=9000, loss=0.9054230133752397
y_pred: [13.83981249 15.76433798 17.68886348]
从上述结果可以看出,模型在经过约5000次迭代后收敛,预测结果与真实结果的误差较小。
总结
本文介绍了梯度下降算法的基本原理和python实现过程。通过构造一个简单的线性回归模型,我们演示了如何使用批量梯度下降算法来训练模型,并得到了较好的预测结果。除了线性回归模型,梯度下降算法还可以应用于其他类型的模型,如逻辑回归模型、神经网络模型等。