赞
踩
本文的将随机采集100个数据,并假设误差变量属于正态分布进行试验
代码如下:
# 采集数据
data = []
# 循环采样100个点
for i in range(100):
x = np.random.uniform(-10, 10) # uniform:随机生成一个实数
eps = np.random.normal(0., 0.01) # normal:正态分布
y = 1.477 * x + 0.089 + eps
data.append([x, y])
data = np.array(data)
通过方差公式计算误差,可适用于线性的模型
代码如下:
# 计算误差 def mse(b, w, points): """ :param b: b的值 :param w: w的值 :param points: [x,y]的数据集 :return: 误差值 """ # 设置初始误差为0 totalError = 0 # 循环遍历所有数据 for i in range(0, len(points)): # 获取第i个位置的x的值 x = points[i, 0] # 获取第i个位置的y的值 y = points[i, 1] # 计算总误差 totalError += (y - (w * x + b)) ** 2 # 获得平均方差(误差) return totalError / float(len(points))
梯度计算公式如下:
代码如下:
# 计算梯度 def step_gradient(b_current, w_current, points, lr): """ :param b_current: b的值 :param w_current: w的值 :param points: [x,y]的数据集 :param lr: 学习速度 :return: 更新后的b和w的值组成的数组[b,w] """ # 设置初始变量 b_gradient = 0 w_gradient = 0 M = float(len(points)) # 遍历所有数据 for i in range(0, len(points)): # 计算b的梯度 b_gradient += (2 / M) * ((w_current * x + b_current) - y) # 计算w的梯度 w_gradient += ((2 / M) * x * ((w_current * x + b_current) - y)) # 更新w和b的值,lr为学习率 new_b = b_current - (lr * b_gradient) new_w = w_current - (lr * w_gradient) # 返回新得到的w和b的值 return [new_b, new_w]
循环训练不断更新w和b的值,并计算出误差大小。每50次训练打印出相关数据。
具体代码如下:
# 更新w和b的值 def gradient_descent(points, starting_b, starting_w, lr, num_iterations): """ :param points: [x,y]的数据集 :param starting_b: b的初始值 :param starting_w: w的初始值 :param lr: 学习速度 :param num_iterations: 学习次数 :return: 更新后的[b, w} """ b = starting_b w = starting_w # 循环训练 for step in range(num_iterations): # 调用step_gradient函数更新b,w的值 if step % 50 == 0: print(f"w:{w},b:{b}") b, w = step_gradient(b, w, np.array(points), lr) # 计算误差 loss = mse(b, w, points) # 每50个打印一下loss ,w ,b的值 if step % 50 == 0: print(f"iteration:{step},loss:{loss},w:{w},b:{b}") return [b, w]
代码如下:
# 主函数 def main(): # 设置学习速度 lr = 0.01 # 设置初始b值 initial_b = 0 # 设置初始w值 initial_w = 0 # 设置训练次数 num_iterations = 1000 # 得到最优的b和w的值 b, w = gradient_descent(data, initial_b, initial_w, lr, num_iterations) # 计算当最优值解w和b时的误差 loss = mse(b, w, data) # 打印误差值和b以及w的值 print(f"Final loss:{loss},w:{w},b:{b}") main()
结果如下:
w:0,b:0 iteration:0,loss:50.97753728816465,w:2.773969394653172,b:0.2871579814227153 w:1.4670253907341861,b:0.1518647071993988 iteration:50,loss:0.003996092455715741,w:1.4736812030648103,b:0.15255370890117476 w:1.4705453451013133,b:0.1522290886495735 iteration:100,loss:0.004626595698334646,w:1.4705613149378474,b:0.15223074182787877 w:1.4705537908165853,b:0.1522299629398788 iteration:150,loss:0.00462881626037251,w:1.4705538291343245,b:0.15222996690648516 w:1.4705538110810834,b:0.15222996503763542 iteration:200,loss:0.004628821592423818,w:1.4705538111730216,b:0.15222996504715275 w:1.4705538111297045,b:0.1522299650426685 iteration:250,loss:0.004628821605217145,w:1.4705538111299266,b:0.15222996504269148 w:1.4705538111298213,b:0.1522299650426807 iteration:300,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:350,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:400,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:450,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:500,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:550,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:600,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:650,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:700,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:750,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:800,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:850,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:900,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 w:1.4705538111298213,b:0.1522299650426807 iteration:950,loss:0.004628821605247868,w:1.470553811129823,b:0.15222996504268085 Final loss:0.004628821605248407,w:1.4705538111298213,b:0.1522299650426807
可以看出在第50次训练左右,w和b的值就已经离给定值相差不远
下面给出全部代码:
import numpy as np # 采集数据 data = [] # 循环采样100个点 for i in range(100): x = np.random.uniform(-10, 10) # uniform:随机生成一个实数 eps = np.random.normal(0., 0.01) # normal:正态分布 y = 1.477 * x + 0.089 + eps data.append([x, y]) data = np.array(data) # 计算误差 def mse(b, w, points): """ :param b: b的值 :param w: w的值 :param points: [x,y]的数据集 :return: 误差值 """ # 设置初始误差为0 totalError = 0 # 循环遍历所有数据 for i in range(0, len(points)): # 获取第i个位置的x的值 x = points[i, 0] # 获取第i个位置的y的值 y = points[i, 1] # 计算总误差 totalError += (y - (w * x + b)) ** 2 # 获得平均方差(误差) return totalError / float(len(points)) # 计算梯度 def step_gradient(b_current, w_current, points, lr): """ :param b_current: b的值 :param w_current: w的值 :param points: [x,y]的数据集 :param lr: 学习速度 :return: 更新后的b和w的值组成的数组[b,w] """ # 设置初始变量 b_gradient = 0 w_gradient = 0 M = float(len(points)) # 遍历所有数据 for i in range(0, len(points)): # 计算b的梯度 b_gradient += (2 / M) * ((w_current * x + b_current) - y) # 计算w的梯度 w_gradient += ((2 / M) * x * ((w_current * x + b_current) - y)) # 更新w和b的值,lr为学习率 new_b = b_current - (lr * b_gradient) new_w = w_current - (lr * w_gradient) # 返回新得到的w和b的值 return [new_b, new_w] # 更新w和b的值 def gradient_descent(points, starting_b, starting_w, lr, num_iterations): """ :param points: [x,y]的数据集 :param starting_b: b的初始值 :param starting_w: w的初始值 :param lr: 学习速度 :param num_iterations: 学习次数 :return: 更新后的[b, w} """ b = starting_b w = starting_w # 循环训练 for step in range(num_iterations): # 调用step_gradient函数更新b,w的值 if step % 50 == 0: print(f"w:{w},b:{b}") b, w = step_gradient(b, w, np.array(points), lr) # 计算误差 loss = mse(b, w, points) # 每50个打印一下loss ,w ,b的值 if step % 50 == 0: print(f"iteration:{step},loss:{loss},w:{w},b:{b}") return [b, w] # 主函数 def main(): # 设置学习速度 lr = 0.01 # 设置初始b值 initial_b = 0 # 设置初始w值 initial_w = 0 # 设置训练次数 num_iterations = 1000 # 得到最优的b和w的值 b, w = gradient_descent(data, initial_b, initial_w, lr, num_iterations) # 计算当最优值解w和b时的误差 loss = mse(b, w, data) # 打印误差值和b以及w的值 print(f"Final loss:{loss},w:{w},b:{b}") main()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。