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. js 数组的forEach 函数

    var numbers = [4, 9, 16, 25]; function myFunction(item, index) { console.log("item:" + ite ...

  2. CentOS 7 各个版本的区别

    CentOS 7 各个版本的区别 2017年07月04日 10:44:37 程诺 阅读数 52029    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.n ...

  3. Confluence 6 预览一个文件

    当你浏览一个页面的时候,单击一个图片,文件缩略图或者链接将会运行预览. 预览视图包括了从远程 Web 页面导入的图片文件和已经附加到页面中的文件(尽管有可能这些文件没有在页面中显示). 在预览中你可以 ...

  4. sh_08_格式化字符串

    sh_08_格式化字符串 info_tuple = ("小明", 21, 1.85) # 格式化字符串后面的 `()` 本质上就是元组 print("%s 年龄是 %d ...

  5. malloc,calloc,realloc

    与堆操作相关的两个函数 malloc #include<stdio.h> #include<stdlib.h> #include<string.h> int mai ...

  6. 学习sklearn聚类使用

    学习利用sklearn的几个聚类方法: 一.几种聚类方法 1.高斯混合聚类(mixture of gaussians) 2.k均值聚类(kmeans) 3.密度聚类,均值漂移(mean shift) ...

  7. POJ3233 [C - Matrix Power Series] 矩阵乘法

    解题思路 题目里要求\(\sum_{i=1}^kA^i\),我们不妨再加上一个单位矩阵,求\(\sum_{i=0}^kA^i\).然后我们发现这个式子可以写成这样的形式:\(A(A(A...)+E)+ ...

  8. 原生Js_制作简易日历

    javascript制作简易日历,月份信息已经放在一个数组中,在<script>...</script>中编写代码实现其功能 实现步骤 a) 获取需要操作的dom对象 b) 在 ...

  9. HTML jQuery 文档操作 - html() 方法

    jQuery 文档操作 - html() 方法 jQuery 文档操作参考手册 实例 设置所有 p 元素的内容: $(".btn1").click(function(){ $(&q ...

  10. 第八周学习总结&实验报告(6)

    实验六 异常 一.实验目的: (1)理解异常的基本概念: (2)掌握异常处理方法及熟悉常见异常的捕获方法. 二.实验要求: (1)练习捕获异常.声明异常.抛出异常的方法.熟悉try和catch子句的使 ...