github博客传送门
csdn博客传送门
本章所需知识:
- numpy
- matplotlib
资料下载链接:
- 深度学习基础网络模型(mnist手写体识别数据集)
梯度下降 BP 算法手动实现
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1, 100, 100) # 造出一些100个伪数据 范围在 1,100之间
y = 2 * x + np.random.randn(*x.shape) * 10 # 将x数据乘以2 再加上一些噪点
step = 0.00001 # 学习率 步长
diff = [0, 0] # 梯度
cnt = 0 # 计数
b = 0 # b值初始化
w = 0 # w值初始化
error0 = 0 # 第一次误差
error1 = 0 # 下一次误差
epsilon = 0.000001 # 两次误差差值
def h(ax):
return w * ax + b # 定义一个主函数
while True:
# cnt = cnt+1 # 计数 查看训练了多少次
diff = [0, 0]
for i in range(len(x)): # 遍历ax数据个数这么多次
diff[0] += h(x[i]) - y[i] # 预测的y值 减去 原本的y的值 求和
diff[1] += (h(x[i]) - y[i]) * x[i] # 预测的y值 减去 原本的y值 乘以x的值 求和
b = b - step / len(x) * diff[0] # 更新b值 现在的 b 值 减去 学习率/x的个数*diff[0]的梯度
w = w - step / len(x) * diff[1] # 更新w值 现在的 w 值 减去 学习率/x的个数*diff[1]的梯度
error1 = 0 # 重置本次拟合误差为 0
for i in range(len(x)): # 计算本次 拟合误差
error1 += (y[i] - (b + w * x[i])) ** 2 / 2 # 均方差
if abs(error1 - error0) < epsilon: # 如果 本次拟合误差 与 上次拟合误差 小于设置阈值 则可跳出拟合循环
break # 跳出整个 拟合循环网络
else:
error0 = error1 # 否则将 本次误差赋给 error0 以便下次循环拟合误差相比较
plt.ion() # 开启动态画图
plt.clf() # 清除画板上的图
plt.plot(x, [h(x) for x in x]) # 画出原本的x值 和 预测的y值 预测线
plt.plot(x, y, 'bo') # 再画出 原本的x, y对应的点(样本)
print(w, b) # 打印出当前训练好的 w, b 的值
plt.pause(0.1) # 暂停 0.1 秒
plt.ioff() # 关闭所有画板
最后附上截图训练截图: