故事背景
在正式学习pytorch深度框架之前,假设你已经掌握了机器学习、深度学习的梯度下降算法基础理论,但是编程技术还不够熟练,于是本文将使用python演示如何利用梯度下降法求解一元线性回归中的参数。对于复杂的目标函数,无法求出显式解以及高维目标函数无法可视化。在知道样本数据下,于是通过梯度下降算法求解最优解(可能是局部最优解)。
y = w ∗ x + b y = w*x+b y=w∗x+b
其中的 w w w 和 b b b就是我们要求解的参数。
生成数据
假设500个样本来源于:
y
=
5
∗
x
+
3
y = 5*x+3
y=5∗x+3
并且受到其他因素影响,这里设置标准高斯噪声,则生成样本数据:
y
=
5
∗
x
+
3
+
N
(
0
,
1
)
y = 5*x+3+N(0,1)
y=5∗x+3+N(0,1)
import numpy as np
def function(b=3,size=500):
x = np.random.uniform(1, 30, size)
noise = np.random.normal(0, 1, size)
y = 5 * x + b + noise
list_1 = []
for i, j in zip(x, y):
list_1.append([i, j])
return list_1
损失函数
设置损失函数为均方误差MSE:
M S E = 1 n ∑ i = 1 n ( Y i − Y ^ i ) 2 Y i ^ = w ^ ∗ x i + b ^ \mathrm{MSE}=\frac{1}{n} \sum_{i=1}^n\left(Y_i-\hat{Y}_i\right)^2 \\ \hat{Y_i} = \hat{w}*x_i+\hat{b} MSE=n1i=1∑n(Yi−Y^i)2Yi^=w^∗xi+b^
梯度更新1次
梯度更新方法,lr为学习率:
w
i
+
1
=
w
i
−
l
r
∗
∂
M
S
E
∂
w
w_{i+1} = w_i - lr *\frac{\partial MSE}{\partial w}
wi+1=wi−lr∗∂w∂MSE
b i + 1 = b i − l r ∗ ∂ M S E ∂ b b_{i+1} = b_i - lr * \frac{\partial MSE}{\partial b} bi+1=bi−lr∗∂b∂MSE
# 梯度更新1次
def grad_step(c_w, c_b, lr, points):
total_w_g, total_b_g = 0, 0
N = len(points)
for point in points:
x, y = point[0], point[1]
total_w_g += 2 * (y- (c_w * x + c_b) ) * (-x) / N
total_b_g += 2 * (y- (c_w * x + c_b)) *(-1) / N
c_w = c_w - lr * total_w_g
c_b = c_b - lr * total_b_g
return [c_w, c_b]
迭代
在整个数据集上面循环time次,这里没有设置batch,即将整个样本理解为1个batch。
# 迭代
def diedai(i_w, i_b, lr, points,time):
n_w, n_b = i_w, i_b
for i in range(time):
n_w, n_b = grad_step(n_w, n_b, lr, points)
print('参数:', n_w, n_b )
return [n_w, n_b]
主函数
可以对比看迭代前后的损失,设置初始参数,并输出迭代后的参数估计值。
# 主函数
def main(i_w, i_b, lr, points, time):
loss_i = copute_erro(i_w, i_b, points)
print(f"初始状态损失:{loss_i}")
ii_w, ii_b = diedai(i_w, i_b, lr, points, time)
loss_e = copute_erro(ii_w, ii_b, points)
print(f"结束状态损失:{loss_e}")
执行
设置初始参数均为0,学习率为0.0001,迭代40000次,最后输出结果。
# 执行
if __name__ == "__main__":
o_w = 0
o_b = 0
lr = 0.0001
time = 40000
points = function()
main(o_w, o_b, lr, points, time)
'''
输出结果:
初始状态损失:8168.732799656018
参数: 5.0154640678882005 2.771481630325438
结束状态损失:1.0200946795304344
'''
参数估计值 w w w, b b b分别为5.015464和2.77148,这总体设置的5和3很接近。前提是我们并不知道参数真实值为5和3,于是就用参数估计值5.015464和2.77148去替代总体参数。