梯度
在单变量函数中,梯度其实就是函数的微分形式,代表着在某点处,函数的切线的斜率;
在多变量函数中,梯度是一个向量,(向量具有方向,有该点指向上升最快的方向);
梯度的方向:函数中某切点上升最快的方向
梯度下降法的基本思想
可以将函数类比一座山,梯度下降法相当于移步到达山谷。我们都知道沿着最陡峭的山坡,到达山谷的速度最快。在数学中就是特定点梯度,沿着梯度的反方向,就能让函数下降的最快方向。反复的下降(移步),就能到达局部最小值(全局最小值)。
损失函数(Loss Function)
损失函数有多种,本次演例使用MSE损失函数。
计算二次函数极值
# 函数: x**2 + 3*x + 4的极值点
# 导数为:2*x + 3,在x=-1.5出有极小值
x_pre = -5 # 初始值
n_now = 1 # 梯度下降的初始值
lr = 0.01 # 学习率
count = 0 # 迭代次数
pression = 0.0001 # 精度
while abs(x_pre - x_now) >= pression:
x_pre = x_now
x_now = x_pre - lr*(2 * x_pre + 3)
count += 1
print(count)
print(x_now)
309
-1.4951381965479744
拟合一次曲线
对离散数据点,拟合一次曲线
m = 100 # 数据点数量
lr = 0.01 # 学习率
epochs = 1000 # 迭代次数
theta = np.random.randn(2, 1) # 随机生成权重
x = np.sort(np.random.rand(100, 1), axis=0) # 随机生成横坐标(服从正太分布), 相当于做归一化
x_c = np.c_[np.ones((100, 1)), x] # 在数据前面,添加数据
y = 4 + 3 * x + np.random.randn(100, 1) # 生成纵坐标,
for _ in range(epochs):
gradient = (1/m) * np.dot(x_c.T, (np.dot(x_c, theta) - y))
theta = theta - lr * gradient
print(theta)
plt.scatter(x, y)
plt.plot(x, theta[1] * x + theta[0])
plt.show()
[[3.99855097]
[2.98841104]]
拟合二次曲线
lr = 0.01 # 学习率
m = 100 # 数据数量
epochs = 100 # 迭代次数
np.random.seed(10)
theta = np.random.randn(3, 1) # 随机初始化权重,符合正太分布
x = np.sort(np.random.randn(m, 1), axis=0) # 生成随机横坐标,服从正太分布,相当与对横坐标做归一化处理
x_c = np.c_[np.ones_like(x), x, x**2] # 在数据前和后,添加数据
y = 4 * x ** 2 + 3 * x + 10 + np.random.randn(m, 1) # 生成纵坐标
# 梯度下降
for _ in range(epochs):
gradient = (1 / m) * np.dot(x_c.T, np.dot(x_c, theta) - y)
theta = theta - lr * gradient
plt.scatter(x, y)
plt.plot(x, theta[2] * x ** 2 + theta[1] * x + theta[0])
plt.show()
[[6.99941591]
[2.26086401]
[5.01650791]]