BP算法为深度学习中参数更新的重要角色,一般基于loss对参数的偏导进行更新。

一些根据均方误差,每层默认激活函数sigmoid(不同激活函数,则更新公式不一样)

假设网络如图所示:

则更新公式为:

以上列举了最后2层的参数更新方式,第一层的更新公式类似,即上一层的误差来自于下一层所有的神经元,e的更新就是不断建立在旧的e上(这里g可以当做初始的e)

下面上代码:

1,BP算法

# 手写BP算法
import numpy as np # 先更新参数,再继续传播
# layers:包括从输入层到输出层,每层参数为:连接权重w,阈值b,输出y。类型为np.array
# 对于输入层,w和b随便是啥,反正不用,只需y即原始输入
# 基于激活函数sigmoid
# loss为均方误差
def bp(layers,labels,lr=0.001):
# 翻转layers,反向传播
reversed_layers=layers[::-1]
# 输出层
output_w,output_b,output_y=reversed_layers[0]
g=np.array([output_y[j]*(1-output_y[j])*(labels[j]-output_y[j]) for j in range(len(labels))])
# 最后一层更新较为特殊,先进行更新
delta_w=np.empty(shape=(output_w.shape[0],output_w.shape[1]))
# 上一层输出y
last_y=reversed_layers[1][2]
for h in range(output_w.shape[0]):
for j in range(output_w.shape[1]):
delta_w[h,j]=lr*g[j]*last_y[h]
delta_b=-lr*g
new_w=output_w+delta_w
new_b=output_b+delta_b
reversed_layers[0][0]=new_w
reversed_layers[0][1]=new_b # 从倒数第二层到第二层进行更新,每次取3层进行计算,由公式知,需用到上一层输出即下一层权重
for i in range(1,len(reversed_layers)-1):
# 下一层w
next_w=reversed_layers[i-1][0]
out_w,out_b,out_y=reversed_layers[i]
# 上一层y
last_y=reversed_layers[i+1][2]
# 更新辅助量,意思即上一层每个神经元的误差都由下一层所有神经元的误差反向传播,体现在这里内循环
e=np.empty(shape=(len(out_b),1))
for h in range(len(out_b)):
temp=0
for j in range(next_w.shape[1]):
temp+=next_w[h,j]*g[j]
e[h]=out_y[h]*(1-out_y[h])*temp
delta_w=np.empty(shape=(out_w.shape[0],out_w.shape[1]))
for h in range(out_w.shape[0]):
for j in range(out_w.shape[1]):
delta_w[h,j]=lr*e[j]*last_y[h]
delta_b=-lr*e
out_new_w=out_w+delta_w
out_new_b=out_b+delta_b
reversed_layers[i][0]=out_new_w
reversed_layers[i][1]=out_new_b
g=np.copy(e)
return layers

以上假设每个神经元的输出为一个实数y值

2,构建测试

构建平面上的点(x,y),将y是否大于0作为划分,进行训练。只使用了一层网络,sigmoid激活

X=[]
Y=[]
for i in range(-100,100):
for j in range(-100,100):
X.append([[i],[j]])
if j>=0:
Y.append([1])
else:
Y.append([0])
X=np.array(X)
Y=np.array(Y)

3,划分训练,验证集

indexs=np.random.choice(range(40000),size=30000)

