BP 算法手动实现

github博客传送门
csdn博客传送门

本章所需知识:

  1. numpy
  2. matplotlib

资料下载链接:

  1. 深度学习基础网络模型(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()  # 关闭所有画板

最后附上截图训练截图:

BP

posted @ 2018-11-02 22:29  账号  阅读(400)  评论(0编辑  收藏  举报