梯度下降法(英语:Gradient descent)是一个一阶最优化算法,通常也称为最速下降法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点;这个过程则被称为梯度上升法。
梯度下降法(英语:Gradient descent)是一个一阶最优化算法,通常也称为最速下降法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点;这个过程则被称为梯度上升法。
graph LR
A[输入] --> B[学习模型]
B --> C[预测输出]
C --> D[尽可能接近实际输出]
D --> B
0.5 5.0
0.6 5.5
0.8 6.0
1.1 6.8
1.4 7.0 预测函数 -> 寻找w0和w1 -> 模型参数
x y y'=w0+w1x
单样本误差:
根据预测函数求出输入为x时的预测值:$y' = w_0 + w_1x$
总样本误差:
把所有单样本误差相加即是总样本误差:$\frac{1}{2}\sum(y-y')^2$
损失函数:反映总样本误差因模型参数的变化而变化的规律
$loss = \frac{1}{2}\sum(y-(w_0+w_1x))^2$
所以损失函数就是总样本误差关于模型参数的函数,该函数属于三维数学模型,即需要找到一组 $w_0$, $w_1$ 使得 $loss$ 取极小值。
整理训练集数据,自定义梯度下降算法规则,求出w<sub>0</sub> , w<sub>1</sub> ,绘制回归线。
import numpy as np
import matplotlib.pyplot as mp
train_x = np.array([0.5, 0.6, 0.8, 1.1, 1.4])
train_y = np.array([5.0, 5.5, 6.0, 6.8, 7.0])
test_x = np.array([0.45, 0.55, 1.0, 1.3, 1.5])
test_y = np.array([4.8, 5.3, 6.4, 6.9, 7.3])
times = 1000 # 定义梯度下降次数
lrate = 0.01 # 记录每次梯度下降参数变化率
epoches = [] # 记录每次梯度下降的索引
w0, w1, losses = [1], [1], []
for i in range(1, times + 1):
epoches.append(i)
loss = (((w0[-1] + w1[-1] * train_x) - train_y) ** 2).sum() / 2
losses.append(loss)
d0 = ((w0[-1] + w1[-1] * train_x) - train_y).sum()
d1 = (((w0[-1] + w1[-1] * train_x) - train_y) * train_x).sum()
print('{:4}> w0={:.8f}, w1={:.8f}, loss={:.8f}'.format(epoches[-1], w0[-1], w1[-1], losses[-1]))
w0.append(w0[-1] - lrate * d0)
w1.append(w1[-1] - lrate * d1)
pred_test_y = w0[-1] + w1[-1] * test_x
mp.figure('Linear Regression', facecolor='lightgray')
mp.title('Linear Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(train_x, train_y, marker='s', c='dodgerblue', alpha=0.5, s=80, label='Training')
mp.scatter(test_x, test_y, marker='D', c='orangered', alpha=0.5, s=60, label='Testing')
mp.scatter(test_x, pred_test_y, c='orangered', alpha=0.5, s=80, label='Predicted')
mp.plot(test_x, pred_test_y, '--', c='limegreen', label='Regression', linewidth=1)
mp.legend()
mp.show()

2. 绘制随着每次梯度下降,w<sub>0</sub>,w<sub>1</sub>,loss的变化曲线。
w0 = w0[:-1]
w1 = w1[:-1]
mp.figure('Training Progress', facecolor='lightgray')
mp.subplot(311)
mp.title('Training Progress', fontsize=20)
mp.ylabel('w0', fontsize=14)
mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches, w0, c='dodgerblue', label='w0')
mp.legend()
mp.subplot(312)
mp.ylabel('w1', fontsize=14)
mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches, w1, c='limegreen', label='w1')
mp.legend()
mp.subplot(313)
mp.xlabel('epoch', fontsize=14)
mp.ylabel('loss', fontsize=14)
mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches, losses, c='orangered', label='loss')
mp.legend()