x_train=np.array([X[i] for i in indexs])
y_train=np.array([Y[i] for i in indexs]) x_val=np.array([X[i] for i in np.setdiff1d(range(40000),indexs))
y_val=np.array([Y[i] for i in np.setdiff1d(range(40000),indexs))

4,训练。这里只对所有样本训练了一轮。使用随机初始化的w和b,每个样本都会改变w和b

# 使用sigmoid激活函数
def output(input_x,w,b):
res=0
t=np.matmul(np.transpose(w),input_x)-b
return 1./(1+np.power(np.e,-t)) w1=np.random.normal(size=(2,1))
b1=np.array([[0]])
for i in range(len(x_train)):
y0=x_train[i]
l=y_train[i]
input_layers=[]
w0,b0=(0,0)
input_layers.append([w0,b0,y0])
input_layers.append([w1,b1,output(y0,w1,b1)])
input_layers=bp(input_layers,l)
w1=input_layers[1][0]
b1=input_layers[1][1] # w: [[0.11213777]
# [1.67425498]]
# b: [[0.0001581]]
print('w: ',w1)
print('b: ',b1)

5,验证。从分出的验证集选取部分验证即可

for xx in x_val[:50]:
print(xx.reshape((2,)),output(xx,w1,b1).reshape((1,)))

验证结果如下:

[63 68] [1.]
[-100 -99] [1.39636722e-77]
[-100 -98] [7.44936654e-77]
[63 69] [1.]
[-100 -96] [2.12011171e-75]
[-100 -94] [6.03390049e-74]
[-100 -93] [3.21897678e-73]
[63 74] [1.]
[-100 -91] [9.16130293e-72]
[63 75] [1.]
[63 76] [1.]
[63 77] [1.]
[63 78] [1.]
[-100 -86] [3.95872874e-68]
[-100 -85] [2.11191018e-67]
[63 79] [1.]
[-100 -83] [6.01055872e-66]
[-100 -82] [3.20652436e-65]
[63 82] [1.]
[-100 -80] [9.12586299e-64]
[-100 -79] [4.86848285e-63]
[63 83] [1.]
[-100 -77] [1.38558459e-61]
[-100 -76] [7.39184317e-61]
[63 89] [1.]
[-100 -74] [2.10374039e-59]
[63 91] [1.]
[-100 -72] [5.98730724e-58]
[-100 -71] [3.19412012e-57]
[-100 -70] [1.70400531e-56]
[-100 -69] [9.09056014e-56]
[-100 -68] [4.84964942e-55]
[-100 -67] [2.58720025e-54]
[-100 -66] [1.38022454e-53]
[63 99] [1.]
[-100 -64] [3.92815978e-52]
[-100 -63] [2.09560219e-51]
[ 64 -100] [2.53988133e-70]
[-100 -61] [5.9641457e-50]
[ 64 -97] [3.85631522e-68]
[ 64 -96] [2.05727442e-67]
[-100 -58] [9.05539386e-48]
[ 64 -90] [4.74253371e-63]
[ 64 -89] [2.53005596e-62]
[ 64 -87] [7.20061393e-61]
[-100 -52] [2.08749548e-43]
[ 64 -84] [1.09327301e-58]
[-100 -50] [5.94107377e-42]
[ 95 -13] [1.49260907e-05]
[-100 -45] [2.56722211e-38]

6,总结:可以看出,这50个验证样本上都没问题,虽然想到的测试方案有点low,但一时找不到啥好数据。由此验证BP算法的正确性。如有可疑或不足之处,敬请告知。

手写BP(反向传播)算法的更多相关文章

  1. 机器学习 —— 基础整理(七)前馈神经网络的BP反向传播算法步骤整理

    这里把按 [1] 推导的BP算法(Backpropagation)步骤整理一下.突然想整理这个的原因是知乎上看到了一个帅呆了的求矩阵微分的方法(也就是 [2]),不得不感叹作者的功力.[1] 中直接使 ...

  2. 【深度学习】BP反向传播算法Python简单实现

    转载:火烫火烫的 个人觉得BP反向传播是深度学习的一个基础,所以很有必要把反向传播算法好好学一下 得益于一步一步弄懂反向传播的例子这篇文章,给出一个例子来说明反向传播 不过是英文的,如果你感觉不好阅读 ...

  3. 手推机器学习公式(一) —— BP 反向传播算法

    方便起见,本文仅以三层的神经网络举例. f(⋅):表示激励函数 xi:表示输入层: yj:表示中间的隐层: yj=f(netj) netj=∑i=0nvijxi ok:表示输出层,dk 则表示期望输出 ...

  4. BP反向传播算法的工作原理How the backpropagation algorithm works

    In the last chapter we saw how neural networks can learn their weights and biases using the gradient ...

  5. 神经网络训练中的Tricks之高效BP(反向传播算法)

    神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

  6. 深度神经网络(DNN)反向传播算法(BP)

    在深度神经网络(DNN)模型与前向传播算法中,我们对DNN的模型和前向传播算法做了总结,这里我们更进一步,对DNN的反向传播算法(Back Propagation,BP)做一个总结. 1. DNN反向 ...

  7. 神经网络之反向传播算法(BP)公式推导(超详细)

    反向传播算法详细推导 反向传播(英语:Backpropagation,缩写为BP)是"误差反向传播"的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见 ...

  8. 稀疏自动编码之反向传播算法(BP)

    假设给定m个训练样本的训练集,用梯度下降法训练一个神经网络,对于单个训练样本(x,y),定义该样本的损失函数: 那么整个训练集的损失函数定义如下: 第一项是所有样本的方差的均值.第二项是一个归一化项( ...

  9. 【机器学习】反向传播算法 BP

    知识回顾 1:首先引入一些便于稍后讨论的新标记方法: 假设神经网络的训练样本有m个,每个包含一组输入x和一组输出信号y,L表示神经网络的层数,S表示每层输入的神经元的个数,SL代表最后一层中处理的单元 ...

随机推荐

  1. HDU - 6253 Knightmare (打表+拉格朗日插值)

    题目链接 题意:一个马在无限大的棋盘中跳,问跳n步能跳到多少个不同的格子. 首先写个打表程序打一下n比较小的时候的表: #include<bits/stdc++.h> using name ...

  2. JavaScript基础——JavaScript常量和变量(笔记)

    JavaScript常量和变量(笔记) Javascript代码严格区分大小写. javascript暂不支持constant关键字,不允许用户自定义常量. javascript使用var关键字声明变 ...

  3. Spring boot之全局异常捕捉

    在一个项目中的异常我们我们都会统一进行处理的,那么如何进行统一进行处理呢? 新建一个类GlobalDefaultExceptionHandler, 在class注解上@ControllerAdvice ...

  4. 在SSH项目中Struts2、Spring、Hibernate分别起到什么作用?

    (1)Struts主要起控制作用,Spring主要起解耦作用,Hibernate主要起操作数据作用. (2)Struts2是一个基于MVC设计模式的Web应用框架,在MVC设计模式中Struts2作为 ...

  5. python3笔记十三:python数据类型-Set集合

    一:学习内容 集合概念 集合创建 集合添加 集合插入 集合删除 集合访问 集合操作:并集.交集 二:集合概念 1.set:类似dict,是一组key的集合,不存储value 2.本质:无序和无重复元素 ...

  6. 【Spark机器学习速成宝典】模型篇05决策树【Decision Tree】(Python版)

    目录 决策树原理 决策树代码(Spark Python) 决策树原理 详见博文:http://www.cnblogs.com/itmorn/p/7918797.html 返回目录 决策树代码(Spar ...

  7. shell脚本之for 列表循环

    作用:对列表进行循环处理 语法: for var in list do commands done 案例: 1.读取列表中的值 2.读取列表中的复杂值 异常案例:未显示出“'”单引号,使语句出现异常 ...

  8. mesh之孔洞检测

    mesh之孔洞检测 图1 检测孔洞点 图2 检测孔洞点 图3 检测孔洞点 图4 细节

  9. vue中limitBy,filterBy,orderBy的用法

    1.limitBy的用法 <body> <div id="box"> <ul> <li v-for="val in arr | ...

  10. orcal 根据打分时间计算打分情况

    create or replace function F_GET_TEST(in_ny in date,in_project_id in number ) return number is sRetu ...