话不多说,上代码
import time
import numpy as np
# 保存样本集的列表
data = []
# 循环采样100个点
for i in range(100):
# 随机采样, numpy.uniform表示从一个均匀分布[low,high)中随机采样,定义域是左闭右开,即包含low,不包含high.
# 从-10到10之间采样,数字格式为浮点类型
x = np.random.uniform(-10., 10.)
# 采样高斯噪声 np.random.normal生成高斯分布的概率密度随机数
# 此概率分布的均值(对应着整个分布的中心centre)
# loc:float
# 此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
# scale:float
# 输出的shape,默认为None,只输出一个值
# size:int or tuple of ints
# 输出以0为中心,标准差为0.01的随机数,只输出一个数
eps = np.random.normal(0., 0.01)
# 得到模型的输出
y = 1.477 * x + 0.089 + eps
# 保存样本点
data.append([x, y])
# 转换为二维数组
data = np.array(data)
# 定义均方误差
def mse(b, w, points):
# 根据当前的w, b参数计算均方差损失
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):
# 计算误差函数在所有点上的导数,并更新w,b
b_gradient = 0
w_gradient = 0
# 总样本数
M = float(len(points))
for i in range(0, len(points)):
x = points[i, 0]
y = points[i, 1]
# 误差函数对b的导数:grad_b = 2(wx+b-y)
b_gradient += (2 / M) * ((w_current * x + b_current) - y)
# 误差函数对w的导数:grad_b = 2(wx+b-y)
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)
return [new_b, new_w]
def gradient_descent(points, starting_b, starting_w, lr, num_iterations):
# 循环更新w,b多次
# b的初始值
b = starting_b
# w的初始值
w = starting_w
# 根据梯度下降算法更新多次
# 计算梯度并更新一次
b, w = step_gradient(b, w, np.array(points), lr)
# 计算当前的均方差,用于监控训练进度
for step in range(num_iterations):
loss = mse(b, w, points)
# 打印误差和实时的w,b值
if step % 50 == 0:
print(f"iteration:{step}, loss:{loss}, w:{b}, b:{b}")
# 返回最后一次的w,b
return [b, w]
def main():
# 学习率
lr = 0.01
# 初始化b为0
initial_b = 0
# 初始化w为0
initial_w = 0
num_iterations = 1000
# 训练优化1000次,返回最优w*,b*和训练Loss的下降过程
[b, w] = gradient_descent(data, initial_b, initial_w, lr, num_iterations)
# 计算最优数值解w,b上的均方差
loss = mse(b, w, data)
# python3.6新增f-字符串格式化:在字符串里用花括号表达变量和表达式
print(f'Final loss:{loss}, w:{w}, b:{b}')
if __name__ == "__main__":
start = time.process_time()
main()
end = time.process_time()
print(f'一共用时:' + str(end - start))
希望对小伙伴们有帮助,爱你哟